2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-22 10:10:06 +00:00

4321. [bug] Zones using mapped files containing out-of-zone data

could return SERVFAIL instead of the expected NODATA
                        or NXDOMAIN results. [RT #41596]
This commit is contained in:
Mark Andrews 2016-02-24 11:13:24 +11:00
parent 62735fcde3
commit f9da4a8e54
9 changed files with 140 additions and 33 deletions

View File

@ -1,3 +1,7 @@
4321. [bug] Zones using mapped files containing out-of-zone data
could return SERVFAIL instead of the expected NODATA
or NXDOMAIN results. [RT #41596]
4320. [bug] Insufficient memory allocation when handling 4320. [bug] Insufficient memory allocation when handling
"none" ACL could cause an assertion failure in "none" ACL could cause an assertion failure in
named when parsing ACL configuration. [RT #41745] named when parsing ACL configuration. [RT #41745]

View File

@ -40,3 +40,6 @@ rm -f */named.memstats
rm -f */named.run rm -f */named.run
rm -f */ans.run rm -f */ans.run
rm -f ns*/named.lock rm -f ns*/named.lock
rm -f ns2/mapped.db
rm -f ns3/mapped.bk
rm -f dig.out.?.*

View File

@ -0,0 +1,26 @@
; <<>> DiG 9.10.2-P3 <<>> -p 5300 axfr mapped @10.53.0.3
;; global options: +cmd
mapped. 3600 IN SOA . . 0 0 0 2147483647 0
example.aa. 3600 IN A 1.2.3.4
example1.aa. 3600 IN A 1.2.3.4
example.bb. 3600 IN A 1.2.3.4
example1.bb. 3600 IN A 1.2.3.4
example.com. 3600 IN A 1.2.3.4
example1.com. 3600 IN A 1.2.3.4
bar.dd. 3600 IN A 1.2.3.4
foo.ee. 3600 IN A 1.2.3.4
foo.ff. 3600 IN A 1.2.3.4
foo.gg. 3600 IN A 1.2.3.4
foo.hh. 3600 IN A 1.2.3.4
foo.ii. 3600 IN A 1.2.3.4
foo.jj. 3600 IN A 1.2.3.4
foo.kk. 3600 IN A 1.2.3.4
foo.ll. 3600 IN A 1.2.3.4
mapped. 3600 IN NS .
mapped. 3600 IN SOA . . 0 0 0 2147483647 0
;; Query time: 4 msec
;; SERVER: 10.53.0.3#5300(10.53.0.3)
;; WHEN: Tue Feb 16 14:38:25 EST 2016
;; XFR size: 18 records (messages 1, bytes 468)

View File

@ -0,0 +1,17 @@
mapped. 3600 IN SOA . . 0 0 0 2147483647 0
example.aa. 3600 IN A 1.2.3.4
example1.aa. 3600 IN A 1.2.3.4
example.bb. 3600 IN A 1.2.3.4
example1.bb. 3600 IN A 1.2.3.4
example.com. 3600 IN A 1.2.3.4
example1.com. 3600 IN A 1.2.3.4
bar.dd. 3600 IN A 1.2.3.4
foo.ee. 3600 IN A 1.2.3.4
foo.ff. 3600 IN A 1.2.3.4
foo.gg. 3600 IN A 1.2.3.4
foo.hh. 3600 IN A 1.2.3.4
foo.ii. 3600 IN A 1.2.3.4
foo.jj. 3600 IN A 1.2.3.4
foo.kk. 3600 IN A 1.2.3.4
foo.ll. 3600 IN A 1.2.3.4
mapped. 3600 IN NS .

View File

@ -66,3 +66,10 @@ zone "slave" {
masters { 10.53.0.1; }; masters { 10.53.0.1; };
masterfile-format text; masterfile-format text;
}; };
zone "mapped" {
type slave;
file "mapped.db";
masterfile-format text;
masters { 10.53.0.100; };
};

View File

@ -74,4 +74,9 @@ zone "tsigzone" {
allow-transfer { key tsigzone.; }; allow-transfer { key tsigzone.; };
}; };
zone "mapped" {
type slave;
masters { 10.53.0.2; };
masterfile-format map;
file "mapped.bk";
};

View File

@ -35,5 +35,7 @@ cp -f ns4/named.conf.base ns4/named.conf
cp ns2/slave.db.in ns2/slave.db cp ns2/slave.db.in ns2/slave.db
touch -t 200101010000 ns2/slave.db touch -t 200101010000 ns2/slave.db
cp ns2/mapped.db.in ns2/mapped.db
$PERL -e 'for ($i=0;$i<4096;$i++){ printf("name%u 259200 A 1.2.3.4\nname%u 259200 TXT \"Hello World %u\"\n", $i, $i, $i);}' > ns8/small.db $PERL -e 'for ($i=0;$i<4096;$i++){ printf("name%u 259200 A 1.2.3.4\nname%u 259200 TXT \"Hello World %u\"\n", $i, $i, $i);}' > ns8/small.db
$PERL -e 'printf("large IN TYPE45234 \\# 48000 "); for ($i=0;$i<16*3000;$i++) { printf("%02x", $i % 256); } printf("\n");' > ns8/large.db $PERL -e 'printf("large IN TYPE45234 \\# 48000 "); for ($i=0;$i<16*3000;$i++) { printf("%02x", $i % 256); } printf("\n");' > ns8/large.db

View File

@ -23,7 +23,9 @@ SYSTEMTESTTOP=..
DIGOPTS="+tcp +noadd +nosea +nostat +noquest +nocomm +nocmd" DIGOPTS="+tcp +noadd +nosea +nostat +noquest +nocomm +nocmd"
status=0 status=0
n=0
n=`expr $n + 1`
echo "I:testing basic zone transfer functionality" echo "I:testing basic zone transfer functionality"
$DIG $DIGOPTS example. \ $DIG $DIGOPTS example. \
@10.53.0.2 axfr -p 5300 > dig.out.ns2 || status=1 @10.53.0.2 axfr -p 5300 > dig.out.ns2 || status=1
@ -49,6 +51,7 @@ $PERL ../digcomp.pl dig1.good dig.out.ns2 || status=1
$PERL ../digcomp.pl dig1.good dig.out.ns3 || status=1 $PERL ../digcomp.pl dig1.good dig.out.ns3 || status=1
n=`expr $n + 1`
echo "I:testing TSIG signed zone transfers" echo "I:testing TSIG signed zone transfers"
$DIG $DIGOPTS tsigzone. \ $DIG $DIGOPTS tsigzone. \
@10.53.0.2 axfr -y tsigzone.:1234abcd8765 -p 5300 \ @10.53.0.2 axfr -y tsigzone.:1234abcd8765 -p 5300 \
@ -124,6 +127,7 @@ grep "1397051952 ; serial" ns2/slave.db > /dev/null 2>&1 || tmp=1
if test $tmp != 0 ; then echo "I:failed"; fi if test $tmp != 0 ; then echo "I:failed"; fi
status=`expr $status + $tmp` status=`expr $status + $tmp`
n=`expr $n + 1`
echo "I:testing ixfr-from-differences yes;" echo "I:testing ixfr-from-differences yes;"
tmp=0 tmp=0
for i in 0 1 2 3 4 5 6 7 8 9 for i in 0 1 2 3 4 5 6 7 8 9
@ -146,6 +150,7 @@ test -f ns3/example.bk.jnl || tmp=1
if test $tmp != 0 ; then echo "I:failed"; fi if test $tmp != 0 ; then echo "I:failed"; fi
status=`expr $status + $tmp` status=`expr $status + $tmp`
n=`expr $n + 1`
echo "I:testing ixfr-from-differences master; (master zone)" echo "I:testing ixfr-from-differences master; (master zone)"
tmp=0 tmp=0
@ -166,6 +171,7 @@ test -f ns3/master.bk.jnl || tmp=1
if test $tmp != 0 ; then echo "I:failed"; fi if test $tmp != 0 ; then echo "I:failed"; fi
status=`expr $status + $tmp` status=`expr $status + $tmp`
n=`expr $n + 1`
echo "I:testing ixfr-from-differences master; (slave zone)" echo "I:testing ixfr-from-differences master; (slave zone)"
tmp=0 tmp=0
@ -186,6 +192,7 @@ test -f ns6/slave.bk.jnl && tmp=1
if test $tmp != 0 ; then echo "I:failed"; fi if test $tmp != 0 ; then echo "I:failed"; fi
status=`expr $status + $tmp` status=`expr $status + $tmp`
n=`expr $n + 1`
echo "I:testing ixfr-from-differences slave; (master zone)" echo "I:testing ixfr-from-differences slave; (master zone)"
tmp=0 tmp=0
@ -195,6 +202,8 @@ test -f ns7/master2.db.jnl && tmp=1
if test $tmp != 0 ; then echo "I:failed"; fi if test $tmp != 0 ; then echo "I:failed"; fi
status=`expr $status + $tmp` status=`expr $status + $tmp`
n=`expr $n + 1`
echo "I:testing ixfr-from-differences slave; (slave zone)" echo "I:testing ixfr-from-differences slave; (slave zone)"
tmp=0 tmp=0
@ -368,7 +377,8 @@ $DIGCMD nil. TXT | grep 'incorrect key AXFR' >/dev/null && {
status=1 status=1
} }
echo "I:check that we ask for and get a EDNS EXPIRE response" n=`expr $n + 1`
echo "I:check that we ask for and get a EDNS EXPIRE response ($n)"
# force a refresh query # force a refresh query
$RNDC -s 10.53.0.7 -p 9953 -c ../common/rndc.conf refresh edns-expire 2>&1 | sed 's/^/I:ns7 /' $RNDC -s 10.53.0.7 -p 9953 -c ../common/rndc.conf refresh edns-expire 2>&1 | sed 's/^/I:ns7 /'
sleep 10 sleep 10
@ -380,7 +390,8 @@ test ${expire:-0} -gt 0 -a ${expire:-0} -lt 1814400 || {
status=1 status=1
} }
echo "I:test smaller transfer TCP message size" n=`expr $n + 1`
echo "I:test smaller transfer TCP message size ($n)"
$DIG $DIGOPTS example. @10.53.0.8 axfr -p 5300 \ $DIG $DIGOPTS example. @10.53.0.8 axfr -p 5300 \
-y key1.:1234abcd8765 > dig.out.msgsize || status=1 -y key1.:1234abcd8765 > dig.out.msgsize || status=1
@ -396,5 +407,19 @@ if [ $num_messages -le 300 ]; then
status=1 status=1
fi fi
n=`expr $n + 1`
echo "I:test mapped zone with out of zone data ($n)"
tmp=0
$DIG -p 5300 txt mapped @10.53.0.3 > dig.out.1.$n
grep "status: NOERROR," dig.out.1.$n > /dev/null || tmp=1
$PERL $SYSTEMTESTTOP/stop.pl . ns3
$PERL $SYSTEMTESTTOP/start.pl --noclean --restart . ns3
$DIG -p 5300 txt mapped @10.53.0.3 > dig.out.2.$n
grep "status: NOERROR," dig.out.2.$n > /dev/null || tmp=1
$DIG -p 5300 axfr mapped @10.53.0.3 > dig.out.3.$n
$PERL ../digcomp.pl knowngood.mapped dig.out.3.$n || tmp=1
if test $tmp != 0 ; then echo "I:failed"; fi
status=`expr $status + $tmp`
echo "I:exit status: $status" echo "I:exit status: $status"
exit $status exit $status

View File

@ -7282,8 +7282,9 @@ deserialize32(void *arg, FILE *f, off_t offset) {
int fd; int fd;
off_t filesize = 0; off_t filesize = 0;
char *base; char *base;
dns_rbt_t *temporary_rbt = NULL; dns_rbt_t *tree = NULL, *nsec = NULL, *nsec3 = NULL;
int protect, flags; int protect, flags;
dns_rbtnode_t *origin_node = NULL;
REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(VALID_RBTDB(rbtdb));
@ -7308,28 +7309,21 @@ deserialize32(void *arg, FILE *f, off_t offset) {
header = (rbtdb_file_header_t *)(base + offset); header = (rbtdb_file_header_t *)(base + offset);
rbtdb->mmap_location = base;
rbtdb->mmap_size = (size_t) filesize;
rbtdb->origin_node = NULL;
if (header->tree != 0) { if (header->tree != 0) {
result = dns_rbt_deserialize_tree(base, filesize, result = dns_rbt_deserialize_tree(base, filesize,
(off_t) header->tree, (off_t) header->tree,
rbtdb->common.mctx, rbtdb->common.mctx,
delete_callback, rbtdb, delete_callback, rbtdb,
rbt_datafixer, rbtdb, rbt_datafixer, rbtdb,
&rbtdb->origin_node, NULL, &tree);
&temporary_rbt);
if (temporary_rbt != NULL) {
dns_rbt_destroy(&rbtdb->tree);
rbtdb->tree = temporary_rbt;
temporary_rbt = NULL;
rbtdb->origin_node =
(dns_rbtnode_t *)(header->tree + base + 1024);
}
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (result); goto cleanup;
result = dns_rbt_findnode(tree, &rbtdb->common.origin, NULL,
&origin_node, NULL,
DNS_RBTFIND_EMPTYDATA, NULL, NULL);
if (result != ISC_R_SUCCESS)
goto cleanup;
} }
if (header->nsec != 0) { if (header->nsec != 0) {
@ -7338,14 +7332,9 @@ deserialize32(void *arg, FILE *f, off_t offset) {
rbtdb->common.mctx, rbtdb->common.mctx,
delete_callback, rbtdb, delete_callback, rbtdb,
rbt_datafixer, rbtdb, rbt_datafixer, rbtdb,
NULL, &temporary_rbt); NULL, &nsec);
if (temporary_rbt != NULL) {
dns_rbt_destroy(&rbtdb->nsec);
rbtdb->nsec = temporary_rbt;
temporary_rbt = NULL;
}
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (result); goto cleanup;
} }
if (header->nsec3 != 0) { if (header->nsec3 != 0) {
@ -7354,17 +7343,46 @@ deserialize32(void *arg, FILE *f, off_t offset) {
rbtdb->common.mctx, rbtdb->common.mctx,
delete_callback, rbtdb, delete_callback, rbtdb,
rbt_datafixer, rbtdb, rbt_datafixer, rbtdb,
NULL, &temporary_rbt); NULL, &nsec3);
if (temporary_rbt != NULL) {
dns_rbt_destroy(&rbtdb->nsec3);
rbtdb->nsec3 = temporary_rbt;
temporary_rbt = NULL;
}
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (result); goto cleanup;
}
/*
* We have a successfully loaded all the rbt trees now update
* rbtdb to use them.
*/
rbtdb->mmap_location = base;
rbtdb->mmap_size = (size_t) filesize;
if (tree != NULL) {
dns_rbt_destroy(&rbtdb->tree);
rbtdb->tree = tree;
rbtdb->origin_node = origin_node;
}
if (nsec != NULL) {
dns_rbt_destroy(&rbtdb->nsec);
rbtdb->nsec = nsec;
}
if (nsec3 != NULL) {
dns_rbt_destroy(&rbtdb->nsec3);
rbtdb->nsec3 = nsec3;
} }
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
cleanup:
if (tree != NULL)
dns_rbt_destroy(&tree);
if (nsec != NULL)
dns_rbt_destroy(&nsec);
if (nsec3 != NULL)
dns_rbt_destroy(&nsec3);
isc_file_munmap(base, (size_t) filesize);
return (result);
} }
static isc_result_t static isc_result_t