From: Mark Andrews Date: Mon, 9 Mar 2020 00:33:05 +0000 (+1100) Subject: Silence missing unlock from Coverity. X-Git-Tag: v9.17.1~48^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8dd8d48c9f679b58c244cbe09637404905a00af6;p=thirdparty%2Fbind9.git Silence missing unlock from Coverity. 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'. --- diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 9c4391a9cc1..a4522c1dd80 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -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);