git: b27a0b8bfb15 - stable/15 - pf: Free a table entry that cannot be routed

From: R. Christian McDonald <rcm_at_FreeBSD.org>
Date: Wed, 28 Oct 2026 20:35:57 UTC
The branch stable/15 has been updated by rcm:

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

commit b27a0b8bfb151543c42b5d899327bf7168dc5f37
Author:     R. Christian McDonald <rcm@FreeBSD.org>
AuthorDate: 2026-10-13 15:53:00 +0000
Commit:     R. Christian McDonald <rcm@FreeBSD.org>
CommitDate: 2026-10-28 20:34:14 +0000

    pf: Free a table entry that cannot be routed
    
    pfr_insert_kentry() returned the error of pfr_route_kentry() and
    leaked the entry it had created; pfr_insert_kentries() stopped at the
    first entry it could not route and leaked it and the rest of the work
    queue, which no caller frees.  Destroy an entry that cannot be routed
    and go on with the next.
    
    Reviewed by:            kp
    MFC after:              2 weeks
    Sponsored by:           Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D60532
    
    (cherry picked from commit 989d72fd3d35daa6a056afdd0c6b0aba4c5d8ccf)
---
 sys/netpfil/pf/pf_table.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/sys/netpfil/pf/pf_table.c b/sys/netpfil/pf/pf_table.c
index 1785e8a78d31..85820a65f290 100644
--- a/sys/netpfil/pf/pf_table.c
+++ b/sys/netpfil/pf/pf_table.c
@@ -846,15 +846,16 @@ static void
 pfr_insert_kentries(struct pfr_ktable *kt,
     struct pfr_kentryworkq *workq, time_t tzero)
 {
-	struct pfr_kentry	*p;
+	struct pfr_kentry	*p, *q;
 	int			 rv, n = 0;
 
-	SLIST_FOREACH(p, workq, pfrke_workq) {
+	SLIST_FOREACH_SAFE(p, workq, pfrke_workq, q) {
 		rv = pfr_route_kentry(kt, p);
 		if (rv) {
 			printf("pfr_insert_kentries: cannot route entry "
 			    "(code=%d).\n", rv);
-			break;
+			pfr_destroy_kentry(p);
+			continue;
 		}
 		p->pfrke_counters.pfrkc_tzero = tzero;
 		n++;
@@ -876,8 +877,10 @@ pfr_insert_kentry(struct pfr_ktable *kt, struct pfr_addr *ad, time_t tzero)
 		return (ENOMEM);
 
 	rv = pfr_route_kentry(kt, p);
-	if (rv)
+	if (rv) {
+		pfr_destroy_kentry(p);
 		return (rv);
+	}
 
 	p->pfrke_counters.pfrkc_tzero = tzero;
 	kt->pfrkt_cnt++;