Fix stack Use-After-Return in SIG(0) handling

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.
This commit is contained in:
Ondřej Surý 2026-02-20 09:46:32 +01:00 committed by Michał Kępień
parent 613a93478b
commit b4b81deed9
No known key found for this signature in database

View 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,