Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 Aug 2012 12:19:14 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r239773 - projects/pf/head/sys/contrib/pf/net
Message-ID:  <201208281219.q7SCJEug066022@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201208281219.q7SCJEug066022>