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'.
8072static isc_result_t
8073getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *foundname) {
8074 dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
8075 rdatasetheader_t *header = NULL, *this;
8076 unsigned int i;
8077 isc_result_t result = ISC_R_NOTFOUND;
8078 unsigned int locknum;
8079
1. Condition rbtdb != NULL, taking true branch.
2. Condition rbtdb->common.impmagic == (1380074548U /* (((0x52 << 24) | (0x42 << 16)) | (0x44 << 8)) | 0x34 */), taking true branch.
3. Condition !!(rbtdb != NULL && rbtdb->common.impmagic == (1380074548U /* (((0x52 << 24) | (0x42 << 16)) | (0x44 << 8)) | 0x34 */)), taking true branch.
8080 REQUIRE(VALID_RBTDB(rbtdb));
8081
4. Condition !!(isc_rwlock_lock(&rbtdb->tree_lock, isc_rwlocktype_read) == 0), taking true branch.
5. Condition !!(isc_rwlock_lock(&rbtdb->tree_lock, isc_rwlocktype_read) == 0), taking true branch.
8082 RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
8083
6. Condition i < rbtdb->node_lock_count, taking true branch.
13. Condition i < rbtdb->node_lock_count, taking true branch.
20. Condition i < rbtdb->node_lock_count, taking true branch.
28. Condition i < rbtdb->node_lock_count, taking true branch.
38. Condition i < rbtdb->node_lock_count, taking false branch.
8084 for (i = 0; i < rbtdb->node_lock_count; i++) {
7. Condition !!(isc_rwlock_lock(&rbtdb->node_locks[i].lock, isc_rwlocktype_read) == 0), taking true branch.
8. Condition !!(isc_rwlock_lock(&rbtdb->node_locks[i].lock, isc_rwlocktype_read) == 0), taking true branch.
14. Condition !!(isc_rwlock_lock(&rbtdb->node_locks[i].lock, isc_rwlocktype_read) == 0), taking true branch.
15. Condition !!(isc_rwlock_lock(&rbtdb->node_locks[i].lock, isc_rwlocktype_read) == 0), taking true branch.
21. lock: isc_rwlock_lock locks rbtdb->node_locks[i].lock.rwlock. [show details]
22. Condition !!(isc_rwlock_lock(&rbtdb->node_locks[i].lock, isc_rwlocktype_read) == 0), taking true branch.
23. Condition !!(isc_rwlock_lock(&rbtdb->node_locks[i].lock, isc_rwlocktype_read) == 0), taking true branch.
29. Condition !!(isc_rwlock_lock(&rbtdb->node_locks[i].lock, isc_rwlocktype_read) == 0), taking true branch.
30. Condition !!(isc_rwlock_lock(&rbtdb->node_locks[i].lock, isc_rwlocktype_read) == 0), taking true branch.
8085 NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_read);
8086 this = isc_heap_element(rbtdb->heaps[i], 1);
9. Condition this == NULL, taking true branch.
16. Condition this == NULL, taking true branch.
24. Condition this == NULL, taking false branch.
31. Condition this == NULL, taking false branch.
8087 if (this == NULL) {
10. Condition !!(isc_rwlock_unlock(&rbtdb->node_locks[i].lock, isc_rwlocktype_read) == 0), taking true branch.
11. Condition !!(isc_rwlock_unlock(&rbtdb->node_locks[i].lock, isc_rwlocktype_read) == 0), taking true branch.
17. Condition !!(isc_rwlock_unlock(&rbtdb->node_locks[i].lock, isc_rwlocktype_read) == 0), taking true branch.
18. Condition !!(isc_rwlock_unlock(&rbtdb->node_locks[i].lock, isc_rwlocktype_read) == 0), taking true branch.
8088 NODE_UNLOCK(&rbtdb->node_locks[i].lock,
8089 isc_rwlocktype_read);
12. Continuing loop.
19. Continuing loop.
8090 continue;
8091 }
25. Condition header == NULL, taking true branch.
32. Condition header == NULL, taking false branch.
8092 if (header == NULL) {
8093 header = this;
26. Falling through to end of if statement.
33. Condition resign_sooner(this, header), taking true branch.
8094 } else if (resign_sooner(this, header)) {
8095 locknum = header->node->locknum;
34. Condition !!(isc_rwlock_unlock(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_read) == 0), taking true branch.
35. Condition !!(isc_rwlock_unlock(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_read) == 0), taking true branch.
8096 NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
8097 isc_rwlocktype_read);
8098 header = this;
36. Falling through to end of if statement.
8099 } else {
8100 NODE_UNLOCK(&rbtdb->node_locks[i].lock,
8101 isc_rwlocktype_read);
8102 }
27. Jumping back to the beginning of the loop.
37. Jumping back to the beginning of the loop.
8103 }
8104
39. Condition header == NULL, taking false branch.
8105 if (header == NULL) {
8106 goto unlock;
8107 }
8108
8109 bind_rdataset(rbtdb, header->node, header, 0, rdataset);
8110
40. Condition foundname != NULL, taking true branch.
8111 if (foundname != NULL) {
8112 dns_rbt_fullnamefromnode(header->node, foundname);
8113 }
8114
41. Condition !!(isc_rwlock_unlock(&rbtdb->node_locks[header->node->locknum].lock, isc_rwlocktype_read) == 0), taking true branch.
42. Condition !!(isc_rwlock_unlock(&rbtdb->node_locks[header->node->locknum].lock, isc_rwlocktype_read) == 0), taking true branch.
8115 NODE_UNLOCK(&rbtdb->node_locks[header->node->locknum].lock,
8116 isc_rwlocktype_read);
8117
8118 result = ISC_R_SUCCESS;
8119
8120unlock:
43. Condition !!(isc_rwlock_unlock(&rbtdb->tree_lock, isc_rwlocktype_read) == 0), taking true branch.
44. Condition !!(isc_rwlock_unlock(&rbtdb->tree_lock, isc_rwlocktype_read) == 0), taking true branch.
8121 RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
8122
CID 288552 (#1 of 1): Missing unlock (LOCK)
45. missing_unlock: Returning without unlocking rbtdb->node_locks[i].lock.rwlock.
8123 return (result);
8124}
Edited by Mark Andrews