Merge branch '2528-check-soa-rdata' into 'main'

Check SOA rdata for consistency in AXFR.

Closes #2528

See merge request isc-projects/bind9!5014
This commit is contained in:
Mark Andrews
2021-05-13 05:17:39 +00:00
5 changed files with 59 additions and 1 deletions

View File

@@ -1,3 +1,6 @@
5639. [bug] Check that the first and last SOA record of an AXFR
are consistent. [GL #2528]
5638. [bug] Improvements related to network manager/task manager
integration:
- added isc_managers_create() and _destroy() functions

View File

@@ -0,0 +1,10 @@
/SOA tsig_key LSAnCU+Z/
nil. 300 SOA ns.nil. root.nil. 1 300 300 604800 300
/AXFR tsig_key LSAnCU+Z/
nil. 300 SOA ns.nil. root.nil. 1 300 300 604800 300
/AXFR tsig_key LSAnCU+Z/
nil. 300 NS ns.nil.
nil. 300 TXT "SOA mismatch AXFR"
a.nil. 60 A 10.0.0.61
/AXFR tsig_key LSAnCU+Z/
nil. 300 SOA whatever. other. 1 300 300 604800 300

View File

@@ -428,6 +428,25 @@ $DIGCMD nil. TXT | grep 'bad message id' >/dev/null && {
status=$((status+1))
}
n=$((n+1))
echo_i "mismatched SOA ($n)"
sendcmd < ans5/soamismatch
$RNDCCMD 10.53.0.4 retransfer nil | sed 's/^/ns4 /' | cat_i
sleep 2
nextpart ns4/named.run | grep "Transfer status: FORMERR" > /dev/null || {
echo_i "failed: expected status was not logged"
status=$((status+1))
}
$DIGCMD nil. TXT | grep 'SOA mismatch AXFR' >/dev/null && {
echo_i "failed"
status=$((status+1))
}
n=$((n+1))
echo_i "check that we ask for and get a EDNS EXPIRE response ($n)"
# force a refresh query

View File

@@ -180,6 +180,9 @@ struct dns_xfrin_ctx {
uint32_t current_serial;
dns_journal_t *journal;
} ixfr;
dns_rdata_t firstsoa;
unsigned char *firstsoa_data;
};
#define XFRIN_MAGIC ISC_MAGIC('X', 'f', 'r', 'I')
@@ -565,6 +568,13 @@ redo:
xfr->ixfr.request_serial, xfr->end_serial);
FAIL(DNS_R_UPTODATE);
}
xfr->firstsoa = *rdata;
if (xfr->firstsoa_data != NULL) {
isc_mem_free(xfr->mctx, xfr->firstsoa_data);
}
xfr->firstsoa_data = isc_mem_allocate(xfr->mctx, rdata->length);
memcpy(xfr->firstsoa_data, rdata->data, rdata->length);
xfr->firstsoa.data = xfr->firstsoa_data;
xfr->state = XFRST_FIRSTDATA;
break;
@@ -649,6 +659,16 @@ redo:
}
CHECK(axfr_putdata(xfr, DNS_DIFFOP_ADD, name, ttl, rdata));
if (rdata->type == dns_rdatatype_soa) {
/*
* Use dns_rdata_compare instead of memcmp to
* allow for case differences.
*/
if (dns_rdata_compare(rdata, &xfr->firstsoa) != 0) {
xfrin_log(xfr, ISC_LOG_ERROR,
"start and ending SOA records "
"mismatch");
FAIL(DNS_R_FORMERR);
}
CHECK(axfr_commit(xfr));
xfr->state = XFRST_AXFR_END;
break;
@@ -852,7 +872,8 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_nm_t *netmgr,
.id = (dns_messageid_t)isc_random16(),
.maxrecords = dns_zone_getmaxrecords(zone),
.masteraddr = *masteraddr,
.sourceaddr = *sourceaddr };
.sourceaddr = *sourceaddr,
.firstsoa = DNS_RDATA_INIT };
isc_mem_attach(mctx, &xfr->mctx);
dns_zone_iattach(zone, &xfr->zone);
@@ -1616,6 +1637,10 @@ xfrin_destroy(dns_xfrin_ctx_t *xfr) {
dns_zone_idetach(&xfr->zone);
}
if (xfr->firstsoa_data != NULL) {
isc_mem_free(xfr->mctx, xfr->firstsoa_data);
}
isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
}

View File

@@ -1000,6 +1000,7 @@
./bin/tests/system/xfer/ans5/badmessageid X 2020,2021
./bin/tests/system/xfer/ans5/goodaxfr X 2011,2018,2019,2020,2021
./bin/tests/system/xfer/ans5/partial X 2011,2018,2019,2020,2021
./bin/tests/system/xfer/ans5/soamismatch X 2021
./bin/tests/system/xfer/ans5/unknownkey X 2011,2018,2019,2020,2021
./bin/tests/system/xfer/ans5/unsigned X 2011,2018,2019,2020,2021
./bin/tests/system/xfer/ans5/wrongkey X 2011,2018,2019,2020,2021