From 0f2ecf4b5c6721629162d4fd32826189d33a9b03 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 16 Sep 2015 10:43:22 +1000 Subject: [PATCH] 4207. [bug] Handle class mismatches with raw zone files. [RT #40746] --- CHANGES | 3 +++ bin/tests/system/checkzone/tests.sh | 8 ++++++++ .../system/checkzone/zones/.gitattributes | 1 + .../system/checkzone/zones/bad-badclass.raw | Bin 0 -> 104 bytes lib/dns/master.c | 4 ++++ lib/dns/rbtdb.c | 3 ++- lib/dns/xfrin.c | 19 +++++++++++++++--- 7 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 bin/tests/system/checkzone/zones/.gitattributes create mode 100644 bin/tests/system/checkzone/zones/bad-badclass.raw diff --git a/CHANGES b/CHANGES index 16ebb0fb5c..0c687d900a 100644 --- 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] diff --git a/bin/tests/system/checkzone/tests.sh b/bin/tests/system/checkzone/tests.sh index 4fffa3e988..82ef4b5a04 100644 --- a/bin/tests/system/checkzone/tests.sh +++ b/bin/tests/system/checkzone/tests.sh @@ -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 index 0000000000..a1b3cec0ee --- /dev/null +++ b/bin/tests/system/checkzone/zones/.gitattributes @@ -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 index 0000000000000000000000000000000000000000..d8f1bf7414e5a78f7073fd2f6070f65c61b4839b GIT binary patch literal 104 ocmZQzU|?ckU|=-B3K$p}7(fyr6%5RbKw1i`IwV0%Ei52e0HxUs?f?J) literal 0 HcmV?d00001 diff --git a/lib/dns/master.c b/lib/dns/master.c index e2d4d6bc2f..7d994dcdb1 100644 --- a/lib/dns/master.c +++ b/lib/dns/master.c @@ -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); diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index f63c7ae252..0cd1e0e960 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -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. */ diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index 30cfdaf1b2..4781465168 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -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)