]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix stack Use-After-Return in SIG(0) handling
authorOndřej Surý <ondrej@isc.org>
Fri, 20 Feb 2026 08:46:32 +0000 (09:46 +0100)
committerMichał Kępień <michal@isc.org>
Fri, 13 Mar 2026 12:47:17 +0000 (13:47 +0100)
The asynchronous SIG(0) handling improperly used srcaddr, and dstaddr
from the caller's stack and didn't attach to aclenv.  This could
possibly lead to ACL bypass as an invalid srcaddr could be matched or
possible assertion failure if the ACL environment would change between
the initial call and the SIG(0) processing due to the server
reconfiguration.  This has been fixed.

bin/named/server.c

index 25eb888e7ad9b2cd8e41dd98782b97502a6348b3..6a9a39846db9179c6f178e3080499d6948526397 100644 (file)
@@ -24,6 +24,8 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <dns/acl.h>
+
 #ifdef HAVE_DNSTAP
 #include <fstrm.h>
 #endif
@@ -280,10 +282,10 @@ struct zonelistentry {
  * asynchronously.
  */
 typedef struct matching_view_ctx {
-       isc_netaddr_t *srcaddr;
-       isc_netaddr_t *destaddr;
+       isc_netaddr_t srcaddr;
+       isc_netaddr_t destaddr;
        dns_message_t *message;
-       dns_aclenv_t *env;
+       dns_aclenv_t *aclenv;
        ns_server_t *sctx;
        isc_loop_t *loop;
        isc_job_cb cb;
@@ -9299,6 +9301,8 @@ get_matching_view_done(void *cbarg) {
 
        mvctx->cb(mvctx->cbarg);
 
+       dns_aclenv_detach(&mvctx->aclenv);
+
        if (mvctx->quota_result == ISC_R_SUCCESS) {
                isc_quota_release(&mvctx->sctx->sig0checksquota);
        }
@@ -9340,10 +9344,10 @@ get_matching_view_continue(void *cbarg, isc_result_t result) {
                tsig = dns_tsigkey_identity(mvctx->message->tsigkey);
        }
 
-       if (dns_acl_allowed(mvctx->srcaddr, tsig, mvctx->view->matchclients,
-                           mvctx->env) &&
-           dns_acl_allowed(mvctx->destaddr, tsig,
-                           mvctx->view->matchdestinations, mvctx->env) &&
+       if (dns_acl_allowed(&mvctx->srcaddr, tsig, mvctx->view->matchclients,
+                           mvctx->aclenv) &&
+           dns_acl_allowed(&mvctx->destaddr, tsig,
+                           mvctx->view->matchdestinations, mvctx->aclenv) &&
            !(mvctx->view->matchrecursiveonly &&
              (mvctx->message->flags & DNS_MESSAGEFLAG_RD) == 0))
        {
@@ -9415,9 +9419,9 @@ get_matching_view(isc_netaddr_t *srcaddr, isc_netaddr_t *destaddr,
 
        matching_view_ctx_t *mvctx = isc_mem_get(message->mctx, sizeof(*mvctx));
        *mvctx = (matching_view_ctx_t){
-               .srcaddr = srcaddr,
-               .destaddr = destaddr,
-               .env = env,
+               .srcaddr = *srcaddr,
+               .destaddr = *destaddr,
+               .aclenv = dns_aclenv_ref(env),
                .cb = cb,
                .cbarg = cbarg,
                .sigresult = sigresult,