From d2e1b47d4fc7f2e12ea91cc59dc5f951a9df5fbc Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 12 Jan 2017 14:25:45 +1100 Subject: [PATCH] 4553. [bug] Named could deadlock there were multiple changes to NSEC/NSEC3 parameters for a zone being processed at the same time. [RT #42770] --- CHANGES | 4 ++++ doc/arm/notes.xml | 7 +++++++ lib/dns/rbtdb.c | 3 +++ lib/dns/zone.c | 20 ++++++++++++-------- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index 49e3f0b6be..f3b6a3c9c7 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 965988b9bd..a76a96d5ca 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -195,6 +195,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 b10a6ffee3..90a09a3201 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -9270,6 +9270,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 f715b2a7bf..b426c754ae 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -7475,6 +7475,9 @@ zone_nsec3chain(dns_zone_t *zone) { nsec3chain->save_delete_nsec = nsec3chain->delete_nsec; } + if (nsec3chain != NULL) + goto skip_removals; + /* * Process removals. */ @@ -7682,6 +7685,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. */ @@ -7744,9 +7748,6 @@ zone_nsec3chain(dns_zone_t *zone) { } } - if (nsec3chain != NULL) - dns_dbiterator_pause(nsec3chain->dbiterator); - /* * Add / update signatures for the NSEC3 records. */ @@ -8460,6 +8461,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. */ @@ -8472,11 +8481,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++)