rework pf_state_expires to avoid confusion around state->timeout.
authordlg <dlg@openbsd.org>
Wed, 23 Jun 2021 04:16:32 +0000 (04:16 +0000)
committerdlg <dlg@openbsd.org>
Wed, 23 Jun 2021 04:16:32 +0000 (04:16 +0000)
commit99e6e1ef5c9fa2ffc9cbb56b4b4f522d9b8918e3
treed854dd7f67ce8af8f254a2f96884356a923677e5
parenta5963c21680ebcecd75fa6f32d99ecfc63aaaa72
rework pf_state_expires to avoid confusion around state->timeout.

im going to make it so pf_purge_expired_states() can gather states
largely without sharing a lock with pfsync or actual packet processing
in pf. if pf or pfsync unlink a state while pf_purge_expired_states
is looking at it, we can race with some checks and fall over a
KASSERT.

i'm fixing this by having the caller of pf_state_expires read
state->timeout first, do it's checks, and then pass the value as
an argument into pf_state_expires. this means there's a consistent
view of the state->timeout variable across all the checks that
pf_purge_expired_states in particular does. if pf/pfsync does change
the timeout while pf_purge_expired_states is looking at it, the
worst thing that happens is that it doesn't get picked as a candidate
for purging in this pass and will have to wait for the next sweep.

ok sashan@ as part of a bigger diff
sys/net/pf.c
sys/net/pfvar.h