summaryrefslogtreecommitdiffstats
path: root/sys/contrib
diff options
context:
space:
mode:
authormlaier <mlaier@FreeBSD.org>2005-07-20 18:58:27 +0000
committermlaier <mlaier@FreeBSD.org>2005-07-20 18:58:27 +0000
commite0e4afff1d417b7889e3e39e69d594d5309b77ce (patch)
treead7de18a5f7c0eb49f5f05bbfeeb9a6091f444b4 /sys/contrib
parent6fa05635cf323fac06a364da1c608e0a9a8388f9 (diff)
downloadFreeBSD-src-e0e4afff1d417b7889e3e39e69d594d5309b77ce.zip
FreeBSD-src-e0e4afff1d417b7889e3e39e69d594d5309b77ce.tar.gz
Prevent a race condition. As pf_send_tcp() - called for expired synproxy
states - has to drop the lock when calling back to ip_output(), the state purge timeout might run and gc the state. This results in a rb-tree inconsistency. With this change we flag expiring states while holding the lock and back off if the flag is already set. Reported by: glebius MFC after: 2 weeks
Diffstat (limited to 'sys/contrib')
-rw-r--r--sys/contrib/pf/net/pf.c5
-rw-r--r--sys/contrib/pf/net/pfvar.h3
2 files changed, 8 insertions, 0 deletions
diff --git a/sys/contrib/pf/net/pf.c b/sys/contrib/pf/net/pf.c
index 9fb50e3..eb034da 100644
--- a/sys/contrib/pf/net/pf.c
+++ b/sys/contrib/pf/net/pf.c
@@ -1085,6 +1085,11 @@ pf_src_tree_remove_state(struct pf_state *s)
void
pf_purge_expired_state(struct pf_state *cur)
{
+#ifdef __FreeBSD__
+ if (cur->sync_flags & PFSTATE_EXPIRING)
+ return;
+ cur->sync_flags |= PFSTATE_EXPIRING;
+#endif
if (cur->src.state == PF_TCPS_PROXY_DST)
pf_send_tcp(cur->rule.ptr, cur->af,
&cur->ext.addr, &cur->lan.addr,
diff --git a/sys/contrib/pf/net/pfvar.h b/sys/contrib/pf/net/pfvar.h
index 8d0469f..5fdef85 100644
--- a/sys/contrib/pf/net/pfvar.h
+++ b/sys/contrib/pf/net/pfvar.h
@@ -790,6 +790,9 @@ struct pf_state {
#define PFSTATE_NOSYNC 0x01
#define PFSTATE_FROMSYNC 0x02
#define PFSTATE_STALE 0x04
+#ifdef __FreeBSD__
+#define PFSTATE_EXPIRING 0x10
+#endif
u_int8_t pad;
};
OpenPOWER on IntegriCloud