]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix swapped arguments in redirect2() single-label branch 11908/head
authorOndřej Surý <ondrej@isc.org>
Wed, 29 Apr 2026 17:23:19 +0000 (19:23 +0200)
committerOndřej Surý <ondrej@isc.org>
Wed, 29 Apr 2026 19:46:27 +0000 (21:46 +0200)
For a query whose qname is the root, the labels==1 branch in
redirect2() called dns_name_copy(redirectname, view->redirectzone)
with arguments reversed, overwriting the view-global
nxdomain-redirect target with the empty redirectname rather than
copying the configured target into the per-query lookup name.  After
the corruption, view->redirectzone names the root, so
dns_name_issubdomain() makes redirect2() short-circuit for every
subsequent query and the nxdomain-redirect feature stops working
until named is restarted.

Triggering this needs the resolver to receive an NXDOMAIN for the
root from upstream, which does not happen in normal DNS operation.

Swap the arguments to match the dns_name_copy(source, dest)
signature.  Add a system test that issues a root query through the
nxdomain-redirect resolver and verifies the redirect feature still
works for a normal NXDOMAIN-producing query afterwards.

Assisted-by: Claude:claude-opus-4-7
bin/tests/system/redirect/tests.sh
lib/ns/query.c

index 5d074907f39f7d7757aeffb777c9afd37513c447..007b6f73de99b391efcc6c3f432f495b2e411c28 100644 (file)
@@ -542,6 +542,16 @@ n=$((n + 1))
 if [ $ret != 0 ]; then echo_i "failed"; fi
 status=$((status + ret))
 
+echo_i "checking nxdomain-redirect survives query for root ($n)"
+ret=0
+$DIG $DIGOPTS . any @10.53.0.4 -b 10.53.0.2 >dig.out.ns4.test$n.a || ret=1
+$DIG $DIGOPTS nonexist. @10.53.0.4 -b 10.53.0.2 a >dig.out.ns4.test$n.b || ret=1
+grep "status: NOERROR" dig.out.ns4.test$n.b >/dev/null || ret=1
+grep "nonexist.        .*100.100.100.1" dig.out.ns4.test$n.b >/dev/null || ret=1
+n=$((n + 1))
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+
 echo_i "checking extended error is not set on allow-recursion ($n)"
 ret=0
 $DIG $DIGOPTS example. @10.53.0.1 -b 10.53.0.2 soa >dig.out.ns1.test$n || ret=1
index da187369c68eeb6a56655f3721afbd321c22f19d..7b1ed3a01581d091f4bbba7bcfd9fe18c628f5ca 100644 (file)
@@ -4900,7 +4900,7 @@ redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
                        return ISC_R_NOTFOUND;
                }
        } else {
-               dns_name_copy(redirectname, client->inner.view->redirectzone);
+               dns_name_copy(client->inner.view->redirectzone, redirectname);
        }
 
        result = query_getdb(client, redirectname, qtype,