]> 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:49:48 +0000 (13:49 +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.

(cherry picked from commit b4b81deed9930fdb59cfbf8179218621c812497b)

bin/named/server.c

index 796b4cc97ee6b08710e302e3bf8cac169fbe405c..a59ec7bb7ce506c9fb1538996a928e3c2c10b402 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;
@@ -10356,6 +10358,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);
        }
@@ -10397,10 +10401,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))
        {
@@ -10472,9 +10476,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,