git: f5c0005567b4 - stable/14 - pfsync: fix use of invalidated stack variable

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Mon, 01 Apr 2024 07:34:37 UTC
The branch stable/14 has been updated by kp:

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

commit f5c0005567b4f029297ffc5b5c7c2925b2608ba1
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2024-03-24 08:46:31 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-04-01 07:33:32 +0000

    pfsync: fix use of invalidated stack variable
    
    Calls to pfsync_send_plus() pass pointers to stack variables.
    If pfsync_sendout() then fails it retains the pointer to these stack
    variables, accesing them later.
    
    Allocate a buffer and copy the data instead, so that we can retain the
    pointer safely.
    
    Reported by:    CI KASAN, markj
    MFC after:      1 week
    
    (cherry picked from commit 81debbd60e5773e812e9227a2003ea88699580be)
---
 sys/netpfil/pf/if_pfsync.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c
index 41eab7be515d..5df5824c93b8 100644
--- a/sys/netpfil/pf/if_pfsync.c
+++ b/sys/netpfil/pf/if_pfsync.c
@@ -474,6 +474,9 @@ pfsync_clone_destroy(struct ifnet *ifp)
 		MPASS(TAILQ_EMPTY(&b->b_deferrals));
 		PFSYNC_BUCKET_UNLOCK(b);
 
+		free(b->b_plus, M_PFSYNC);
+		b->b_plus = NULL;
+
 		callout_drain(&b->b_tmo);
 	}
 
@@ -1766,6 +1769,7 @@ pfsync_drop(struct pfsync_softc *sc)
 		}
 
 		b->b_len = PFSYNC_MINPKT;
+		free(b->b_plus, M_PFSYNC);
 		b->b_plus = NULL;
 	}
 }
@@ -1906,6 +1910,7 @@ pfsync_sendout(int schedswi, int c)
 		bcopy(b->b_plus, m->m_data + offset, b->b_pluslen);
 		offset += b->b_pluslen;
 
+		free(b->b_plus, M_PFSYNC);
 		b->b_plus = NULL;
 	}
 
@@ -2563,13 +2568,21 @@ pfsync_send_plus(void *plus, size_t pluslen)
 
 	PFSYNC_BUCKET_LOCK(b);
 
+	MPASS(b->b_plus == NULL);
+
 	if (b->b_len + pluslen > sc->sc_ifp->if_mtu)
 		pfsync_sendout(1, b->b_id);
 
-	b->b_plus = plus;
+	b->b_plus = malloc(pluslen, M_PFSYNC, M_NOWAIT);
+	if (b->b_plus == NULL)
+		goto out;
+
+	memcpy(b->b_plus, plus, pluslen);
 	b->b_len += (b->b_pluslen = pluslen);
 
 	pfsync_sendout(1, b->b_id);
+
+out:
 	PFSYNC_BUCKET_UNLOCK(b);
 }