]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3737. [bug] 'rndc retransfer' could trigger a assertion failure
authorMark Andrews <marka@isc.org>
Wed, 12 Feb 2014 21:54:51 +0000 (08:54 +1100)
committerMark Andrews <marka@isc.org>
Wed, 12 Feb 2014 21:55:09 +0000 (08:55 +1100)
                        with inline zones. [RT #35353]

(cherry picked from commit 8e30a7e9fdef51b53448aff26b9f4f339b023a38)

CHANGES
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index 22b92aa2c303752a220044f919f7639520127cc0..fb59c5f9cc92963953458cb2448bd1b0ca3cbce0 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+3737.  [bug]           'rndc retransfer' could trigger a assertion failure
+                       with inline zones. [RT #35353]
+
 3736.  [bug]           nsupdate: When specifying a server by name,
                        fall back to alternate addresses if the first
                        address for that name is not reachable. [RT #25784]
index cc503ae6f1b88756939aca260cffbf3ee52199cd..a91cc74cbf2f105e724d3a68e1e0dc3f6cffe29c 100644 (file)
@@ -13484,7 +13484,6 @@ save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
        isc_result_t result;
        dns_dbnode_t *node = NULL;
        dns_rdataset_t rdataset, prdataset;
-       dns_rdata_t rdata_in, prdata_in, prdata_out;
        dns_dbversion_t *version = NULL;
        nsec3param_t *nsec3param = NULL;
        nsec3param_t *nsec3p = NULL;
@@ -13518,8 +13517,10 @@ save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
             result == ISC_R_SUCCESS;
             result = dns_rdataset_next(&rdataset))
        {
-               dns_rdata_init(&rdata_in);
-               dns_rdataset_current(&rdataset, &rdata_in);
+               dns_rdata_t rdata = DNS_RDATA_INIT;
+               dns_rdata_t private = DNS_RDATA_INIT;
+
+               dns_rdataset_current(&rdataset, &rdata);
                isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
                              DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
                              "looping through nsec3param data");
@@ -13532,11 +13533,10 @@ save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
                 * now transfer the data from the rdata to
                 * the nsec3param
                 */
-               dns_rdata_init(&prdata_out);
-               dns_nsec3param_toprivate(&rdata_in, &prdata_out,
+               dns_nsec3param_toprivate(&rdata, &private,
                                         zone->privatetype, nsec3param->data,
                                         sizeof(nsec3param->data));
-               nsec3param->length = prdata_out.length;
+               nsec3param->length = private.length;
                ISC_LIST_APPEND(*nsec3list, nsec3param, link);
        }
 
@@ -13556,26 +13556,39 @@ save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
             result == ISC_R_SUCCESS;
             result = dns_rdataset_next(&prdataset))
        {
-               dns_rdata_init(&prdata_in);
-               dns_rdataset_current(&prdataset, &prdata_in);
+               dns_rdata_t rdata = DNS_RDATA_INIT;
+               dns_rdata_t private = DNS_RDATA_INIT;
+
+               dns_rdataset_current(&prdataset, &private);
                isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
                              DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
                              "looping through nsec3param private data");
 
-               if (!dns_nsec3param_fromprivate(&prdata_in, &prdata_out,
+               /*
+                * Do we have a valid private record?
+                */
+               if (!dns_nsec3param_fromprivate(&private, &rdata,
                                                buf, sizeof(buf)))
                        continue;
 
-               if ((prdata_out.data[1] & DNS_NSEC3FLAG_REMOVE) !=0) {
-                       prdata_out.data[1] = 0;
+               /*
+                * Remove any NSEC3PARAM records scheduled to be removed.
+                */
+               if (NSEC3REMOVE(rdata.data[1])) {
+                       /*
+                        * Zero out the flags.
+                        */
+                       rdata.data[1] = 0;
 
                        for (nsec3p = ISC_LIST_HEAD(*nsec3list);
                             nsec3p != NULL;
                             nsec3p = next)
                        {
                                next = ISC_LIST_NEXT(nsec3p, link);
-                               if (memcmp(prdata_out.data, nsec3p->data,
-                                   sizeof(nsec3p->data)) == 0) {
+                               
+                               if (nsec3p->length == rdata.length + 1 &&
+                                   memcmp(rdata.data, nsec3p->data + 1,
+                                          nsec3p->length - 1) == 0) {
                                        ISC_LIST_UNLINK(*nsec3list,
                                                        nsec3p, link);
                                        isc_mem_put(zone->mctx, nsec3p,
@@ -13590,11 +13603,13 @@ save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
                        CHECK(ISC_R_NOMEMORY);
                ISC_LINK_INIT(nsec3param, link);
 
-               dns_rdata_init(&prdata_out);
-               dns_nsec3param_toprivate(&prdata_in, &prdata_out,
-                       zone->privatetype, nsec3param->data,
-                       sizeof(nsec3param->data));
-               nsec3param->length = prdata_out.length;
+               /*
+                * Copy the remaining private records so the nsec/nsec3
+                * chain gets created.
+                */
+               INSIST(private.length <= sizeof(nsec3param->data));
+               memmove(nsec3param->data, private.data, private.length);
+               nsec3param->length = private.length;
                ISC_LIST_APPEND(*nsec3list, nsec3param, link);
        }
 
@@ -13810,6 +13825,12 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
                dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
                             dns_result_totext(result));
 
+       while (!ISC_LIST_EMPTY(nsec3list)) {
+               nsec3param_t *nsec3p;
+               nsec3p = ISC_LIST_HEAD(nsec3list);
+               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) {