Commit Message
On Mon, 2017-06-19 at 13:18 +0100, Phil Blundell wrote:
> On Mon, 2017-06-19 at 12:04 +0100, Phil Blundell wrote:
> > Under conditions that I don't entirely understand yet, we seem to
> > be somehow returning from gai_suspend while its waitlist[] entry is
> > still linked into requestlist->waiting.
>
> Here's a patch that fixes bug 20874 for me, fwiw. It still passes
> "make subdirs='resolv' xcheck".
>
> OK to commit?
Ping?
2017-06-26 Phil Blundell <pb@pbcl.net>
* resolv/gai_suspend.c (gai_suspend): Ensure we always remove the
entry we added to the waitlist before returning.
From 6e5dbbcfc0594dad90dc6f8b4537dba26bceb428 Mon Sep 17 00:00:00 2001
From: Phil Blundell <pb@pbcl.net>
Date: Mon, 19 Jun 2017 13:11:00 +0100
Subject: [PATCH] gai_suspend: Remove bogus check for EAI_INPROGRESS [BZ
#20874]
If we added an entry to the waitlist for any request, it is important
that we remove it again before returning. Failing to do so will
cause obscure and hard-to-debug crashes because the linked list
will contain a pointer to a struct that was assigned on the stack
and has since been overwritten.
Although we check that the current "return value" of the request
is EAI_INPROGRESS before adding an entry to its waitlist, this
value may change while we sleep so we cannot assume it will still
be EAI_INPROGRESS when we come to remove the entry afterwards.
---
resolv/gai_suspend.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
Comments
On Jun 26 2017, Phil Blundell <pb@pbcl.net> wrote:
> diff --git a/resolv/gai_suspend.c b/resolv/gai_suspend.c
> index a86bd4360d..139d636c78 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;
Is the comment still accurate?
Andreas.
@@ -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;