pf: Set the reassembly flags under the rules lock

DIOCSETREASS stored V_pf_status.reass twice with no lock, first the
flags it was given and then, if reassembly was not among them, zero.
pf_normalize_ip() and pf_normalize_ip6() read the flags with the rules
lock held for reading, so a packet could see the intermediate value.
Compute the flags first and store them once, with the rules lock held
for writing, as DIOCSETDEBUG and DIOCSETHOSTID do.

Reviewed by:		kp
Fixes:			39282ef356 ("pf: backport OpenBSD syntax of "scrub" option for "match" and "pass" rules")
MFC after:		2 weeks
Sponsored by:		Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D60531
This commit is contained in:
R. Christian McDonald committed 2026-10-13 09:39:30 -04:00
1 parent b5219c068f
commit b951994edd
1 file changed
+7 -3
+7 -3
View File
@@ -6627,12 +6627,16 @@ DIOCCHANGEADDR_error:
case DIOCSETREASS: {
u_int32_t *reass = (u_int32_t *)addr;
u_int32_t flags;
V_pf_status.reass = *reass & (PF_REASS_ENABLED|PF_REASS_NODF);
flags = *reass & (PF_REASS_ENABLED|PF_REASS_NODF);
/* Removal of DF flag without reassembly enabled is not a
* valid combination. Disable reassembly in such case. */
if (!(V_pf_status.reass & PF_REASS_ENABLED))
V_pf_status.reass = 0;
if (!(flags & PF_REASS_ENABLED))
flags = 0;
PF_RULES_WLOCK();
V_pf_status.reass = flags;
PF_RULES_WUNLOCK();
break;
}