From: Ondřej Surý Date: Mon, 22 Jun 2026 11:29:58 +0000 (+0200) Subject: Fail the fetch when a response fails the TSIG signature check X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2327277f90c720d8136a3982646fb14d79a9149d;p=thirdparty%2Fbind9.git Fail the fetch when a response fails the TSIG signature check A response that failed the signature check with a missing or unexpected TSIG used to set nextitem, so the resolver kept reading the dispatch for another response. When the response was truncated with the TSIG cut off the end of the wire, no further response ever arrived and the fetch stalled until resolver-query-timeout. Treat an unauthenticated response like every other signature-check failure and finish the fetch immediately. A response carrying a missing or bogus TSIG now yields SERVFAIL instead of being skipped in favour of a later one; the cookie system test that fed a spoofed TSIG response is updated to expect that. The unauthenticated data is still never returned. --- diff --git a/bin/tests/system/cookie/tests.sh b/bin/tests/system/cookie/tests.sh index 36ba4940300..dafa315972d 100755 --- a/bin/tests/system/cookie/tests.sh +++ b/bin/tests/system/cookie/tests.sh @@ -484,7 +484,7 @@ if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) n=$((n + 1)) -echo_i "check that spoofed response with a TSIG is dropped when we have a server cookie ($n)" +echo_i "check that a spoofed response with a TSIG is rejected when we have a server cookie ($n)" ret=0 pat='10\.53\.0\.9 .*\[cookie=................................\] \[ttl' # prime EDNS COOKIE state @@ -492,15 +492,13 @@ $DIG $DIGOPTS @10.53.0.1 tld >dig.out.test$n.1 || ret=1 grep "status: NOERROR" dig.out.test$n.1 >/dev/null || ret=1 rndc_dumpdb ns1 grep "$pat" ns1/named_dump.db.test$n >/dev/null || ret=1 -# spoofed response contains 10.53.0.10 +# The spoofed response carries a bogus TSIG and contains 10.53.0.10. It cannot +# be authenticated, so the resolver rejects it with SERVFAIL and never returns +# the spoofed address. nextpart ns1/named.run >/dev/null $DIG $DIGOPTS @10.53.0.1 withtsig.tld >dig.out.test$n.2 || ret=1 -grep "status: NOERROR" dig.out.test$n.2 >/dev/null || ret=1 -grep 'A.10\.53\.0\.9' dig.out.test$n.2 >/dev/null || ret=1 +grep "status: SERVFAIL" dig.out.test$n.2 >/dev/null || ret=1 grep 'A.10\.53\.0\.10' dig.out.test$n.2 >/dev/null && ret=1 -nextpart ns1/named.run >named.run.test$n -count=$(grep -c ') [0-9][0-9]* NOERROR 0' named.run.test$n) -test $count -eq 1 || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index d61bd76f679..183712a3e64 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -7879,11 +7879,6 @@ resquery_response_continue(void *arg, isc_result_t result) { if (result != ISC_R_SUCCESS) { FCTXTRACE3("signature check failed", result); - if (result == DNS_R_UNEXPECTEDTSIG || - result == DNS_R_EXPECTEDTSIG) - { - rctx->nextitem = true; - } rctx_done(rctx, result); goto cleanup; }