svn commit: r239773 - projects/pf/head/sys/contrib/pf/net
Gleb Smirnoff
glebius at FreeBSD.org
Tue Aug 28 12:19:15 UTC 2012
Author: glebius
Date: Tue Aug 28 12:19:14 2012
New Revision: 239773
URL: http://svn.freebsd.org/changeset/base/239773
Log:
Protection against race between pf_unlink_state() vs
pf_unlink_state().
This may happen in a very rare case, when a forwarding
thread creates a state, and encounters state with same key
but with both sides in >= TCPS_FIN_WAIT_2. The old state
is deleted then, and it can race with deletion by expiry
thread.
Modified:
projects/pf/head/sys/contrib/pf/net/pf.c
Modified: projects/pf/head/sys/contrib/pf/net/pf.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf.c Tue Aug 28 11:35:09 2012 (r239772)
+++ projects/pf/head/sys/contrib/pf/net/pf.c Tue Aug 28 12:19:14 2012 (r239773)
@@ -1503,6 +1503,18 @@ pf_unlink_state(struct pf_state *s, u_in
else
PF_HASHROW_ASSERT(ih);
+ if (s->timeout == PFTM_UNLINKED) {
+ /*
+ * State is being processed
+ * by pf_unlink_state() in
+ * an other thread.
+ */
+ PF_HASHROW_UNLOCK(ih);
+ return (0); /* XXXGL: undefined actually */
+ }
+
+ s->timeout = PFTM_UNLINKED;
+
if (s->src.state == PF_TCPS_PROXY_DST) {
/* XXX wire key the right one? */
pf_send_tcp(NULL, s->rule.ptr, s->key[PF_SK_WIRE]->af,
@@ -1520,7 +1532,6 @@ pf_unlink_state(struct pf_state *s, u_in
if (export_pflow_ptr != NULL)
export_pflow_ptr(s);
#endif
- s->timeout = PFTM_UNLINKED;
pf_src_tree_remove_state(s);
PF_HASHROW_UNLOCK(ih);
More information about the svn-src-projects
mailing list