From 5209d41e4aff1c786da284a609a9a817aa816b9d Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Fri, 9 Jan 2009 20:35:43 -0500 Subject: [PATCH] Fixed a pinentry segfault (hopefully) during cleanup of the pinentry thread. --- src/pinentry.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/pinentry.c b/src/pinentry.c index d28ac4f7..891df5c6 100644 --- a/src/pinentry.c +++ b/src/pinentry.c @@ -403,13 +403,21 @@ static void reset(struct pinentry_s *pin) { int status; - pth_waitpid(pin->pid, &status, 0); - close(pin->fd); + if (pin->pid) + pth_waitpid(pin->pid, &status, 0); + + if (pin->fd != -1) + close(pin->fd); + pin->fd = -1; pin->pid = pin->pin_pid = 0; - pin->tid = 0; - pth_event_isolate(pin->ev); - pth_event_free(pin->ev, PTH_FREE_THIS); + pin->tid = NULL; + + if (pin->ev) { + pth_event_isolate(pin->ev); + pth_event_free(pin->ev, PTH_FREE_THIS); + } + pin->ev = NULL; pin->status = PINENTRY_NONE; } @@ -426,8 +434,8 @@ static void *timeout_thread(void *arg) /* pth_cancel() was called from pinentry_iterate() (we have a key). * pth_wait() was the cancelation point. */ if (pin->status == PINENTRY_NONE) { - reset(pin); pth_mutex_release(&pin->status_mutex); + pth_exit(PTH_CANCELED); return NULL; } @@ -436,7 +444,6 @@ static void *timeout_thread(void *arg) if (kill(pin->pin_pid, 0) == 0) kill(pin->pin_pid, SIGKILL); - reset(pin); pin->status = PINENTRY_TIMEOUT; pth_mutex_release(&pin->status_mutex); pth_exit(PTH_CANCELED); @@ -628,7 +635,6 @@ pth_event_t pinentry_iterate(struct client_s *cl, pth_event_t ev) * now that we know the pid of it. */ pth_attr_t attr = pth_attr_new(); - pth_attr_init(attr); pth_attr_set(attr, PTH_ATTR_JOINABLE, 0); pth_attr_set(attr, PTH_ATTR_CANCEL_STATE, @@ -675,19 +681,16 @@ pth_event_t pinentry_iterate(struct client_s *cl, pth_event_t ev) if (pk.error) { if (cl->pinentry->tid) { - pth_cancel(cl->pinentry->tid); cl->pinentry->status = PINENTRY_NONE; + pth_cancel(cl->pinentry->tid); } - else - reset(cl->pinentry); if (cl->pinentry->which == PINENTRY_OPEN) cleanup_client(cl); } - else if (pk.status == PINENTRY_RUNNING) - reset(cl->pinentry); if (pk.error || pk.status == PINENTRY_RUNNING) { + reset(cl->pinentry); unlock_file_mutex(cl); unlock_pin_mutex(cl->pinentry); } -- 2.11.4.GIT