]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2938. [bug] When generating signed responses, from a signed zone
authorMark Andrews <marka@isc.org>
Fri, 13 Aug 2010 07:00:40 +0000 (07:00 +0000)
committerMark Andrews <marka@isc.org>
Fri, 13 Aug 2010 07:00:40 +0000 (07:00 +0000)
                        that uses NSEC3, named would use a uninitialised
                        pointer if it needed to skip a NSEC3 record because
                        it didn't match the selected NSEC3PARAM record for
                        zone. [RT# 21868]

CHANGES
bin/tests/system/dnssec/clean.sh
bin/tests/system/dnssec/dnssec_update_test.pl
bin/tests/system/dnssec/ns2/badparam.db.in [new file with mode: 0644]
bin/tests/system/dnssec/ns2/named.conf
bin/tests/system/dnssec/ns2/sign.sh
bin/tests/system/dnssec/tests.sh
lib/dns/rbtdb.c

diff --git a/CHANGES b/CHANGES
index e770b98850caed731c3b5397997d71dda58bd319..e3bd4b90c350b6b18229af6d0656803ccd404dac 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,9 @@
+2938.  [bug]           When generating signed responses, from a signed zone
+                       that uses NSEC3, named would use a uninitialised
+                       pointer if it needed to skip a NSEC3 record because
+                       it didn't match the selected NSEC3PARAM record for
+                       zone. [RT# 21868]
+
 2937.  [bug]           Worked around an apparent race condition in over
                        memory conditions.  Without this fix a DNS cache DB or
                        ADB could incorrectly stay in an over memory state,
index fb54f14d29f753d2c0a74aca9cb22326c0afee2c..904815b2380f1659514bae319c25f10f6e4d2e7d 100644 (file)
@@ -15,7 +15,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: clean.sh,v 1.25.32.3 2010/06/25 03:51:06 marka Exp $
+# $Id: clean.sh,v 1.25.32.4 2010/08/13 07:00:40 marka Exp $
 
 rm -f */K* */keyset-* */dsset-* */dlvset-* */signedkey-* */*.signed */trusted.conf */tmp* */*.jnl */*.bk
 rm -f ns1/root.db ns2/example.db ns3/secure.example.db
@@ -23,6 +23,7 @@ rm -f ns3/unsecure.example.db ns3/bogus.example.db ns3/keyless.example.db
 rm -f ns3/dynamic.example.db ns3/dynamic.example.db.signed.jnl
 rm -f ns3/rsasha256.example.db ns3/rsasha512.example.db
 rm -f ns2/private.secure.example.db
+rm -f ns2/badparam.db ns2/badparam.db.bad
 rm -f */example.bk
 rm -f dig.out.*
 rm -f random.data
index 3a87242ef609746cc283a1fab4131289a651780e..9d5fda03e4af7edaed27102fc217b74f2aef2418 100644 (file)
@@ -32,7 +32,7 @@
 #
 #    perl -MCPAN -e "install Net::DNS"
 #
-# $Id: dnssec_update_test.pl,v 1.5 2007/06/19 23:47:02 tbox Exp $
+# $Id: dnssec_update_test.pl,v 1.5.558.1 2010/08/13 07:00:40 marka Exp $
 #
 
 use Getopt::Std;
@@ -97,9 +97,9 @@ section("Delete the name");
 test("NOERROR", ["update", rr_del("a.$zone")]);
 
 if ($failures) {
-    print "I:$failures tests failed.\n";
+    print "I:$failures update tests failed.\n";
 } else {
-    print "I:All tests successful.\n";
+    print "I:All update tests successful.\n";
 }
 
 exit $failures;
diff --git a/bin/tests/system/dnssec/ns2/badparam.db.in b/bin/tests/system/dnssec/ns2/badparam.db.in
new file mode 100644 (file)
index 0000000..d8dccd2
--- /dev/null
@@ -0,0 +1,26 @@
+; Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+;
+; Permission to use, copy, modify, and/or distribute this software for any
+; purpose with or without fee is hereby granted, provided that the above
+; copyright notice and this permission notice appear in all copies.
+;
+; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+; AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+; PERFORMANCE OF THIS SOFTWARE.
+
+; $Id: badparam.db.in,v 1.2.2.2 2010/08/13 07:00:40 marka Exp $
+
+$TTL 300       ; 5 minutes
+@                      IN SOA  mname1. . (
+                               2010081000 ; serial
+                               20         ; refresh (20 seconds)
+                               20         ; retry (20 seconds)
+                               1814400    ; expire (3 weeks)
+                               3600       ; minimum (1 hour)
+                               )
+                       NS      ns2
+ns2                    A       10.53.0.2
index 3160413010a5839743e26fa96aa33e93437fa73e..b6cf3dd9238c8e7add8207c4c901c3e0582b1283 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: named.conf,v 1.30 2008/09/25 04:02:38 tbox Exp $ */
+/* $Id: named.conf,v 1.30.268.1 2010/08/13 07:00:40 marka Exp $ */
 
 // NS2
 
@@ -80,4 +80,10 @@ zone "child.optout.example" {
        allow-update { none; };
 };
 
+
+zone "badparam" {
+       type master;
+       file "badparam.db.bad";
+};
+
 include "trusted.conf";
index 3bae1db1388f003c675972fbc0762e0d1f62e306..c9f15fc21027969ba760b1c14ea3bd42ed455d84 100644 (file)
@@ -15,7 +15,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: sign.sh,v 1.35.32.3 2010/01/18 23:48:01 tbox Exp $
+# $Id: sign.sh,v 1.35.32.4 2010/08/13 07:00:40 marka Exp $
 
 SYSTEMTESTTOP=../..
 . $SYSTEMTESTTOP/conf.sh
@@ -114,3 +114,19 @@ dlvkeyname=`$KEYGEN -q -r $RANDFILE -a RSAMD5 -b 768 -n zone $dlvzone`
 cat $dlvinfile $dlvkeyname.key dlvset-$privzone > $dlvzonefile
 
 $SIGNER -P -g -r $RANDFILE -o $dlvzone $dlvzonefile > /dev/null
+
+
+# Sign the badparam secure file
+
+zone=badparam.
+infile=badparam.db.in
+zonefile=badparam.db
+
+keyname1=`$KEYGEN -q -r $RANDFILE -a RSASHA256 -b 1024 -n zone -f KSK $zone`
+keyname2=`$KEYGEN -q -r $RANDFILE -a RSASHA256 -b 1024 -n zone $zone`
+
+cat $infile $keyname1.key $keyname2.key >$zonefile
+
+$SIGNER -P -3 - -H 1 -g -r $RANDFILE -o $zone -k $keyname1 $zonefile $keyname2 > /dev/null
+
+sed 's/IN NSEC3 1 0 1 /IN NSEC3 1 0 10 /' $zonefile.signed > $zonefile.bad
index f97717ea3611f15bb367078fcc2bf92cb1bf8750..76a2f93b0c7ad260a20294a2b06a373f88b2ec22 100644 (file)
@@ -15,7 +15,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: tests.sh,v 1.55.32.12 2010/08/09 22:35:06 each Exp $
+# $Id: tests.sh,v 1.55.32.13 2010/08/13 07:00:40 marka Exp $
 
 SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
@@ -995,6 +995,17 @@ n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+#
+# RT21868 regression test.
+#
+echo "I:checking NSEC3 zone with mismatched NSEC3PARAM / NSEC parameters ($n)"
+ret=0
+$DIG $DIGOPTS non-exist.badparam. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
+grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 # Run a minimal update test if possible.  This is really just
 # a regression test for RT #2399; more tests should be added.
 
index bfdaf6c6d30df5fff10012e9144759c083c9e140..41fe78d23cd91f684e174fb42d28716848b64667 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rbtdb.c,v 1.292.8.10 2010/08/11 22:56:58 jinmei Exp $ */
+/* $Id: rbtdb.c,v 1.292.8.11 2010/08/13 07:00:39 marka Exp $ */
 
 /*! \file */
 
@@ -3275,6 +3275,9 @@ matchparams(rdatasetheader_t *header, rbtdb_search_t *search)
        return (ISC_FALSE);
 }
 
+/*
+ * Find node of the NSEC/NSEC3 record that is 'name'.
+ */
 static inline isc_result_t
 previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search,
                    dns_name_t *name, dns_name_t *origin,
@@ -3286,15 +3289,15 @@ previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search,
        dns_rbtnode_t *nsecnode;
        isc_result_t result;
 
+       REQUIRE(nodep != NULL && *nodep == NULL);
+
        if (type == dns_rdatatype_nsec3) {
                result = dns_rbtnodechain_prev(&search->chain, NULL, NULL);
                if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN)
                        return (result);
                result = dns_rbtnodechain_current(&search->chain, name, origin,
                                                  nodep);
-               if (result != ISC_R_SUCCESS)
-                       return (result);
-               return (ISC_R_SUCCESS);
+               return (result);
        }
 
        dns_fixedname_init(&ftarget);
@@ -3327,11 +3330,11 @@ previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search,
                                 * Try the previous node in the NSEC tree.
                                 */
                                result = dns_rbtnodechain_prev(nsecchain,
-                                                       name, origin);
+                                                              name, origin);
                                if (result == DNS_R_NEWORIGIN)
                                        result = ISC_R_SUCCESS;
-                       } else if (result == ISC_R_NOTFOUND
-                                  || result == DNS_R_PARTIALMATCH) {
+                       } else if (result == ISC_R_NOTFOUND ||
+                                  result == DNS_R_PARTIALMATCH) {
                                result = dns_rbtnodechain_current(nsecchain,
                                                        name, origin, NULL);
                                if (result == ISC_R_NOTFOUND)
@@ -3348,8 +3351,6 @@ previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search,
                        result = dns_rbtnodechain_prev(nsecchain, name, origin);
                        if (result == DNS_R_NEWORIGIN)
                                result = ISC_R_SUCCESS;
-                       if (result != ISC_R_SUCCESS)
-                               return (result);
                }
                if (result != ISC_R_SUCCESS)
                        return (result);
@@ -3373,10 +3374,7 @@ previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search,
                 * same name as the node in the auxiliary NSEC tree, except for
                 * nodes in the auxiliary tree that are awaiting deletion.
                 */
-               if (result == DNS_R_PARTIALMATCH)
-                       result = ISC_R_NOTFOUND;
-
-               if (result != ISC_R_NOTFOUND) {
+               if (result != DNS_R_PARTIALMATCH && result != ISC_R_NOTFOUND) {
                        isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
                                      DNS_LOGMODULE_CACHE, ISC_LOG_ERROR,
                                      "previous_closest_nsec(): %s",
@@ -3386,6 +3384,11 @@ previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search,
        }
 }
 
+/*
+ * Find the NSEC/NSEC3 which is or before the current point on the
+ * search chain.  For NSEC3 records only NSEC3 records that match the
+ * current NSEC3PARAM record are considered.
+ */
 static inline isc_result_t
 find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
                  dns_name_t *foundname, dns_rdataset_t *rdataset,
@@ -3419,15 +3422,16 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
         * Use the auxiliary tree only starting with the second node in the
         * hope that the original node will be right much of the time.
         */
-               dns_fixedname_init(&fname);
-               name = dns_fixedname_name(&fname);
-               dns_fixedname_init(&forigin);
-               origin = dns_fixedname_name(&forigin);
+       dns_fixedname_init(&fname);
+       name = dns_fixedname_name(&fname);
+       dns_fixedname_init(&forigin);
+       origin = dns_fixedname_name(&forigin);
  again:
        node = NULL;
+       prevnode = NULL;
        result = dns_rbtnodechain_current(&search->chain, name, origin, &node);
-               if (result != ISC_R_SUCCESS)
-                       return (result);
+       if (result != ISC_R_SUCCESS)
+               return (result);
        do {
                NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock),
                          isc_rwlocktype_read);
@@ -3478,8 +3482,10 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
                                empty_node = ISC_TRUE;
                                found = NULL;
                                foundsig = NULL;
-                               result = dns_rbtnodechain_prev(&search->chain,
-                                                              NULL, NULL);
+                               result = previous_closest_nsec(type, search,
+                                                              name, origin,    
+                                                              &prevnode, NULL,
+                                                              NULL);
                        } else if (found != NULL &&
                                   (foundsig != NULL || !need_sig)) {
                                /*
@@ -3519,8 +3525,10 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
                                 */
                                empty_node = ISC_TRUE;
                                result = previous_closest_nsec(type, search,
-                                                       name, origin, &prevnode,
-                                                       &nsecchain, &first);
+                                                              name, origin,
+                                                              &prevnode,
+                                                              &nsecchain,
+                                                              &first);
                        } else {
                                /*
                                 * We found an active node, but either the
@@ -3541,6 +3549,7 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
                NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock),
                            isc_rwlocktype_read);
                node = prevnode;
+               prevnode = NULL;
        } while (empty_node && result == ISC_R_SUCCESS);
 
        if (!first)