]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fail the fetch when a response fails the TSIG signature check 12080/head
authorOndřej Surý <ondrej@isc.org>
Mon, 22 Jun 2026 11:29:58 +0000 (13:29 +0200)
committerOndřej Surý <ondrej@isc.org>
Wed, 24 Jun 2026 10:18:19 +0000 (12:18 +0200)
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.

bin/tests/system/cookie/tests.sh
lib/dns/resolver.c

index 36ba494030049fec21abce393ed0e936d0f6e0fb..dafa315972d5735ae01ccdbadd5b10a23f062236 100755 (executable)
@@ -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))
 
index d61bd76f6795354b398364732ba02d5ecb2d43fb..183712a3e64d24349a828a0666dce602be2834c8 100644 (file)
@@ -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;
        }