diff options
author | mlaier <mlaier@FreeBSD.org> | 2005-07-20 18:58:27 +0000 |
---|---|---|
committer | mlaier <mlaier@FreeBSD.org> | 2005-07-20 18:58:27 +0000 |
commit | e0e4afff1d417b7889e3e39e69d594d5309b77ce (patch) | |
tree | ad7de18a5f7c0eb49f5f05bbfeeb9a6091f444b4 /sys/contrib/pf | |
parent | 6fa05635cf323fac06a364da1c608e0a9a8388f9 (diff) | |
download | FreeBSD-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/pf')
-rw-r--r-- | sys/contrib/pf/net/pf.c | 5 | ||||
-rw-r--r-- | sys/contrib/pf/net/pfvar.h | 3 |
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; }; |