mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
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:
1 file changed
+7
-3
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user