summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Fergeau <cfergeau@redhat.com>2014-09-21 18:46:04 +0200
committerStef Walter <stefw@gnome.org>2014-11-13 21:44:24 +0100
commitb087539a6cdd624fc4e0d6ae7de2811ab96864e6 (patch)
tree6d22cd38ee9a4b0efbeecfd5f28ff4f6d248fb45
parentdc5a7dc4e5690e258a90d8ddfc39e17c1f8d4938 (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.c10
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 */