]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Silence missing unlock from Coverity.
authorMark Andrews <marka@isc.org>
Mon, 9 Mar 2020 00:33:05 +0000 (11:33 +1100)
committerMark Andrews <marka@isc.org>
Fri, 13 Mar 2020 01:42:52 +0000 (12:42 +1100)
Save 'i' to 'locknum' and use that rather than using
'header->node->locknum' when performing the deferred
unlock as 'header->node->locknum' can theoretically be
different to 'i'.

lib/dns/rbtdb.c

index 9c4391a9cc157603e7e86ceb88d1de4e7a68209a..a4522c1dd80bb34cf5e55b1f519a81eb7c1cf67b 100644 (file)
@@ -8075,7 +8075,7 @@ getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *foundname) {
        rdatasetheader_t *header = NULL, *this;
        unsigned int i;
        isc_result_t result = ISC_R_NOTFOUND;
-       unsigned int locknum;
+       unsigned int locknum = 0;
 
        REQUIRE(VALID_RBTDB(rbtdb));
 
@@ -8083,41 +8083,64 @@ getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *foundname) {
 
        for (i = 0; i < rbtdb->node_lock_count; i++) {
                NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_read);
+
+               /*
+                * Find for the earliest signing time among all of the
+                * heaps, each of which is covered by a different bucket
+                * lock.
+                */
                this = isc_heap_element(rbtdb->heaps[i], 1);
                if (this == NULL) {
+                       /* Nothing found; unlock and try the next heap. */
                        NODE_UNLOCK(&rbtdb->node_locks[i].lock,
                                    isc_rwlocktype_read);
                        continue;
                }
+
                if (header == NULL) {
+                       /*
+                        * Found a signing time: retain the bucket lock and
+                        * preserve the lock number so we can unlock it
+                        * later.
+                        */
                        header = this;
+                       locknum = i;
                } else if (resign_sooner(this, header)) {
-                       locknum = header->node->locknum;
+                       /*
+                        * Found an earlier signing time; release the
+                        * previous bucket lock and retain this one instead.
+                        */
                        NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
                                    isc_rwlocktype_read);
                        header = this;
+                       locknum = i;
                } else {
+                       /*
+                        * Earliest signing time in this heap isn't
+                        * an improvement; unlock and try the next heap.
+                        */
                        NODE_UNLOCK(&rbtdb->node_locks[i].lock,
                                    isc_rwlocktype_read);
                }
        }
 
-       if (header == NULL) {
-               goto unlock;
-       }
-
-       bind_rdataset(rbtdb, header->node, header, 0, rdataset);
+       if (header != NULL) {
+               /*
+                * Found something; pass back the answer and unlock
+                * the bucket.
+                */
+               bind_rdataset(rbtdb, header->node, header, 0, rdataset);
 
-       if (foundname != NULL) {
-               dns_rbt_fullnamefromnode(header->node, foundname);
-       }
+               if (foundname != NULL) {
+                       dns_rbt_fullnamefromnode(header->node, foundname);
+               }
 
-       NODE_UNLOCK(&rbtdb->node_locks[header->node->locknum].lock,
-                   isc_rwlocktype_read);
+               NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
+                           isc_rwlocktype_read);
 
-       result = ISC_R_SUCCESS;
+               result = ISC_R_SUCCESS;
+       }
 
-unlock:
        RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
 
        return (result);