diff options
author | Christophe Fergeau <cfergeau@redhat.com> | 2014-10-13 17:06:09 +0200 |
---|---|---|
committer | Christophe Fergeau <cfergeau@redhat.com> | 2014-10-14 10:28:07 +0200 |
commit | a734dbcfd38f7079a1b747742e9c4d75b3b79af7 (patch) | |
tree | fa3adc4a67385c0e6019c248fb9bcbd9d6b29de3 | |
parent | 13b69c55c2a7c020012cca4d6575da33d994c8bc (diff) |
GkmMock: Fix handling of CKA_G_CREDENTIAL_TEMPLATE attributesleaks
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
-rw-r--r-- | 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 6aaaff9e..7f4ba06a 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; } |