]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
4207. [bug] Handle class mismatches with raw zone files.
authorMark Andrews <marka@isc.org>
Wed, 16 Sep 2015 00:43:22 +0000 (10:43 +1000)
committerMark Andrews <marka@isc.org>
Wed, 16 Sep 2015 00:43:22 +0000 (10:43 +1000)
                        [RT #40746]

CHANGES
bin/tests/system/checkzone/tests.sh
bin/tests/system/checkzone/zones/.gitattributes [new file with mode: 0644]
bin/tests/system/checkzone/zones/bad-badclass.raw [new file with mode: 0644]
lib/dns/master.c
lib/dns/rbtdb.c
lib/dns/xfrin.c

diff --git a/CHANGES b/CHANGES
index 16ebb0fb5c06da120079cfd4caeff2f679c4769c..0c687d900a6f50b278706e294f8fd2b93832cfb8 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+4207.  [bug]           Handle class mismatches with raw zone files.
+                       [RT #40746]
+
 4206.   [bug]           contrib: fixed a possible NULL dereference in
                        DLZ wildcard module. [RT #40745]
 
index 4fffa3e988e4464425176c74c3714bac84fe77d3..82ef4b5a044641383b5c85cab4c6b5db7ef19c70 100644 (file)
@@ -133,5 +133,13 @@ n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+echo "I:checking that raw zone with bad class is handled ($n)"
+ret=0
+$CHECKZONE -f raw example zones/bad-badclass.raw > test.out.$n 2>&1 && ret=1
+grep "failed: bad class" test.out.$n >/dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 echo "I:exit status: $status"
 exit $status
diff --git a/bin/tests/system/checkzone/zones/.gitattributes b/bin/tests/system/checkzone/zones/.gitattributes
new file mode 100644 (file)
index 0000000..a1b3cec
--- /dev/null
@@ -0,0 +1 @@
+*.raw -text
diff --git a/bin/tests/system/checkzone/zones/bad-badclass.raw b/bin/tests/system/checkzone/zones/bad-badclass.raw
new file mode 100644 (file)
index 0000000..d8f1bf7
Binary files /dev/null and b/bin/tests/system/checkzone/zones/bad-badclass.raw differ
index e2d4d6bc2f2935bc610c35441b5885853ab38343..7d994dcdb18b85169cbad77f0201e467b621dfa4 100644 (file)
@@ -2385,6 +2385,10 @@ load_raw(dns_loadctx_t *lctx) {
                /* Construct RRset headers */
                dns_rdatalist_init(&rdatalist);
                rdatalist.rdclass = isc_buffer_getuint16(&target);
+               if (lctx->zclass != rdatalist.rdclass) {
+                       result = DNS_R_BADCLASS;
+                       goto cleanup;
+               }
                rdatalist.type = isc_buffer_getuint16(&target);
                rdatalist.covers = isc_buffer_getuint16(&target);
                rdatalist.ttl =  isc_buffer_getuint32(&target);
index f63c7ae252622a0d44d0cca1b95fd151198df0e1..0cd1e0e96026a1e7489aa2327b76c47d31a575ef 100644 (file)
@@ -7118,13 +7118,14 @@ loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) {
        isc_region_t region;
        rdatasetheader_t *newheader;
 
+       REQUIRE(rdataset->rdclass == rbtdb->common.rdclass);
+
        /*
         * This routine does no node locking.  See comments in
         * 'load' below for more information on loading and
         * locking.
         */
 
-
        /*
         * SOA records are only allowed at top of zone.
         */
index 30cfdaf1b27544da7e9552f3567517a542150d72..4781465168ee5ad3712538be0f3b81337d22023f 100644 (file)
@@ -292,6 +292,9 @@ axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
 
        dns_difftuple_t *tuple = NULL;
 
+       if (rdata->rdclass != xfr->rdclass)
+               return(DNS_R_BADCLASS);
+
        CHECK(dns_zone_checknames(xfr->zone, name, rdata));
        CHECK(dns_difftuple_create(xfr->diff.mctx, op,
                                   name, ttl, rdata, &tuple));
@@ -376,8 +379,11 @@ ixfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op,
             dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
 {
        isc_result_t result;
-
        dns_difftuple_t *tuple = NULL;
+
+       if (rdata->rdclass != xfr->rdclass)
+               return(DNS_R_BADCLASS);
+
        if (op == DNS_DIFFOP_ADD)
                CHECK(dns_zone_checknames(xfr->zone, name, rdata));
        CHECK(dns_difftuple_create(xfr->diff.mctx, op,
@@ -1246,10 +1252,17 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) {
                          dns_result_totext(result));
 
        if (result != ISC_R_SUCCESS || msg->rcode != dns_rcode_noerror ||
+           msg->opcode != dns_opcode_query ||msg->rdclass != xfr->rdclass ||
            (xfr->checkid && msg->id != xfr->id)) {
-               if (result == ISC_R_SUCCESS)
+               if (result == ISC_R_SUCCESS && msg->rcode != dns_rcode_noerror)
                        result = ISC_RESULTCLASS_DNSRCODE + msg->rcode; /*XXX*/
-               if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR)
+               else if (result == ISC_R_SUCCESS &&
+                        msg->opcode != dns_opcode_query)
+                       result = DNS_R_UNEXPECTEDOPCODE;
+               else if (result == ISC_R_SUCCESS &&
+                        msg->rdclass != xfr->rdclass)
+                       result = DNS_R_BADCLASS;
+               else if (result == ISC_R_SUCCESS || result == DNS_R_NOERROR)
                        result = DNS_R_UNEXPECTEDID;
                if (xfr->reqtype == dns_rdatatype_axfr ||
                    xfr->reqtype == dns_rdatatype_soa)