[gnome-keyring] GkmMock: Fix handling of CKA_G_CREDENTIAL_TEMPLATE attributes



commit ddcdccbf98ba71547c6494db07b3ece505ec769b
Author: Christophe Fergeau <cfergeau redhat com>
Date:   Mon Oct 13 17:06:09 2014 +0200

    GkmMock: Fix handling of CKA_G_CREDENTIAL_TEMPLATE attributes
    
    These are special as their value is an array of CK_ATTRIBUTE pointing to
    allocated memory. Moreover, when gkm_mock_C_SetAttributeValue() is
    called, this memory is owned by the caller, so it needs to be duplicated
    as the caller may free it before GkmMock no longer needs it.
    
    We also need to make sure this memory we just duplicated is correctly
    freed when no longer needed.
    
    This is achieved by introducing an additional global variable,
    the_credential_template. This is similar to how this type of attributes
    is handled in GkmSecretCollection.
    
    Without this, running test-login-auto in valgrind causes invalid reads:
    
    ==5954== Invalid read of size 1
    ==5954==    at 0x4123D4: gkm_attributes_find_boolean (gkm-attributes.c:503)
    ==5954==    by 0x408C00: set_unlock_options_on_prompt (gkm-wrap-prompt.c:520)
    ==5954==    by 0x40A3E8: gkm_wrap_prompt_do_credential (gkm-wrap-prompt.c:1055)
    ==5954==    by 0x40641C: auth_C_CreateObject (gkm-wrap-layer.c:764)
    ==5954==    by 0x404D7B: test_unlock_keyring (test-login-auto.c:243)
    ==5954==    by 0x5E04A8B: test_case_run (gtestutils.c:2059)
    ==5954==    by 0x5E04E2D: g_test_run_suite_internal (gtestutils.c:2120)
    ==5954==    by 0x5E04EEF: g_test_run_suite_internal (gtestutils.c:2131)
    ==5954==    by 0x5E04EEF: g_test_run_suite_internal (gtestutils.c:2131)
    ==5954==    by 0x5E0506F: g_test_run_suite (gtestutils.c:2184)
    ==5954==    by 0x5E03D5C: g_test_run (gtestutils.c:1488)
    ==5954==    by 0x410725: testing_thread (egg-testing.c:142)
    ==5954==    by 0x5E07B29: g_thread_proxy (gthread.c:764)
    ==5954==    by 0x3899207529: start_thread (pthread_create.c:310)
    ==5954==    by 0x3898F0077C: clone (clone.S:109)
    ==5954==  Address 0x85bad90 is 0 bytes inside a block of size 1 free'd
    ==5954==    at 0x4A07CE9: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==5954==    by 0x5DE1A0D: g_free (gmem.c:190)
    ==5954==    by 0x409E54: gkm_wrap_prompt_finalize (gkm-wrap-prompt.c:933)
    ==5954==    by 0x590293A: g_object_unref (gobject.c:3170)
    ==5954==    by 0x40644A: auth_C_CreateObject (gkm-wrap-layer.c:771)
    ==5954==    by 0x404CD5: test_unlock_keyring (test-login-auto.c:234)
    ==5954==    by 0x5E04A8B: test_case_run (gtestutils.c:2059)
    ==5954==    by 0x5E04E2D: g_test_run_suite_internal (gtestutils.c:2120)
    ==5954==    by 0x5E04EEF: g_test_run_suite_internal (gtestutils.c:2131)
    ==5954==    by 0x5E04EEF: g_test_run_suite_internal (gtestutils.c:2131)
    ==5954==    by 0x5E0506F: g_test_run_suite (gtestutils.c:2184)
    ==5954==    by 0x5E03D5C: g_test_run (gtestutils.c:1488)
    ==5954==    by 0x410725: testing_thread (egg-testing.c:142)
    ==5954==    by 0x5E07B29: g_thread_proxy (gthread.c:764)
    ==5954==    by 0x3899207529: start_thread (pthread_create.c:310)
    ==5954==    by 0x3898F0077C: clone (clone.S:109)
    
    https://bugzilla.gnome.org/show_bug.cgi?id=738508

 pkcs11/gkm/gkm-mock.c |   27 +++++++++++++++++++++++++--
 1 files changed, 25 insertions(+), 2 deletions(-)
---
diff --git a/pkcs11/gkm/gkm-mock.c b/pkcs11/gkm/gkm-mock.c
index 6aaaff9..7f4ba06 100644
--- a/pkcs11/gkm/gkm-mock.c
+++ b/pkcs11/gkm/gkm-mock.c
@@ -72,6 +72,7 @@ typedef struct _Session {
 static guint unique_identifier = 100;
 static GHashTable *the_sessions = NULL;
 static GHashTable *the_objects = NULL;
+static GArray *the_credential_template = NULL;
 
 enum {
        PRIVATE_KEY_CAPITALIZE = 3,
@@ -260,6 +261,7 @@ gkm_mock_C_Initialize (CK_VOID_PTR pInitArgs)
        n_the_pin = strlen (the_pin);
        the_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_session);
        the_objects = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, 
(GDestroyNotify)gkm_template_free);
+       the_credential_template = gkm_template_new (NULL, 0);
 
        /* Our token object */
        attrs = gkm_template_new (NULL, 0);
@@ -337,6 +339,9 @@ gkm_mock_C_Finalize (CK_VOID_PTR pReserved)
        g_hash_table_destroy (the_sessions);
        the_sessions = NULL;
 
+       gkm_template_free (the_credential_template);
+       the_credential_template = NULL;
+
        g_free (the_pin);
        return CKR_OK;
 }
@@ -867,6 +872,10 @@ gkm_mock_C_GetAttributeValue (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObje
 
        for (i = 0; i < ulCount; ++i) {
                result = pTemplate + i;
+               if (result->type == CKA_G_CREDENTIAL_TEMPLATE) {
+                       gkm_attribute_set_template (result, the_credential_template);
+                       continue;
+               }
                attr = gkm_template_find (attrs, result->type);
                if (!attr) {
                        result->ulValueLen = (CK_ULONG)-1;
@@ -910,8 +919,22 @@ gkm_mock_C_SetAttributeValue (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObje
                return CKR_OBJECT_HANDLE_INVALID;
        }
 
-       for (i = 0; i < ulCount; ++i)
-               gkm_template_set (attrs, pTemplate + i);
+       for (i = 0; i < ulCount; ++i) {
+               CK_ATTRIBUTE_PTR attr = pTemplate + i;
+
+               if (attr->type == CKA_G_CREDENTIAL_TEMPLATE) {
+                       CK_RV rv;
+                       GArray *template;
+
+                       rv = gkm_attribute_get_template (attr, &template);
+                       if (rv != CKR_OK)
+                               return CKR_OBJECT_HANDLE_INVALID;
+                       gkm_template_free(the_credential_template);
+                       the_credential_template = template;
+               } else {
+                       gkm_template_set (attrs, attr);
+               }
+       }
 
        return CKR_OK;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]