git: be2c6fba9d83 - stable/14 - pfsync: Fix offset calculation

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Sat, 24 Feb 2024 18:48:49 UTC
The branch stable/14 has been updated by kp:

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

commit be2c6fba9d8314f9f8f4d4acc1c35e7a6a84b080
Author:     Kajetan Staszkiewicz <vegeta@tuxpowered.net>
AuthorDate: 2024-02-13 19:41:14 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-02-24 18:47:13 +0000

    pfsync: Fix offset calculation
    
    Even though message version is automatically recognized and the top of
    the struct is identical for different versions, when iterating over
    multiple messages proper message length must be used. That's the length
    of an union member for given version, not of the union itself.
    
    Reviewed by:    kp
    Differential Revision:  https://reviews.freebsd.org/D43862
    
    (cherry picked from commit 50edc630719827b6c58dd515328997fd196b1d78)
---
 sys/netpfil/pf/if_pfsync.c | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c
index 75c361b394e0..41eab7be515d 100644
--- a/sys/netpfil/pf/if_pfsync.c
+++ b/sys/netpfil/pf/if_pfsync.c
@@ -1002,15 +1002,17 @@ pfsync_in_ins(struct mbuf *m, int offset, int count, int flags, int action)
 {
 	struct mbuf *mp;
 	union pfsync_state_union *sa, *sp;
-	int i, offp, len, msg_version;
+	int i, offp, total_len, msg_version, msg_len;
 
 	switch (action) {
 		case PFSYNC_ACT_INS_1301:
-			len = sizeof(struct pfsync_state_1301) * count;
+			msg_len = sizeof(struct pfsync_state_1301);
+			total_len = msg_len * count;
 			msg_version = PFSYNC_MSG_VERSION_1301;
 			break;
 		case PFSYNC_ACT_INS_1400:
-			len = sizeof(struct pfsync_state_1400) * count;
+			msg_len = sizeof(struct pfsync_state_1400);
+			total_len = msg_len * count;
 			msg_version = PFSYNC_MSG_VERSION_1400;
 			break;
 		default:
@@ -1018,7 +1020,7 @@ pfsync_in_ins(struct mbuf *m, int offset, int count, int flags, int action)
 			return (-1);
 	}
 
-	mp = m_pulldown(m, offset, len, &offp);
+	mp = m_pulldown(m, offset, total_len, &offp);
 	if (mp == NULL) {
 		V_pfsyncstats.pfsyncs_badlen++;
 		return (-1);
@@ -1026,7 +1028,7 @@ pfsync_in_ins(struct mbuf *m, int offset, int count, int flags, int action)
 	sa = (union pfsync_state_union *)(mp->m_data + offp);
 
 	for (i = 0; i < count; i++) {
-		sp = &sa[i];
+		sp = (union pfsync_state_union *)((char *)sa + msg_len * i);
 
 		/* Check for invalid values. */
 		if (sp->pfs_1301.timeout >= PFTM_MAX ||
@@ -1046,7 +1048,7 @@ pfsync_in_ins(struct mbuf *m, int offset, int count, int flags, int action)
 			break;
 	}
 
-	return (len);
+	return (total_len);
 }
 
 static int
@@ -1127,15 +1129,17 @@ pfsync_in_upd(struct mbuf *m, int offset, int count, int flags, int action)
 	union pfsync_state_union *sa, *sp;
 	struct pf_kstate *st;
 	struct mbuf *mp;
-	int sync, offp, i, len, msg_version;
+	int sync, offp, i, total_len, msg_len, msg_version;
 
 	switch (action) {
 		case PFSYNC_ACT_UPD_1301:
-			len = sizeof(struct pfsync_state_1301) * count;
+			msg_len = sizeof(struct pfsync_state_1301);
+			total_len = msg_len * count;
 			msg_version = PFSYNC_MSG_VERSION_1301;
 			break;
 		case PFSYNC_ACT_UPD_1400:
-			len = sizeof(struct pfsync_state_1400) * count;
+			msg_len = sizeof(struct pfsync_state_1400);
+			total_len = msg_len * count;
 			msg_version = PFSYNC_MSG_VERSION_1400;
 			break;
 		default:
@@ -1143,7 +1147,7 @@ pfsync_in_upd(struct mbuf *m, int offset, int count, int flags, int action)
 			return (-1);
 	}
 
-	mp = m_pulldown(m, offset, len, &offp);
+	mp = m_pulldown(m, offset, total_len, &offp);
 	if (mp == NULL) {
 		V_pfsyncstats.pfsyncs_badlen++;
 		return (-1);
@@ -1151,7 +1155,7 @@ pfsync_in_upd(struct mbuf *m, int offset, int count, int flags, int action)
 	sa = (union pfsync_state_union *)(mp->m_data + offp);
 
 	for (i = 0; i < count; i++) {
-		sp = &sa[i];
+		sp = (union pfsync_state_union *)((char *)sa + msg_len * i);
 
 		/* check for invalid values */
 		if (sp->pfs_1301.timeout >= PFTM_MAX ||
@@ -1214,7 +1218,7 @@ pfsync_in_upd(struct mbuf *m, int offset, int count, int flags, int action)
 		PF_STATE_UNLOCK(st);
 	}
 
-	return (len);
+	return (total_len);
 }
 
 static int