From 31ce25291fcb35f954375672a1cbcf6cb5b50091 Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Wed, 22 Apr 2009 22:15:38 -0400 Subject: [PATCH] Call a child prepare function during the pinentry fork() to release all inherited mutexes. Fixes a segfault in libpth at pth_ring_append(). --- src/pinentry.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/pinentry.c b/src/pinentry.c index 14b4c649..4f882e10 100644 --- a/src/pinentry.c +++ b/src/pinentry.c @@ -481,11 +481,30 @@ static void *timeout_thread(void *arg) return NULL; } +static void child_prepare(void *arg) +{ + gint i; + gint n = g_slist_length(cn_thread_list); + struct pinentry_s *pin = arg; + + for (i = 0; i < n; i++) { + struct client_thread_s *cn = g_slist_nth_data(cn_thread_list, i); + pth_mutex_t *m; + + cache_get_mutex(cn->cl->md5file, &m); + pth_mutex_release(m); + } + + pth_mutex_release(&pin->status_mutex); + pth_mutex_release(&pin->cond_mutex); + free_client_list(); +} + gpg_error_t pinentry_fork(assuan_context_t ctx) { struct client_s *client = assuan_get_pointer(ctx); struct pinentry_s *pin = client->pinentry; - gpg_error_t rc; + gpg_error_t rc = 0; gint p[2]; pid_t pid; pinentry_key_s pk; @@ -494,6 +513,7 @@ gpg_error_t pinentry_fork(assuan_context_t ctx) if (pipe(p) == -1) return gpg_error_from_syserror(); + pth_atfork_push(NULL, NULL, child_prepare, pin); pid = pth_fork(); switch (pid) { @@ -501,12 +521,9 @@ gpg_error_t pinentry_fork(assuan_context_t ctx) rc = gpg_error_from_syserror(); close(p[0]); close(p[1]); - return rc; + break; case 0: close(p[0]); - /* FIXME segfaults in libpth at pth_ring_append() (xmalloc). - this is probably only a symptom of another problem. */ - //free_client_list(); if (pin->timeout > 0 && pin->which == PINENTRY_OPEN) { /* @@ -540,7 +557,8 @@ gpg_error_t pinentry_fork(assuan_context_t ctx) * the callback function which is called after the key has been read() * in pinentry_iterate(). */ - return 0; + pth_atfork_pop(); + return rc; } gpg_error_t lock_pin_mutex(struct client_s *client) -- 2.11.4.GIT