diff --git a/CHANGES b/CHANGES index a20775f377..fb3fb04b09 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +4553. [bug] Named could deadlock there were multiple changes to + NSEC/NSEC3 parameters for a zone being processed at + the same time. [RT #42770] + 4552. [bug] Named could trigger a assertion when sending notify messages. [RT #44019] diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index fe4ed20f19..fd9cd494e3 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -152,6 +152,13 @@
Bug Fixes + + + Named could deadlock there were multiple changes to + NSEC/NSEC3 parameters for a zone being processed at the + same time. [RT #42770] + + Named could trigger a assertion when sending notify diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index df5be506e7..aaa9d95885 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -9186,6 +9186,9 @@ dbiterator_first(dns_dbiterator_t *iterator) { rbtdbiter->result = result; + if (result != ISC_R_SUCCESS) + ENSURE(!rbtdbiter->paused); + return (result); } diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 49a1066fb1..3033e8aa53 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -7380,6 +7380,9 @@ zone_nsec3chain(dns_zone_t *zone) { nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; } + if (nsec3chain != NULL) + goto skip_removals; + /* * Process removals. */ @@ -7587,6 +7590,7 @@ zone_nsec3chain(dns_zone_t *zone) { first = ISC_TRUE; } + skip_removals: /* * We may need to update the NSEC/NSEC3 records for the zone apex. */ @@ -7649,9 +7653,6 @@ zone_nsec3chain(dns_zone_t *zone) { } } - if (nsec3chain != NULL) - dns_dbiterator_pause(nsec3chain->dbiterator); - /* * Add / update signatures for the NSEC3 records. */ @@ -8364,6 +8365,14 @@ zone_sign(dns_zone_t *zone) { } failure: + /* + * Pause all dbiterators. + */ + for (signing = ISC_LIST_HEAD(zone->signing); + signing != NULL; + signing = ISC_LIST_NEXT(signing, link)) + dns_dbiterator_pause(signing->dbiterator); + /* * Rollback the cleanup list. */ @@ -8376,11 +8385,6 @@ zone_sign(dns_zone_t *zone) { signing = ISC_LIST_HEAD(cleanup); } - for (signing = ISC_LIST_HEAD(zone->signing); - signing != NULL; - signing = ISC_LIST_NEXT(signing, link)) - dns_dbiterator_pause(signing->dbiterator); - dns_diff_clear(&_sig_diff); for (i = 0; i < nkeys; i++)