summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2012-11-23 18:35:26 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2012-11-23 18:35:26 +0000
commit92e8ca9321f940df5b6639ce14fdceb2b772609f (patch)
treeee0db43dd664fed8f6b9f1adeba04f95483870d6
parentacde2fb8838267158045635e695c9bbbdf516346 (diff)
make sure to always pass an array of struct pf_src_node pointers to
the pf_map_addr. doing otherwise leads to the stack corruption. bug was reported and fix tested by arjan schrijver, thanks! ok jsing, henning, florian who has also found the same bug in pf_route and pf_route6 functions.
-rw-r--r--sys/net/pf.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 5177466a4c1..aa7a787b9d8 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.816 2012/11/06 12:32:41 henning Exp $ */
+/* $OpenBSD: pf.c,v 1.817 2012/11/23 18:35:25 mikeb Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -3204,15 +3204,16 @@ void
pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
{
struct pf_rule *r = s->rule.ptr;
- struct pf_src_node *sn = NULL;
+ struct pf_src_node *sns[PF_SN_MAX];
s->rt_kif = NULL;
if (!r->rt)
return;
+ bzero(sns, sizeof(sns));
switch (s->key[PF_SK_WIRE]->af) {
#ifdef INET
case AF_INET:
- pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, &sn,
+ pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, sns,
&r->route, PF_SN_ROUTE);
s->rt_kif = r->route.kif;
s->natrule.ptr = r;
@@ -3220,7 +3221,7 @@ pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
#endif /* INET */
#ifdef INET6
case AF_INET6:
- pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, &sn,
+ pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, sns,
&r->route, PF_SN_ROUTE);
s->rt_kif = r->route.kif;
s->natrule.ptr = r;
@@ -3710,6 +3711,8 @@ pf_create_state(struct pf_pdesc *pd, struct pf_rule *r, struct pf_rule *a,
#endif
s->set_prio[0] = act->set_prio[0];
s->set_prio[1] = act->set_prio[1];
+ SLIST_INIT(&s->src_nodes);
+
switch (pd->proto) {
case IPPROTO_TCP:
s->src.seqlo = ntohl(th->th_seq);
@@ -5844,7 +5847,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
struct ip *ip;
struct ifnet *ifp = NULL;
struct pf_addr naddr;
- struct pf_src_node *sn = NULL;
+ struct pf_src_node *sns[PF_SN_MAX];
int error = 0;
#ifdef IPSEC
struct m_tag *mtag;
@@ -5901,9 +5904,10 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
} else {
if (s == NULL) {
+ bzero(sns, sizeof(sns));
if (pf_map_addr(AF_INET, r,
(struct pf_addr *)&ip->ip_src,
- &naddr, NULL, &sn, &r->route, PF_SN_ROUTE)) {
+ &naddr, NULL, sns, &r->route, PF_SN_ROUTE)) {
DPFPRINTF(LOG_ERR,
"pf_route: pf_map_addr() failed.");
goto bad;
@@ -6027,7 +6031,7 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
struct ip6_hdr *ip6;
struct ifnet *ifp = NULL;
struct pf_addr naddr;
- struct pf_src_node *sn = NULL;
+ struct pf_src_node *sns[PF_SN_MAX];
if (m == NULL || *m == NULL || r == NULL ||
(dir != PF_IN && dir != PF_OUT) || oifp == NULL)
@@ -6069,8 +6073,9 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
}
if (s == NULL) {
+ bzero(sns, sizeof(sns));
if (pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src,
- &naddr, NULL, &sn, &r->route, PF_SN_ROUTE)) {
+ &naddr, NULL, sns, &r->route, PF_SN_ROUTE)) {
DPFPRINTF(LOG_ERR,
"pf_route6: pf_map_addr() failed.");
goto bad;