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>