]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix race in getaddrinfo() in libirs, which caused assertion failure in delv (#39873)
authorMukund Sivaraman <muks@isc.org>
Mon, 29 Jun 2015 14:14:42 +0000 (19:44 +0530)
committerMukund Sivaraman <muks@isc.org>
Mon, 29 Jun 2015 14:14:42 +0000 (19:44 +0530)
CHANGES
lib/irs/getaddrinfo.c

diff --git a/CHANGES b/CHANGES
index 0ab5a34137d80e1fb40492dac17dff3da8e7dbf9..d94615460ec7809f6fdf66995b2c6d90c2ae64b4 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,9 @@
+4149.  [bug]           Fixed a race condition in the getaddrinfo()
+                       implementation in libirs, which caused the delv
+                       utility to crash with an assertion failure when using
+                       the '@server' syntax with a hostname argument.
+                       [RT #39899]
+
 4148.  [bug]           Fix a bug when printing zone names with '/' character
                        in XML and JSON statistics output. [RT #39873]
 
index cda7b18bff48bd272fb22ebd62e64abfa5f1ad6c..093af0739b9f04472508b9582169062641546027 100644 (file)
 #include <isc/sockaddr.h>
 #include <isc/string.h>
 #include <isc/util.h>
+#include <isc/mutex.h>
 
 #include <dns/client.h>
 #include <dns/fixedname.h>
@@ -531,6 +532,7 @@ typedef struct gai_statehead {
        int                             ai_port;
        isc_appctx_t                    *actx;
        dns_client_t                    *dnsclient;
+       isc_mutex_t                     list_lock;
        ISC_LIST(struct gai_resstate)   resstates;
        unsigned int                    activestates;
 } gai_statehead_t;
@@ -858,6 +860,7 @@ process_answer(isc_task_t *task, isc_event_t *event) {
                 * and have any answer, we can stop now by canceling the
                 * others.
                 */
+               LOCK(&resstate->head->list_lock);
                if (resstate == ISC_LIST_HEAD(resstate->head->resstates)) {
                        if ((resstate->trans4 != NULL &&
                             resstate->trans4->ai_sentinel.ai_next != NULL) ||
@@ -889,6 +892,7 @@ process_answer(isc_task_t *task, isc_event_t *event) {
                                                resstate, link);
                        }
                }
+               UNLOCK(&resstate->head->list_lock);
        }
 }
 
@@ -929,11 +933,19 @@ resolve_name(int family, const char *hostname, int flags,
        head.ai_port = port;
        head.actx = actx;
        head.dnsclient = client;
+       result = isc_mutex_init(&head.list_lock);
+       if (result != ISC_R_SUCCESS) {
+               return (EAI_FAIL);
+       }
+
        ISC_LIST_INIT(head.resstates);
        result = make_resstates(mctx, hostname, &head, conf);
-       if (result != ISC_R_SUCCESS)
+       if (result != ISC_R_SUCCESS) {
+               DESTROYLOCK(&head.list_lock);
                return (EAI_FAIL);
+       }
 
+       LOCK(&head.list_lock);
        for (resstate = ISC_LIST_HEAD(head.resstates);
             resstate != NULL; resstate = ISC_LIST_NEXT(resstate, link)) {
                if (resstate->trans4 != NULL) {
@@ -967,6 +979,8 @@ resolve_name(int family, const char *hostname, int flags,
                                resstate->trans6->is_inprogress= ISC_FALSE;
                }
        }
+       UNLOCK(&head.list_lock);
+
        if (!all_fail) {
                /* Start all the events */
                isc_app_ctxrun(actx);
@@ -1038,6 +1052,7 @@ resolve_name(int family, const char *hostname, int flags,
        irs_context_destroy(&irsctx);
 #endif
 
+       DESTROYLOCK(&head.list_lock);
        return (error);
 }