]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix updating summary RPZ DB for mixed-case RPZs
authorMichał Kępień <michal@isc.org>
Mon, 21 Sep 2020 07:28:36 +0000 (09:28 +0200)
committerMichał Kępień <michal@isc.org>
Mon, 21 Sep 2020 07:32:21 +0000 (09:32 +0200)
Each dns_rpz_zone_t structure keeps a hash table of the names this RPZ
database contains.  Here is what happens when an RPZ is updated:

  - a new hash table is prepared for the new version of the RPZ by
    iterating over it; each name found is added to the summary RPZ
    database,

  - every name added to the new hash table is searched for in the old
    hash table; if found, it is removed from the old hash table,

  - the old hash table is iterated over; all names found in it are
    removed from the summary RPZ database (because at that point the old
    hash table should only contain names which are not present in the
    new version of the RPZ),

  - the new hash table replaces the old hash table.

When the new version of the RPZ is iterated over, if a given name is
spelled using a different letter case than in the old version of the
RPZ, the new variant will hash to a different value than the old
variant, which means it will not be removed from the old hash table.
When the old hash table is subsequently iterated over to remove
seemingly deleted names, the old variant of the name will still be
there, causing the name to be deleted from the summary RPZ database
(which effectively causes a given rule to be ignored).

The issue can be triggered not just by altering the case of existing
names in an RPZ, but also by adding sibling names spelled with a
different letter case.  This is because RBT code preserves case when
node splitting occurs.  The end result is that when the RPZ is iterated
over, a given name may be using a different case than in the zone file
(or XFR contents).

Fix by downcasing all names found in the RPZ database before adding them
to the summary RPZ database.

(cherry picked from commit dc8a7791bd27a7c264e901861875698ef343838c)

bin/tests/system/rpz/clean.sh
bin/tests/system/rpz/ns3/mixed-case-rpz-1.db.in [new file with mode: 0644]
bin/tests/system/rpz/ns3/mixed-case-rpz-2.db.in [new file with mode: 0644]
bin/tests/system/rpz/ns3/named.conf.in
bin/tests/system/rpz/setup.sh
bin/tests/system/rpz/tests.sh
lib/dns/rpz.c

index 40e12eeb15f10acb554b32ede08bb7b442c43a8b..f0e4ff43c84ddaf03de87cfb0eff6f33a6083b3a 100644 (file)
@@ -31,6 +31,7 @@ rm -f ns*/*.key ns*/*.private
 rm -f ns2/tld2s.db ns2/bl.tld2.db
 rm -f ns3/bl*.db ns3/fast-expire.db ns*/empty.db
 rm -f ns3/manual-update-rpz.db
+rm -f ns3/mixed-case-rpz.db
 rm -f ns5/example.db ns5/bl.db ns5/fast-expire.db ns5/expire.conf
 rm -f ns8/manual-update-rpz.db
 rm -f */policy2.db
diff --git a/bin/tests/system/rpz/ns3/mixed-case-rpz-1.db.in b/bin/tests/system/rpz/ns3/mixed-case-rpz-1.db.in
new file mode 100644 (file)
index 0000000..5748942
--- /dev/null
@@ -0,0 +1,14 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+$TTL 300
+@              SOA     mixed-case-rpz.  hostmaster.ns.mixed-case-rpz. ( 1 3600 1200 604800 60 )
+               NS      ns.tld3.
+
+A6-2.TLD2      CNAME   .
diff --git a/bin/tests/system/rpz/ns3/mixed-case-rpz-2.db.in b/bin/tests/system/rpz/ns3/mixed-case-rpz-2.db.in
new file mode 100644 (file)
index 0000000..6588135
--- /dev/null
@@ -0,0 +1,15 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+$TTL 300
+@              SOA     mixed-case-rpz.  hostmaster.ns.mixed-case-rpz. ( 2 3600 1200 604800 60 )
+               NS      ns.tld3.
+
+a6-1.tld2      CNAME   .
+A6-2.TLD2      CNAME   .
index eec06baeb60fe69e3d7be3231e0e4362afeaf31e..89681acab2d11d7ba97def591f8c5b9e1ab808f7 100644 (file)
@@ -48,6 +48,7 @@ options {
            zone "bl-tcp-only"  policy tcp-only;
            zone "bl.tld2";
            zone "manual-update-rpz";
+           zone "mixed-case-rpz";
        }
        add-soa yes
        min-ns-dots 0
@@ -114,6 +115,12 @@ zone "manual-update-rpz." {
        notify no;
 };
 
+zone "mixed-case-rpz." {
+       type primary;
+       file "mixed-case-rpz.db";
+       notify no;
+};
+
 zone "fast-expire." {
        type secondary;
        file "fast-expire.db";
index 937555b3afe3214b10058434ee6ed66a1751ee14..e6c1f16b0b5db3b5378cf0336ddaa055866cfbf4 100644 (file)
@@ -74,6 +74,8 @@ done
 cp ns3/manual-update-rpz.db.in ns3/manual-update-rpz.db
 cp ns8/manual-update-rpz.db.in ns8/manual-update-rpz.db
 
+cp ns3/mixed-case-rpz-1.db.in ns3/mixed-case-rpz.db
+
 # a zone that expires quickly and then can't be refreshed
 cp ns5/fast-expire.db.in ns5/fast-expire.db
 cp ns5/expire.conf.in ns5/expire.conf
index 8def84554234616579cd8850d5d11f6ffb61c612..70c2fc1e2d9600c3f1670cbdc4b584084772be86 100644 (file)
@@ -824,6 +824,24 @@ EOF
     # ensure previous RPZ rules still apply.
     $DIG -p ${PORT} @$ns3 walled.tld2 > dig.out.$t.after
     grep "walled\.tld2\..*IN.*A.*10\.0\.0\.1" dig.out.$t.after > /dev/null || setret "failed"
+
+    t=`expr $t + 1`
+    echo_i "checking reload of a mixed-case RPZ zone (${t})"
+    # First, a sanity check: the A6-2.TLD2.mixed-case-rpz RPZ record should
+    # cause a6-2.tld2 NOERROR answers to be rewritten to NXDOMAIN answers.
+    $DIG -p ${PORT} @$ns3 a6-2.tld2. A > dig.out.$t.before
+    grep "status: NXDOMAIN" dig.out.$t.before >/dev/null || setret "failed"
+    # Add a sibling name (a6-1.tld2.mixed-case-rpz, with "tld2" in lowercase
+    # rather than uppercase) before A6-2.TLD.mixed-case-rpz.
+    nextpart ns3/named.run > /dev/null
+    cp ns3/mixed-case-rpz-2.db.in ns3/mixed-case-rpz.db
+    rndc_reload ns3 $ns3 mixed-case-rpz
+    wait_for_log 20 "rpz: mixed-case-rpz: reload done" ns3/named.run
+    # a6-2.tld2 NOERROR answers should still be rewritten to NXDOMAIN answers.
+    # (The bug we try to trigger here caused a6-2.tld2.mixed-case-rpz to be
+    # erroneously removed from the summary RPZ database after reload.)
+    $DIG -p ${PORT} @$ns3 a6-2.tld2. A > dig.out.$t.after
+    grep "status: NXDOMAIN" dig.out.$t.after >/dev/null || setret "failed"
   fi
 
   t=`expr $t + 1`
index 8d8c459ca90a92401c58cb19521f92b2f24d9e4f..6c02fe5a8df8794f948374ca8b93c2eff102326b 100644 (file)
@@ -2008,6 +2008,7 @@ update_quantum(isc_task_t *task, isc_event_t *event) {
                        continue;
                }
 
+               dns_name_downcase(name, name, NULL);
                result = isc_ht_add(rpz->newnodes, name->ndata, name->length,
                                    rpz);
                if (result != ISC_R_SUCCESS) {