diff options
author | Christophe Fergeau <cfergeau@redhat.com> | 2014-09-21 18:46:04 +0200 |
---|---|---|
committer | Stef Walter <stefw@gnome.org> | 2014-11-13 21:44:24 +0100 |
commit | b087539a6cdd624fc4e0d6ae7de2811ab96864e6 (patch) | |
tree | 6d22cd38ee9a4b0efbeecfd5f28ff4f6d248fb45 | |
parent | dc5a7dc4e5690e258a90d8ddfc39e17c1f8d4938 (diff) |
Don't leak password data in gkm_wrap_prompt_do_credential
Memory returned by auto_unlock_lookup_object() must be freed
while memory returned by gkm_wrap_prompt_request_password() must
not be freed. Depending on the situation, CredentialPrompt::password
will contain one or the other, and currently this field is never
freed, causing leaks when the password comes from
auto_unlock_lookup_object().
This commit will always free CredentialPrompt::password when it's
no longer needed, and will create a copy of the returned string
when gkm_wrap_prompt_request_password() is called.
This fixes (line numbers from 3.13.91-2-g45bb5be):
==2190== 8 bytes in 1 blocks are definitely lost in loss record 58 of 1,294
==2190== at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==2190== by 0x5DE6DE6: g_malloc (gmem.c:97)
==2190== by 0x5E024B5: g_memdup (gstrfuncs.c:384)
==2190== by 0x41296C: gkm_template_set (gkm-attributes.c:600)
==2190== by 0x4129F0: gkm_template_set_value (gkm-attributes.c:614)
==2190== by 0x419BCD: mock_secret_C_CreateObject (mock-secret-store.c:174)
==2190== by 0x40646E: wrap_C_CreateObject (gkm-wrap-layer.c:741)
==2190== by 0x418985: find_login_keyring_item (gkm-wrap-login.c:254)
==2190== by 0x4190AF: gkm_wrap_login_lookup_secret (gkm-wrap-login.c:396)
==2190== by 0x407E8D: auto_unlock_lookup_object (gkm-wrap-prompt.c:198)
==2190== by 0x40B9B0: login_prompt_do_specific (gkm-wrap-prompt.c:1453)
==2190== by 0x40C13A: gkm_wrap_prompt_do_login (gkm-wrap-prompt.c:1591)
==2190== by 0x406384: auth_C_Login (gkm-wrap-layer.c:706)
==2190== by 0x40472A: test_specific (test-login-auto.c:156)
==2190== by 0x5E0A27A: test_case_run (gtestutils.c:2059)
==2190== by 0x5E0A602: g_test_run_suite_internal (gtestutils.c:2120)
==2190== by 0x5E0A6C4: g_test_run_suite_internal (gtestutils.c:2131)
==2190== by 0x5E0A6C4: g_test_run_suite_internal (gtestutils.c:2131)
==2190== by 0x5E0A847: g_test_run_suite (gtestutils.c:2184)
==2190== by 0x5E09551: g_test_run (gtestutils.c:1488)
==2190== by 0x410851: testing_thread (egg-testing.c:142)
==2190== by 0x5E0D2F4: g_thread_proxy (gthread.c:764)
==2190== by 0x3B7AE07F34: start_thread (pthread_create.c:309)
==2190== by 0x3B7AAF4C3C: clone (clone.S:111)
https://bugzilla.gnome.org/show_bug.cgi?id=738508
-rw-r--r-- | pkcs11/wrap-layer/gkm-wrap-prompt.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/pkcs11/wrap-layer/gkm-wrap-prompt.c b/pkcs11/wrap-layer/gkm-wrap-prompt.c index 5b86d1d7..3d3d4f57 100644 --- a/pkcs11/wrap-layer/gkm-wrap-prompt.c +++ b/pkcs11/wrap-layer/gkm-wrap-prompt.c @@ -950,7 +950,7 @@ gkm_wrap_prompt_class_init (GkmWrapPromptClass *klass) typedef struct _CredentialPrompt { GArray *template; CK_ULONG n_template; - const gchar *password; + gchar *password; } CredentialPrompt; static void @@ -958,6 +958,7 @@ credential_prompt_free (gpointer user_data) { CredentialPrompt *data = user_data; g_array_free (data->template, TRUE); + egg_secure_strfree (data->password); g_slice_free (CredentialPrompt, data); } @@ -1033,6 +1034,7 @@ gkm_wrap_prompt_do_credential (GkmWrapPrompt *self, CK_ATTRIBUTE_PTR *template, attrs = get_attributes_from_object (self, &n_attrs); g_return_val_if_fail (attrs, FALSE); + egg_secure_strfree (data->password); data->password = NULL; if (self->iteration == 0) { @@ -1044,6 +1046,7 @@ gkm_wrap_prompt_do_credential (GkmWrapPrompt *self, CK_ATTRIBUTE_PTR *template, } if (!data->password) { + const char *password; setup_unlock_prompt (self, attrs, n_attrs, self->iteration == 1); /* Now load up the unlock options into the prompt*/ @@ -1055,14 +1058,15 @@ gkm_wrap_prompt_do_credential (GkmWrapPrompt *self, CK_ATTRIBUTE_PTR *template, ++(self->iteration); - data->password = gkm_wrap_prompt_request_password (self); - if (data->password == NULL) { + password = gkm_wrap_prompt_request_password (self); + if (password == NULL) { if (error != NULL) { g_warning ("couldn't prompt for password: %s", egg_error_message (error)); g_error_free (error); } return FALSE; } + data->password = egg_secure_strdup (password); } /* Truncate any extra options off the end of template */ |