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