Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 2 Oct 2025 19:19:53 GMT
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: dd2fc08d8543 - main - pf: fix possibe SCTP panic
Message-ID:  <202510021919.592JJrfv098810@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kp:

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

commit dd2fc08d85431e10ad60e01e97b98e9dc23322bd
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-10-02 14:48:22 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-10-02 19:17:00 +0000

    pf: fix possibe SCTP panic
    
    While processing SCTP packets we can enqueue work for later, in the
    sctp_multihome_jobs queue. This deferred job includes a copy of the current
    struct pf_pdesc, which must contain a valid pcksum pointer (in case of NAT).
    
    However, jobs could be enqueued before we'd actually set this pointer in
    pf_setup_pdesc(). Set this pointer before we scan the SCTP chunk headers (and
    could enqueue deferred jobs.)
    
    While here sprinkle in a few more assertions to ensure we got this right.
    
    Reported-by: syzbot+974d0fb7e53c9aa31b90@syzkaller.appspotmail.com
    MFC after:      3 days
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sys/netpfil/pf/pf.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 2c6d62078e6a..25ae1193bfff 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -3364,7 +3364,7 @@ pf_change_ap(struct pf_pdesc *pd, struct pf_addr *a, u_int16_t *p,
 	u_int16_t	po;
 	uint8_t		u = pd->virtual_proto == IPPROTO_UDP;
 
-	MPASS(pd->pcksum);
+	MPASS(pd->pcksum != NULL);
 	if (pd->af == AF_INET) {
 		MPASS(pd->ip_sum);
 	}
@@ -7634,6 +7634,7 @@ again:
 				nj->pd.m = j->pd.m;
 				nj->op = j->op;
 
+				MPASS(nj->pd.pcksum);
 				TAILQ_INSERT_TAIL(&pd->sctp_multihome_jobs, nj, next);
 			}
 			PF_SCTP_ENDPOINTS_UNLOCK();
@@ -7753,6 +7754,7 @@ pf_multihome_scan(int start, int len, struct pf_pdesc *pd, int op)
 			job->pd.m = pd->m;
 			job->op = op;
 
+			MPASS(job->pd.pcksum);
 			TAILQ_INSERT_TAIL(&pd->sctp_multihome_jobs, job, next);
 			break;
 		}
@@ -7786,6 +7788,7 @@ pf_multihome_scan(int start, int len, struct pf_pdesc *pd, int op)
 			job->pd.m = pd->m;
 			job->op = op;
 
+			MPASS(job->pd.pcksum);
 			TAILQ_INSERT_TAIL(&pd->sctp_multihome_jobs, job, next);
 			break;
 		}
@@ -10634,17 +10637,21 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
 			REASON_SET(reason, PFRES_SHORT);
 			return (-1);
 		}
-		if (pf_scan_sctp(pd) != PF_PASS) {
-			*action = PF_DROP;
-			REASON_SET(reason, PFRES_SHORT);
-			return (-1);
-		}
+
 		/*
 		 * Placeholder. The SCTP checksum is 32-bits, but
 		 * pf_test_state() expects to update a 16-bit checksum.
 		 * Provide a dummy value which we'll subsequently ignore.
+		 * Do this before pf_scan_sctp() so any jobs we enqueue
+		 * have a pcksum set.
 		 */
 		pd->pcksum = &pd->sctp_dummy_sum;
+
+		if (pf_scan_sctp(pd) != PF_PASS) {
+			*action = PF_DROP;
+			REASON_SET(reason, PFRES_SHORT);
+			return (-1);
+		}
 		break;
 	}
 	case IPPROTO_ICMP: {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202510021919.592JJrfv098810>