]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] address race conditions with removing inline zones
authorEvan Hunt <each@isc.org>
Wed, 10 Jul 2013 00:39:21 +0000 (17:39 -0700)
committerEvan Hunt <each@isc.org>
Wed, 10 Jul 2013 00:39:21 +0000 (17:39 -0700)
3513. [bug] named could crash when deleting inline-signing
zones with "rndc delzone". [RT #34066]

CHANGES
bin/named/server.c
bin/rndc/rndc.c
bin/tests/system/inline/clean.sh
bin/tests/system/inline/ns2/named.conf
bin/tests/system/inline/ns3/named.conf
bin/tests/system/inline/ns3/sign.sh
bin/tests/system/inline/tests.sh
lib/dns/view.c
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index ce50611698b23d7da7d62180537f964187b8af6b..a69a6c54c12cbb95ce1a640d2eb6c8d3da23705e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+3513.  [bug]           named could crash when deleting inline-signing
+                       zones with "rndc delzone". [RT #34066]
+
 3512.  [port]          Check whether to use -ljson or -ljson-c. [RT #34115]
 
 3611.  [bug]           Improved resistance to a theoretical authentication
index c3c9a4cb13619b8246120ec6293117979b3ede79..f0de910ed41e8f56e07a8567071f494b0f9eb410 100644 (file)
@@ -8481,13 +8481,13 @@ inuse(const char* file, isc_boolean_t first, isc_buffer_t *text) {
 
        if (file != NULL && isc_file_exists(file) &&
            isc_buffer_availablelength(text) >
-           strlen(file) + (first ? sizeof(INUSEMSG) : 0))
+           strlen(file) + (first ? sizeof(INUSEMSG) : sizeof("\n")))
        {
                if (first)
-                       isc__buffer_putstr(text, INUSEMSG);
+                       isc_buffer_putstr(text, INUSEMSG);
                else
                        isc_buffer_putstr(text, "\n");
-               isc__buffer_putstr(text, file);
+               isc_buffer_putstr(text, file);
                return (ISC_FALSE);
        }
        return (first);
@@ -8670,6 +8670,7 @@ ns_server_del_zone(ns_server_t *server, char *args, isc_buffer_t *text) {
                isc_buffer_putstr(text, "zone ");
                isc_buffer_putstr(text, zonename);
                isc_buffer_putstr(text, " and associated files deleted");
+               isc_buffer_putuint8(text, 0);
        } else if (dns_zone_gettype(mayberaw) == dns_zone_slave ||
                   dns_zone_gettype(mayberaw) == dns_zone_stub)
        {
@@ -8688,6 +8689,8 @@ ns_server_del_zone(ns_server_t *server, char *args, isc_buffer_t *text) {
                        file = dns_zone_getjournal(zone);
                        (void)inuse(file, first, text);
                }
+               if (isc_buffer_availablelength(text) > 0)
+                       isc_buffer_putuint8(text, 0);
        }
 
        CHECK(dns_zt_unmount(view->zonetable, zone));
@@ -8882,6 +8885,8 @@ ns_server_signing(ns_server_t *server, char *args, isc_buffer_t *text) {
 
                        isc_buffer_add(text, n);
                }
+               if (!first && isc_buffer_availablelength(text) > 0)
+                       isc_buffer_putuint8(text, 0);
 
                if (result == ISC_R_NOMORE)
                        result = ISC_R_SUCCESS;
index 036b3544c7fcb7c66da9d2f1d294f1491d07a3ed..f811830f8fa6e7cb417e019fad2fc2c80b78f75a 100644 (file)
@@ -269,9 +269,10 @@ rndc_recvdone(isc_task_t *task, isc_event_t *event) {
                        progname, isc_result_totext(result));
 
        result = isccc_cc_lookupstring(data, "text", &textmsg);
-       if (result == ISC_R_SUCCESS)
-               printf("%s\n", textmsg);
-       else if (result != ISC_R_NOTFOUND)
+       if (result == ISC_R_SUCCESS) {
+               if (strlen(textmsg) != 0U)
+                       printf("%s\n", textmsg);
+       } else if (result != ISC_R_NOTFOUND)
                fprintf(stderr, "%s: parsing response failed: %s\n",
                        progname, isc_result_totext(result));
 
index 707ab31e7c978bfd71d10aa9f151a047cfb23025..acd04c7e0f66483fb92cec24e1f4d527bbaf97c4 100644 (file)
@@ -71,3 +71,7 @@ rm -f dig.out.ns*.test*
 rm -f signing.out*
 rm -f freeze.test*
 rm -f thaw.test*
+rm -f */*.nzf
+rm -f ns3/test-?.bk
+rm -f ns3/test-?.bk.signed
+rm -f ns3/test-?.bk.signed.jnl
index 9bd4dc1585f7516edc42028847e7a16ffc6a019a..ee576c2db989c8fc00002a36917887c82ada0f4d 100644 (file)
@@ -18,7 +18,9 @@
 
 // NS2
 
-controls { /* empty */ };
+include "../../common/rndc.key";
+
+controls { inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; };
 
 options {
        query-source address 10.53.0.2;
@@ -31,6 +33,7 @@ options {
        recursion no;
        notify yes;
        notify-delay 0;
+       allow-new-zones yes;
 };
 
 zone "bits" {
index ebfb8d9b9a1c78b8e411de9b3ef77500db898b40..5d22e0931ebb3fe29d6575d59c0639828ad25bf6 100644 (file)
@@ -34,6 +34,7 @@ options {
        notify yes;
        try-tcp-refresh no;
        notify-delay 0;
+       allow-new-zones yes;
 };
 
 zone "bits" {
index ed9123fd76ad0a2290130d207b7d938b2168b91c..4faae800e907bfff65cc511cfcbf255ecff00d2d 100644 (file)
@@ -73,3 +73,16 @@ rm -f K${zone}.+*+*.private
 keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone`
 keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -f KSK $zone`
 $DSFROMKEY -T 1200 $keyname >> ../ns1/root.db
+
+for s in a c d h k l m q z
+do
+       zone=test-$s
+       keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone`
+done
+
+for s in b f i o p t v
+do
+       zone=test-$s
+       keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 768 -n zone $zone`
+       keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -f KSK $zone`
+done
index 987041186de195abe28342b500fca8bc531f30aa..b727604cfd2cd0a5afb4b99ce1d45e3bf1385019 100644 (file)
@@ -776,4 +776,20 @@ done
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+ret=0
+echo "I:test add/del zone combinations"
+for zone in a b c d e f g h i j k l m n o p q r s t u v w x y z
+do
+$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 addzone test-$zone \
+       '{ type master; file "bits.db.in"; allow-transfer { any; }; };'
+$DIG $DIGOPTS @10.53.0.2 -p 5300 test-$zone SOA > dig.out.ns2.$zone.test$n
+grep "status: NOERROR," dig.out.ns2.$zone.test$n  > /dev/null || { ret=1; cat dig.out.ns2.$zone.test$n; }
+$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 addzone test-$zone \
+       '{ type slave; masters { 10.53.0.2; }; file "'test-$zone.bk'"; inline-signing yes; auto-dnssec maintain; allow-transfer { any; }; };'
+$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 delzone test-$zone
+done
+
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 exit $status
index 5ae96107e5b47d2bf07f5aad7dfb6582033ee1da..35969134b14686b8ed4813762c2d46264334649a 100644 (file)
@@ -1393,6 +1393,8 @@ dns_viewlist_findzone(dns_viewlist_t *list, dns_name_t *name,
        dns_zone_t **zp = NULL;;
 
        REQUIRE(list != NULL);
+       REQUIRE(zonep != NULL && *zonep == NULL);
+
        for (view = ISC_LIST_HEAD(*list);
             view != NULL;
             view = ISC_LIST_NEXT(view, link)) {
index 643cbc25f974f10d5fb8bff2959bd661339a7ca8..0a7180ce5e65b9ef434d7f28970ab25ddd25a3c4 100644 (file)
@@ -7639,8 +7639,13 @@ zone_sign(dns_zone_t *zone) {
        }
 
        ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
-       dns_db_attach(zone->db, &db);
+       if (zone->db != NULL)
+               dns_db_attach(zone->db, &db);
        ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
+       if (db == NULL) {
+               result = ISC_R_FAILURE;
+               goto failure;
+       }
 
        result = dns_db_newversion(db, &version);
        if (result != ISC_R_SUCCESS) {
@@ -13244,12 +13249,16 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
        rawdb = ((struct secure_event *)event)->db;
        isc_event_free(&event);
 
-       REQUIRE(inline_secure(zone));
-
        dns_fixedname_init(&fname);
        name = dns_fixedname_name(&fname);
        dns_rdataset_init(&rdataset);
 
+       LOCK_ZONE(zone);
+       if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) {
+               result = ISC_R_SHUTTINGDOWN;
+               goto unlock;
+       }
+
        TIME_NOW(&loadtime);
        if (zone->db != NULL) {
                result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
@@ -13320,15 +13329,13 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
        /*
         * Lock hierarchy: zmgr, zone, raw.
         */
-       LOCK_ZONE(zone);
        INSIST(zone != zone->raw);
-       if (inline_secure(zone))
-               LOCK_ZONE(zone->raw);
+       LOCK_ZONE(zone->raw);
        DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
        result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
        zone_needdump(zone, 0); /* XXXMPA */
-       if (inline_secure(zone))
-               UNLOCK_ZONE(zone->raw);
+       UNLOCK_ZONE(zone->raw);
+ unlock:
        UNLOCK_ZONE(zone);
 
  failure: