The branch main has been updated by kp:

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

commit dd2fc08d85431e10ad60e01e97b98e9dc23322bd
Author:     Kristof Provost <[email protected]>
AuthorDate: 2025-10-02 14:48:22 +0000
Commit:     Kristof Provost <[email protected]>
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: [email protected]
    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: {

Reply via email to