]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
The node lock was released too early.
authorMark Andrews <marka@isc.org>
Thu, 3 Sep 2020 02:53:53 +0000 (12:53 +1000)
committerMark Andrews <marka@isc.org>
Tue, 8 Sep 2020 07:41:33 +0000 (17:41 +1000)
NEGATIVE needs to be call with the node lock held.

WARNING: ThreadSanitizer: data race
  Write of size 2 at 0x000000000001 by thread T1 (mutexes: write M1):
    #0 mark_stale_header lib/dns/rbtdb.c:1802:21
    #1 add32 lib/dns/rbtdb.c:6559:5
    #2 addrdataset lib/dns/rbtdb.c:6975:12
    #3 dns_db_addrdataset lib/dns/db.c:783:10
    #4 cache_name lib/dns/resolver.c:5829:13
    #5 cache_message lib/dns/resolver.c:5926:14
    #6 resquery_response lib/dns/resolver.c:8618:12
    #7 dispatch lib/isc/task.c:1157:7
    #8 run lib/isc/task.c:1331:2

  Previous read of size 2 at 0x000000000001 by thread T2:
    #0 cache_findrdataset lib/dns/rbtdb.c:5932:6
    #1 dns_db_findrdataset lib/dns/db.c:739:10
    #2 query_addadditional2 bin/named/query.c:2196:11
    #3 additionaldata_ns lib/dns/./rdata/generic/ns_2.c:198:10
    #4 dns_rdata_additionaldata lib/dns/rdata.c:1246:2
    #5 dns_rdataset_additionaldata lib/dns/rdataset.c:629:12
    #6 query_addrdataset bin/named/query.c:2411:8
    #7 query_addrrset bin/named/query.c:2802:2
    #8 query_addbestns bin/named/query.c:3501:2
    #9 query_find bin/named/query.c:9165:4
    #10 query_resume bin/named/query.c:4164:12
    #11 dispatch lib/isc/task.c:1157:7
    #12 run lib/isc/task.c:1331:2

lib/dns/rbtdb.c

index 5dca4322502652ee38bb46cbf8c3a3114d1bdc47..21bd85c322b2f79de8932acc7273163d6e691de0 100644 (file)
@@ -5924,10 +5924,10 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
                }
        }
 
-       NODE_UNLOCK(lock, locktype);
-
-       if (found == NULL)
+       if (found == NULL) {
+               NODE_UNLOCK(lock, locktype);
                return (ISC_R_NOTFOUND);
+       }
 
        if (NEGATIVE(found)) {
                /*
@@ -5939,6 +5939,8 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
                        result = DNS_R_NCACHENXRRSET;
        }
 
+       NODE_UNLOCK(lock, locktype);
+
        update_cachestats(rbtdb, result);
 
        return (result);