This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug nss/20874] getaddrinfo_a segfault


https://sourceware.org/bugzilla/show_bug.cgi?id=20874

Phil Blundell <pb at pbcl dot net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |pb at pbcl dot net

--- Comment #7 from Phil Blundell <pb at pbcl dot net> ---
I think the bug is in gai_suspend(), here:

      /* 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)
          {
            struct waitlist **listp = &requestlist[cnt]->waiting;

            /* There is the chance that we cannot find our entry anymore.
               This could happen if the request terminated and restarted
               again.  */
            while (*listp != NULL && *listp != &waitlist[cnt])
              listp = &(*listp)->next;

            if (*listp != NULL)
              *listp = (*listp)->next;
          }

The check for (list[cnt]->__return == EAI_INPROGRESS) here is incorrect because
handle_request() may have assigned a new return value while we were sleeping
(or in fact at any other time, since this particular operation in
handle_request() is not guarded by __gai_requests_mutex).

I think the fix is probably to remove that condition and allow the loop to
search all lists for an entry that we added.

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;

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]