mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-09 13:42:06 -04:00
Merge branch '1501-summary-threadsanitizer-lock-order-inversion-potential-deadlock-in-pthread_rwlock_wrlock-v9_14' into 'v9_14'
Resolve "SUMMARY: ThreadSanitizer: lock-order-inversion (potential deadlock) in pthread_rwlock_wrlock - zone_postload" See merge request isc-projects/bind9!2789
This commit is contained in:
commit
19079bbec0
1 changed files with 97 additions and 64 deletions
161
lib/dns/zone.c
161
lib/dns/zone.c
|
|
@ -15295,21 +15295,86 @@ restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
|
|||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
copy_non_dnssec_records(dns_db_t *db, dns_db_t *version, dns_db_t *rawdb,
|
||||
dns_dbiterator_t *dbiterator, unsigned int *oldserial)
|
||||
{
|
||||
dns_dbnode_t *rawnode = NULL, *node = NULL;
|
||||
dns_fixedname_t fixed;
|
||||
dns_name_t *name = dns_fixedname_initname(&fixed);
|
||||
dns_rdataset_t rdataset;
|
||||
dns_rdatasetiter_t *rdsit = NULL;
|
||||
isc_result_t result;
|
||||
|
||||
result = dns_dbiterator_current(dbiterator, &rawnode, name);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
result = dns_db_findnode(db, name, true, &node);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
dns_rdataset_init(&rdataset);
|
||||
|
||||
for (result = dns_rdatasetiter_first(rdsit);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdatasetiter_next(rdsit))
|
||||
{
|
||||
dns_rdatasetiter_current(rdsit, &rdataset);
|
||||
if (rdataset.type == dns_rdatatype_nsec ||
|
||||
rdataset.type == dns_rdatatype_rrsig ||
|
||||
rdataset.type == dns_rdatatype_nsec3 ||
|
||||
rdataset.type == dns_rdatatype_dnskey ||
|
||||
rdataset.type == dns_rdatatype_nsec3param) {
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
continue;
|
||||
}
|
||||
if (rdataset.type == dns_rdatatype_soa && oldserial != NULL) {
|
||||
result = checkandaddsoa(db, node, version,
|
||||
&rdataset, *oldserial);
|
||||
} else {
|
||||
result = dns_db_addrdataset(db, node, version,
|
||||
0, &rdataset, 0,
|
||||
NULL);
|
||||
}
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
if (result == ISC_R_NOMORE) {
|
||||
result = ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (rdsit != NULL) {
|
||||
dns_rdatasetiter_destroy(&rdsit);
|
||||
}
|
||||
if (rawnode) {
|
||||
dns_db_detachnode(rawdb, &rawnode);
|
||||
}
|
||||
if (node) {
|
||||
dns_db_detachnode(db, &node);
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
receive_secure_db(isc_task_t *task, isc_event_t *event) {
|
||||
isc_result_t result;
|
||||
dns_zone_t *zone;
|
||||
dns_db_t *rawdb, *db = NULL;
|
||||
dns_dbnode_t *rawnode = NULL, *node = NULL;
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *name;
|
||||
dns_dbiterator_t *dbiterator = NULL;
|
||||
dns_rdatasetiter_t *rdsit = NULL;
|
||||
dns_rdataset_t rdataset;
|
||||
dns_dbversion_t *version = NULL;
|
||||
isc_time_t loadtime;
|
||||
unsigned int oldserial = 0;
|
||||
bool have_oldserial = false;
|
||||
unsigned int oldserial = 0, *oldserialp = NULL;
|
||||
nsec3paramlist_t nsec3list;
|
||||
isc_event_t *setnsec3param_event;
|
||||
dns_zone_t *dummy;
|
||||
|
|
@ -15322,9 +15387,6 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
|
|||
rawdb = ((struct secure_event *)event)->db;
|
||||
isc_event_free(&event);
|
||||
|
||||
name = dns_fixedname_initname(&fname);
|
||||
dns_rdataset_init(&rdataset);
|
||||
|
||||
LOCK_ZONE(zone);
|
||||
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) {
|
||||
result = ISC_R_SHUTTINGDOWN;
|
||||
|
|
@ -15335,8 +15397,9 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
|
|||
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
|
||||
if (zone->db != NULL) {
|
||||
result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
have_oldserial = true;
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
oldserialp = &oldserial;
|
||||
}
|
||||
|
||||
/*
|
||||
* assemble nsec3parameters from the old zone, and set a flag
|
||||
|
|
@ -15353,8 +15416,9 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
|
|||
result = dns_db_create(zone->mctx, zone->db_argv[0],
|
||||
&zone->origin, dns_dbtype_zone, zone->rdclass,
|
||||
zone->db_argc - 1, zone->db_argv + 1, &db);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
result = dns_db_setgluecachestats(db, zone->gluecachestats);
|
||||
if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
|
||||
|
|
@ -15362,56 +15426,28 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
|
|||
}
|
||||
|
||||
result = dns_db_newversion(db, &version);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
result = dns_db_createiterator(rawdb, 0, &dbiterator);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
for (result = dns_dbiterator_first(dbiterator);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_dbiterator_next(dbiterator)) {
|
||||
result = dns_dbiterator_current(dbiterator, &rawnode, name);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
continue;
|
||||
|
||||
result = dns_db_findnode(db, name, true, &node);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
result = dns_dbiterator_next(dbiterator))
|
||||
{
|
||||
result = copy_non_dnssec_records(db, version, rawdb,
|
||||
dbiterator, oldserialp);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto failure;
|
||||
|
||||
result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto failure;
|
||||
|
||||
for (result = dns_rdatasetiter_first(rdsit);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdatasetiter_next(rdsit)) {
|
||||
dns_rdatasetiter_current(rdsit, &rdataset);
|
||||
if (rdataset.type == dns_rdatatype_nsec ||
|
||||
rdataset.type == dns_rdatatype_rrsig ||
|
||||
rdataset.type == dns_rdatatype_nsec3 ||
|
||||
rdataset.type == dns_rdatatype_dnskey ||
|
||||
rdataset.type == dns_rdatatype_nsec3param) {
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
continue;
|
||||
}
|
||||
if (rdataset.type == dns_rdatatype_soa &&
|
||||
have_oldserial) {
|
||||
result = checkandaddsoa(db, node, version,
|
||||
&rdataset, oldserial);
|
||||
} else
|
||||
result = dns_db_addrdataset(db, node, version,
|
||||
0, &rdataset, 0,
|
||||
NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto failure;
|
||||
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
}
|
||||
dns_rdatasetiter_destroy(&rdsit);
|
||||
dns_db_detachnode(rawdb, &rawnode);
|
||||
dns_db_detachnode(db, &node);
|
||||
}
|
||||
dns_dbiterator_destroy(&dbiterator);
|
||||
if (result != ISC_R_NOMORE) {
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -15451,9 +15487,13 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
|
|||
|
||||
failure:
|
||||
UNLOCK_ZONE(zone);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
if (dbiterator != NULL) {
|
||||
dns_dbiterator_destroy(&dbiterator);
|
||||
}
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
|
||||
dns_result_totext(result));
|
||||
}
|
||||
|
||||
while (!ISC_LIST_EMPTY(nsec3list)) {
|
||||
nsec3param_t *nsec3p;
|
||||
|
|
@ -15461,20 +15501,13 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
|
|||
ISC_LIST_UNLINK(nsec3list, nsec3p, link);
|
||||
isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
|
||||
}
|
||||
if (dns_rdataset_isassociated(&rdataset))
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
if (db != NULL) {
|
||||
if (node != NULL)
|
||||
dns_db_detachnode(db, &node);
|
||||
if (version != NULL)
|
||||
if (version != NULL) {
|
||||
dns_db_closeversion(db, &version, false);
|
||||
}
|
||||
dns_db_detach(&db);
|
||||
}
|
||||
if (rawnode != NULL)
|
||||
dns_db_detachnode(rawdb, &rawnode);
|
||||
dns_db_detach(&rawdb);
|
||||
if (dbiterator != NULL)
|
||||
dns_dbiterator_destroy(&dbiterator);
|
||||
dns_zone_idetach(&zone);
|
||||
|
||||
INSIST(version == NULL);
|
||||
|
|
|
|||
Loading…
Reference in a new issue