diff options
author | 2011-01-10 18:57:59 +0000 | |
---|---|---|
committer | 2011-01-10 18:57:59 +0000 | |
commit | 0b25aa5597b3a81b7245dd7325abc60f09fe444f (patch) | |
tree | e69cd2ffe2ee597d7d4943f8b4dc0e60d46593f1 | |
parent | regen (diff) | |
download | wireguard-openbsd-0b25aa5597b3a81b7245dd7325abc60f09fe444f.tar.xz wireguard-openbsd-0b25aa5597b3a81b7245dd7325abc60f09fe444f.zip |
If pf_test() was called recursively, the global variable pf_hdrs
could be used multiple times for different packets. This happened
when pflow(4) was used. Instead of a global variable, store the
pf_headers in a local variable on the stack.
david@ found the bug, narrowed it down and tested the fix.
ok henning@
-rw-r--r-- | sys/net/pf.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c index abdfc6e25e9..6ee9a4fbd39 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.718 2011/01/10 10:26:38 mcbride Exp $ */ +/* $OpenBSD: pf.c,v 1.719 2011/01/10 18:57:59 bluhm Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -125,14 +125,14 @@ struct pf_anchor_stackframe { } pf_anchor_stack[64]; /* cannot fold into pf_pdesc directly, unknown storage size outside pf.c */ -union { +union pf_headers { struct tcphdr tcp; struct udphdr udp; struct icmp icmp; #ifdef INET6 struct icmp6_hdr icmp6; #endif /* INET6 */ -} pf_hdrs; +}; struct pool pf_src_tree_pl, pf_rule_pl; @@ -5792,6 +5792,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, struct pf_state *s = NULL; struct pf_ruleset *ruleset = NULL; struct pf_pdesc pd; + union pf_headers hdrs; int off, hdrlen; u_int32_t qid, pqid = 0; @@ -5799,7 +5800,7 @@ pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, return (PF_PASS); memset(&pd, 0, sizeof(pd)); - pd.hdr.any = &pf_hdrs; + pd.hdr.any = &hdrs; if (ifp->if_type == IFT_CARP && ifp->if_carpdev) kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif; else @@ -6057,13 +6058,14 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, struct pf_state *s = NULL; struct pf_ruleset *ruleset = NULL; struct pf_pdesc pd; + union pf_headers hdrs; int off, hdrlen; if (!pf_status.running) return (PF_PASS); memset(&pd, 0, sizeof(pd)); - pd.hdr.any = &pf_hdrs; + pd.hdr.any = &hdrs; if (ifp->if_type == IFT_CARP && ifp->if_carpdev) kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif; else |