diff options
author | glebius <glebius@FreeBSD.org> | 2012-11-07 07:30:40 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2012-11-07 07:30:40 +0000 |
commit | d989f8363f4ca0f593e5d89add63cd3a367c556a (patch) | |
tree | f9e3f1406f92f38a0a7d902fab69de60024298ea | |
parent | 25611f9cf9abb970322ecc6e9eb957d8f47b4819 (diff) | |
download | FreeBSD-src-d989f8363f4ca0f593e5d89add63cd3a367c556a.zip FreeBSD-src-d989f8363f4ca0f593e5d89add63cd3a367c556a.tar.gz |
It may happen that pfsync holds the last reference on a state. In this
case keys had already been freed. If encountering such state, then
just release last reference.
Not sure this can happen as a runtime race, but can be reproduced by
the following scenario:
- enable pfsync
- disable pfsync
- wait some time
- enable pfsync
-rw-r--r-- | sys/netpfil/pf/if_pfsync.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c index bd1e5c4..8736487 100644 --- a/sys/netpfil/pf/if_pfsync.c +++ b/sys/netpfil/pf/if_pfsync.c @@ -1545,6 +1545,16 @@ pfsync_sendout(int schedswi) KASSERT(st->sync_state == q, ("%s: st->sync_state == q", __func__)); + if (st->timeout == PFTM_UNLINKED) { + /* + * This happens if pfsync was once + * stopped, and then re-enabled + * after long time. Theoretically + * may happen at usual runtime, too. + */ + pf_release_state(st); + continue; + } /* * XXXGL: some of write methods do unlocked reads * of state data :( |