git: 16a9f31b8aae - main - pf: Don't access sk and nk before they are allocated

From: Kajetan Staszkiewicz <ks_at_FreeBSD.org>
Date: Sat, 12 Jul 2025 14:31:41 UTC
The branch main has been updated by ks:

URL: https://cgit.FreeBSD.org/src/commit/?id=16a9f31b8aae6cc16baf283183470fc17c9b488e

commit 16a9f31b8aae6cc16baf283183470fc17c9b488e
Author:     Kajetan Staszkiewicz <ks@FreeBSD.org>
AuthorDate: 2025-06-03 14:10:52 +0000
Commit:     Kajetan Staszkiewicz <ks@FreeBSD.org>
CommitDate: 2025-07-12 14:27:46 +0000

    pf: Don't access sk and nk before they are allocated
    
    The NAT addresses are chosen during ruleset parsing. The new afto code stores
    post-nat addresses in nsaddr. The old nat code (also used for new nat-to rules)
    creates state keys and stores addresses in them.
    
    Ensure proper way of accessing the NAT addresses in case sticky-address
    is used for af-to rules.
    
    Reviewed by:    kp
    Approved by:    kp
    Sponsored by:   InnoGames GmbH
    Differential Revision:  https://reviews.freebsd.org/D50768
---
 sys/netpfil/pf/pf.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 41658a29014e..acdeebb85e30 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -6054,9 +6054,16 @@ pf_create_state(struct pf_krule *r, struct pf_test_ctx *ctx,
 	/* src node for translation rule */
 	if (ctx->nr != NULL) {
 		KASSERT(ctx->nat_pool != NULL, ("%s: nat_pool is NULL", __func__));
+		/*
+		 * The NAT addresses are chosen during ruleset parsing.
+		 * The new afto code stores post-nat addresses in nsaddr.
+		 * The old nat code (also used for new nat-to rules) creates
+		 * state keys and stores addresses in them.
+		 */
 		if ((ctx->nat_pool->opts & PF_POOL_STICKYADDR) &&
 		    (sn_reason = pf_insert_src_node(sns, snhs, ctx->nr,
-		    &ctx->sk->addr[pd->sidx], pd->af, &ctx->nk->addr[1], NULL,
+		    ctx->sk ? &(ctx->sk->addr[pd->sidx]) : pd->src, pd->af,
+		    ctx->nk ? &(ctx->nk->addr[1]) : &(pd->nsaddr), NULL,
 		    PF_SN_NAT)) != 0 ) {
 			REASON_SET(&ctx->reason, sn_reason);
 			goto csfailed;