From 10c12ee139cee70c3b0592fd5f0217ce292a3438 Mon Sep 17 00:00:00 2001 From: Rainhard Driessler Date: Mon, 21 Jun 2021 13:29:41 +0200 Subject: [PATCH] resolv: remove dangling pointers from gai request waitlist * resolv/gai_suspend.c: Remove waitlist entries added during suspend regardless of their __return value as to not leave invalid pointers to the stack in requests' waitlists upon exiting gai_suspend. * resolv/gai_notify.c: Remove waitlist pointer added in getaddrinfo_a for asynchronous operation upon freeing the async_waitlist in __gai_notify. --- resolv/gai_notify.c | 13 +++++++++++++ resolv/gai_suspend.c | 3 +-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/resolv/gai_notify.c b/resolv/gai_notify.c index 2056aee..fcf0a79 100644 --- a/resolv/gai_notify.c +++ b/resolv/gai_notify.c @@ -98,12 +98,15 @@ internal_function __gai_notify (struct requestlist *req) { struct waitlist *waitlist; + struct waitlist *lastp; /* Now also notify possibly waiting threads. */ + lastp = NULL; waitlist = req->waiting; while (waitlist != NULL) { struct waitlist *next = waitlist->next; + int removed = 0; if (waitlist->sigevp == NULL) { @@ -122,11 +125,21 @@ __gai_notify (struct requestlist *req) if (--*waitlist->counterp == 0) { __gai_notify_only (waitlist->sigevp, waitlist->caller_pid); + + /* Remove from the request's waitlist */ + if (lastp != NULL) + lastp->next = next; + else + req->waiting = next; + removed = 1; + /* This is tricky. See getaddrinfo_a.c for the reason why this works. */ free ((void *) waitlist->counterp); } + if (!removed) + lastp = waitlist; waitlist = next; } } diff --git a/resolv/gai_suspend.c b/resolv/gai_suspend.c index a86bd43..139d636 100644 --- a/resolv/gai_suspend.c +++ b/resolv/gai_suspend.c @@ -111,8 +111,7 @@ gai_suspend (const struct gaicb *const list[], int ent, /* Now remove the entry in the waiting list for all requests which didn't terminate. */ for (cnt = 0; cnt < ent; ++cnt) - if (list[cnt] != NULL && list[cnt]->__return == EAI_INPROGRESS - && requestlist[cnt] != NULL) + if (list[cnt] != NULL && requestlist[cnt] != NULL) { struct waitlist **listp = &requestlist[cnt]->waiting; -- 2.7.4