CVSROOT:        /cvs
Module name:    src
Changes by:     l...@cvs.openbsd.org    2019/07/17 20:03:46

Modified files:
        sys/net        : pf.c 

Log message:
This commit fixes two bugs involving PF once rules:

1. If a packet happens to match an expired once rule before the rule is removed
by the purge thread, the rule will be added to the pf_rule_gcl list again,
eventually causing a kernel crash when the purge thread tries to remove the
expired rule multiple times; and

2. A packet that matches an expired once rule will still cause a state to be
created, so a once rule is not truly a one shot rule while it is in that
expired-but-not-purged time window.

To fix both bugs, add a check in pf_test_rule() to prevent expired once rules
from being added to pf_rule_gcl.  The check is added "early" in pf_test_rule()
to prevent any new connections from creating state if they match the expired
once rule.

This commit also includes a tweak by sashan@ to ensure that only one PF task
will mark a once rule as expired.  Here is sashan@'s commentary:

"As soon as there will be more PF tasks running in parallel, we would be
able to hit similar crash you are fixing now. The rules are covered by
read lock, so with more PF tasks there might be two packets racing
to expire at once rule at the same time. Using atomic_cas() is sufficient
measure to serialize competing packets."

tested by abieber@ who reported the kernel crash on bugs@
ok sashan@

Reply via email to