Merge branch '2503-stale-answer-client-timeout-crash' into 'main'

Resolve "New stale-answer-client-timeout crashes BIND 9.16 and 9.17"

Closes #2503

See merge request isc-projects/bind9!4714
This commit is contained in:
Matthijs Mekking 2021-02-25 11:03:13 +00:00
commit 6dbdffd7b8
4 changed files with 41 additions and 2 deletions

View file

@ -1,3 +1,7 @@
5591. [bug] Fix a crash happening when "stale-answer-client-timeout"
is triggered and there is no (stale) data for it in the
cache. [GL #2503]
5590. [bug] Process NSEC3PARAM queue when loading a dynamic zone.
This will immediately create NSEC3 records for zones
that use "dnssec-policy" and "nsec3param". [GL #2498]

View file

@ -1068,11 +1068,22 @@ status=$((status+ret))
sleep 2
# Check that if we don't have stale data for a domain name, we will
# not answer anything until the resolver query timeout.
n=$((n+1))
echo_i "check notincache.example times out (max-stale-ttl default) ($n)"
ret=0
$DIG -p ${PORT} +tries=1 +timeout=3 @10.53.0.3 notfound.example TXT > dig.out.test$n 2>&1
grep "connection timed out" dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
echo_i "sending queries for tests $((n+1))-$((n+4))..."
$DIG -p ${PORT} @10.53.0.3 data.example TXT > dig.out.test$((n+1)) &
$DIG -p ${PORT} @10.53.0.3 othertype.example CAA > dig.out.test$((n+2)) &
$DIG -p ${PORT} @10.53.0.3 nodata.example TXT > dig.out.test$((n+3)) &
$DIG -p ${PORT} @10.53.0.3 nxdomain.example TXT > dig.out.test$((n+4))
$DIG -p ${PORT} @10.53.0.3 nxdomain.example TXT > dig.out.test$((n+4)) &
$DIG -p ${PORT} @10.53.0.3 notfound.example TXT > dig.out.test$((n+5))
wait
@ -1112,6 +1123,16 @@ grep "example\..*30.*IN.*SOA" dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
# The notfound.example check is different than nxdomain.example because
# we didn't send a prime query to add notfound.example to the cache.
n=$((n+1))
echo_i "check notfound.example (max-stale-ttl default) ($n)"
ret=0
grep "status: SERVFAIL" dig.out.test$n > /dev/null || ret=1
grep "ANSWER: 0," dig.out.test$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
#
# Now test server with serve-stale answers disabled.
#

View file

@ -59,3 +59,8 @@ Bug Fixes
- An invalid direction field (not one of 'N'/'S' or 'E'/'W') in a LOC record
triggered an INSIST failure. [GL #2499]
- Previously, a BIND server could experience an unexpected server termination
(crash) if the return of stale cached answers was enabled and
``stale-answer-client-timeout`` was applied to a client query in process.
This has been fixed. [GL #2503]

View file

@ -5972,6 +5972,15 @@ query_lookup(query_ctx_t *qctx) {
}
}
}
} else if (stale_only && result != ISC_R_SUCCESS) {
/*
* This is a staleonly lookup and no stale answer was found
* in cache. Treat as we don't have an answer and wait for
* the resolver fetch to finish.
*/
if ((qctx->options & DNS_GETDB_STALEFIRST) == 0) {
return (result);
}
} else {
stale_only = false;
}
@ -6017,13 +6026,13 @@ query_lookup_staleonly(ns_client_t *client) {
qctx_init(client, NULL, client->query.qtype, &qctx);
dns_db_attach(client->view->cachedb, &qctx.db);
client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK;
client->query.dboptions |= DNS_DBFIND_STALEONLY;
(void)query_lookup(&qctx);
if (qctx.node != NULL) {
dns_db_detachnode(qctx.db, &qctx.node);
}
qctx_freedata(&qctx);
client->query.dboptions &= ~DNS_DBFIND_STALEONLY;
qctx_destroy(&qctx);
}