git: 50edc6307198 - main - pfsync: Fix offset calculation

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Thu, 15 Feb 2024 12:55:01 UTC
The branch main has been updated by kp:

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

commit 50edc630719827b6c58dd515328997fd196b1d78
Author:     Kajetan Staszkiewicz <vegeta@tuxpowered.net>
AuthorDate: 2024-02-13 19:41:14 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-02-15 11:54:02 +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
---
 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 c57a89ea052a..e90bc60b85fa 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