aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2025-12-14 15:48:27 +0000
committerMark Johnston <markj@FreeBSD.org>2025-12-14 15:48:27 +0000
commit796abca7e281f0d4b7f72f48da4f941e1c8b139c (patch)
tree1bf9d9e3d0806d35af8772a39f235186cfd8d251
parentc694122f3cfb7d52b882fa79086d49f45a2c7fd2 (diff)
pfsync: Avoid zeroing the state export union
pfsync_state_export() takes a pointer to a union that is in reality a pointer to one of the three state formats (1301, 1400, 1500), and zeros the union. The three formats do not have the same size, so zeroing is wrong when the format isn't that which has the largest size. Refactor a bit so that the zeroing happens at the layer where we know which format we're dealing with. Reported by: CHERI Reviewed by: kp MFC after: 1 week Sponsored by: CHERI Research Centre (EPSRC grant UKRI3001) Differential Revision: https://reviews.freebsd.org/D54163
-rw-r--r--sys/net/pfvar.h8
-rw-r--r--sys/netpfil/pf/if_pfsync.c15
-rw-r--r--sys/netpfil/pf/pf_ioctl.c33
3 files changed, 42 insertions, 14 deletions
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 90e926ef3cb1..daaa2d3cddf7 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1341,8 +1341,12 @@ VNET_DECLARE(pflow_export_state_t *, pflow_export_state_ptr);
#define V_pflow_export_state_ptr VNET(pflow_export_state_ptr)
extern pfsync_detach_ifnet_t *pfsync_detach_ifnet_ptr;
-void pfsync_state_export(union pfsync_state_union *,
- struct pf_kstate *, int);
+void pfsync_state_export_1301(struct pfsync_state_1301 *,
+ struct pf_kstate *);
+void pfsync_state_export_1400(struct pfsync_state_1400 *,
+ struct pf_kstate *);
+void pfsync_state_export_1500(struct pfsync_state_1500 *,
+ struct pf_kstate *);
void pf_state_export(struct pf_state_export *,
struct pf_kstate *);
diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c
index b571734b4250..3edf08aefeb5 100644
--- a/sys/netpfil/pf/if_pfsync.c
+++ b/sys/netpfil/pf/if_pfsync.c
@@ -1900,25 +1900,28 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
static void
pfsync_out_state_1301(struct pf_kstate *st, void *buf)
{
- union pfsync_state_union *sp = buf;
+ struct pfsync_state_1301 *sp;
- pfsync_state_export(sp, st, PFSYNC_MSG_VERSION_1301);
+ sp = buf;
+ pfsync_state_export_1301(sp, st);
}
static void
pfsync_out_state_1400(struct pf_kstate *st, void *buf)
{
- union pfsync_state_union *sp = buf;
+ struct pfsync_state_1400 *sp;
- pfsync_state_export(sp, st, PFSYNC_MSG_VERSION_1400);
+ sp = buf;
+ pfsync_state_export_1400(sp, st);
}
static void
pfsync_out_state_1500(struct pf_kstate *st, void *buf)
{
- union pfsync_state_union *sp = buf;
+ struct pfsync_state_1500 *sp;
- pfsync_state_export(sp, st, PFSYNC_MSG_VERSION_1500);
+ sp = buf;
+ pfsync_state_export_1500(sp, st);
}
static void
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index 6774aaac2ecd..9856842c72b2 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -4118,8 +4118,7 @@ DIOCCHANGERULE_error:
goto fail;
}
- pfsync_state_export((union pfsync_state_union*)&ps->state,
- s, PFSYNC_MSG_VERSION_1301);
+ pfsync_state_export_1301(&ps->state, s);
PF_STATE_UNLOCK(s);
break;
}
@@ -4185,8 +4184,7 @@ DIOCGETSTATES_retry:
if (s->timeout == PFTM_UNLINKED)
continue;
- pfsync_state_export((union pfsync_state_union*)p,
- s, PFSYNC_MSG_VERSION_1301);
+ pfsync_state_export_1301(p, s);
p++;
nr++;
}
@@ -5795,11 +5793,10 @@ fail:
return (error);
}
-void
+static void
pfsync_state_export(union pfsync_state_union *sp, struct pf_kstate *st, int msg_version)
{
const char *tagname;
- bzero(sp, sizeof(union pfsync_state_union));
/* copy from state key */
sp->pfs_1301.key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
@@ -5933,6 +5930,30 @@ pfsync_state_export(union pfsync_state_union *sp, struct pf_kstate *st, int msg_
}
void
+pfsync_state_export_1301(struct pfsync_state_1301 *sp, struct pf_kstate *st)
+{
+ bzero(sp, sizeof(*sp));
+ pfsync_state_export((union pfsync_state_union *)sp, st,
+ PFSYNC_MSG_VERSION_1301);
+}
+
+void
+pfsync_state_export_1400(struct pfsync_state_1400 *sp, struct pf_kstate *st)
+{
+ bzero(sp, sizeof(*sp));
+ pfsync_state_export((union pfsync_state_union *)sp, st,
+ PFSYNC_MSG_VERSION_1400);
+}
+
+void
+pfsync_state_export_1500(struct pfsync_state_1500 *sp, struct pf_kstate *st)
+{
+ bzero(sp, sizeof(*sp));
+ pfsync_state_export((union pfsync_state_union *)sp, st,
+ PFSYNC_MSG_VERSION_1500);
+}
+
+void
pf_state_export(struct pf_state_export *sp, struct pf_kstate *st)
{
bzero(sp, sizeof(*sp));