]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] dispatch.c race
authorEvan Hunt <each@isc.org>
Mon, 23 Dec 2013 17:50:18 +0000 (09:50 -0800)
committerEvan Hunt <each@isc.org>
Mon, 23 Dec 2013 17:50:18 +0000 (09:50 -0800)
3695. [bug] Address a possible race in dispatch.c. [RT #35107]

CHANGES
lib/dns/dispatch.c

diff --git a/CHANGES b/CHANGES
index 8a6dd914a929f6891087666a1b315591fe450e5b..29cceb65bc74246898560e1db1562bab9ded1b79 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,5 @@
+3695.  [bug]           Address a possible race in dispatch.c. [RT #35107]
+
 3694.  [bug]           Warn when a key-directory is configured for a zone,
                        but does not exist or is not a directory. [RT #35108]
 
index c2e04ef42de40f49e69e58fee54729475b79753b..bac8b850dc3490d214e413255e78e9154c64b8d5 100644 (file)
@@ -683,8 +683,8 @@ destroy_disp_ok(dns_dispatch_t *disp)
 /*
  * Called when refcount reaches 0 (and safe to destroy).
  *
- * The dispatcher must not be locked.
- * The manager must be locked.
+ * The dispatcher must be locked.
+ * The manager must not be locked.
  */
 static void
 destroy_disp(isc_task_t *task, isc_event_t *event) {
@@ -809,6 +809,7 @@ socket_search(dns_qid_t *qid, isc_sockaddr_t *dest, in_port_t port,
 {
        dispsocket_t *dispsock;
 
+       REQUIRE(VALID_QID(qid));
        REQUIRE(bucket < qid->qid_nbuckets);
 
        dispsock = ISC_LIST_HEAD(qid->sock_table[bucket]);
@@ -1045,6 +1046,7 @@ entry_search(dns_qid_t *qid, isc_sockaddr_t *dest, dns_messageid_t id,
 {
        dns_dispentry_t *res;
 
+       REQUIRE(VALID_QID(qid));
        REQUIRE(bucket < qid->qid_nbuckets);
 
        res = ISC_LIST_HEAD(qid->qid_table[bucket]);
@@ -2607,8 +2609,7 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests,
  * MUST be unlocked, and not used by anything.
  */
 static void
-dispatch_free(dns_dispatch_t **dispp)
-{
+dispatch_free(dns_dispatch_t **dispp) {
        dns_dispatch_t *disp;
        dns_dispatchmgr_t *mgr;
        int i;
@@ -3271,16 +3272,15 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
         */
        LOCK(&qid->lock);
        id = (dns_messageid_t)dispatch_random(DISP_ARC4CTX(disp));
-       bucket = dns_hash(qid, dest, id, localport);
        ok = ISC_FALSE;
        for (i = 0; i < 64; i++) {
+               bucket = dns_hash(qid, dest, id, localport);
                if (entry_search(qid, dest, id, localport, bucket) == NULL) {
                        ok = ISC_TRUE;
                        break;
                }
                id += qid->qid_increment;
                id &= 0x0000ffff;
-               bucket = dns_hash(qid, dest, id, localport);
        }
        UNLOCK(&qid->lock);
 
@@ -3291,9 +3291,9 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
 
        res = isc_mempool_get(disp->mgr->rpool);
        if (res == NULL) {
-               UNLOCK(&disp->lock);
                if (dispsocket != NULL)
                        destroy_dispsocket(disp, &dispsocket);
+               UNLOCK(&disp->lock);
                return (ISC_R_NOMEMORY);
        }