diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2008-11-23 13:31:00 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2008-11-23 13:31:00 +0000 |
commit | 44978b1eda5b4db2c2ad45c9ec3269d18100063e (patch) | |
tree | 7890fcdf026b57de96da731a29aa8dce8d866748 /sys/netinet6 | |
parent | e86ddb7c0742ced59c785a9fd3f9cc2a443653d5 (diff) |
When accessing cached routes make sure the route is actually still valid.
Before accessing a ro_rt make sure the route is either freshly allocated or
RTF_UP is set. If not ro_rt should be freed and reallocated or at least no
info from the ro_rt should be considered valid.
This seems to solve the crashes seen by Felipe Alfaro Solana.
some sort of OK dlg@
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/frag6.c | 5 | ||||
-rw-r--r-- | sys/netinet6/in6_pcb.c | 4 | ||||
-rw-r--r-- | sys/netinet6/in6_src.c | 6 | ||||
-rw-r--r-- | sys/netinet6/ip6_forward.c | 7 | ||||
-rw-r--r-- | sys/netinet6/raw_ip6.c | 9 | ||||
-rw-r--r-- | sys/netinet6/udp6_output.c | 11 |
6 files changed, 22 insertions, 20 deletions
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c index 102fcdfb1f8..2069b673b14 100644 --- a/sys/netinet6/frag6.c +++ b/sys/netinet6/frag6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: frag6.c,v 1.26 2008/06/11 19:00:50 mcbride Exp $ */ +/* $OpenBSD: frag6.c,v 1.27 2008/11/23 13:30:59 claudio Exp $ */ /* $KAME: frag6.c,v 1.40 2002/05/27 21:40:31 itojun Exp $ */ /* @@ -197,8 +197,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto) #ifdef IN6_IFSTAT_STRICT /* find the destination interface of the packet. */ dst = (struct sockaddr_in6 *)&ro.ro_dst; - if (ro.ro_rt - && ((ro.ro_rt->rt_flags & RTF_UP) == 0 + if (ro.ro_rt && ((ro.ro_rt->rt_flags & RTF_UP) == 0 || !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &ip6->ip6_dst))) { RTFREE(ro.ro_rt); ro.ro_rt = (struct rtentry *)0; diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index 3ff0a17d3ba..a008f565912 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_pcb.c,v 1.47 2008/06/11 19:00:50 mcbride Exp $ */ +/* $OpenBSD: in6_pcb.c,v 1.48 2008/11/23 13:30:59 claudio Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -445,7 +445,7 @@ in6_pcbconnect(struct inpcb *inp, struct mbuf *nam) return (error); } - if (inp->inp_route6.ro_rt) + if (inp->inp_route6.ro_rt && inp->inp_route6.ro_rt->rt_flags & RTF_UP) ifp = inp->inp_route6.ro_rt->rt_ifp; inp->inp_ipv6.ip6_hlim = (u_int8_t)in6_selecthlim(inp, ifp); diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index d7c6a4effd2..8dbd1817864 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_src.c,v 1.22 2006/12/11 11:26:05 itojun Exp $ */ +/* $OpenBSD: in6_src.c,v 1.23 2008/11/23 13:30:59 claudio Exp $ */ /* $KAME: in6_src.c,v 1.36 2001/02/06 04:08:17 itojun Exp $ */ /* @@ -226,8 +226,8 @@ in6_selectsrc(dstsock, opts, mopts, ro, laddr, errorp) * our src addr is taken from the i/f, else punt. */ if (ro) { - if (ro->ro_rt && - !IN6_ARE_ADDR_EQUAL(&satosin6(&ro->ro_dst)->sin6_addr, dst)) { + if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || + !IN6_ARE_ADDR_EQUAL(&satosin6(&ro->ro_dst)->sin6_addr, dst))) { RTFREE(ro->ro_rt); ro->ro_rt = (struct rtentry *)0; } diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index ac9bf41f448..2fcb000bdca 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_forward.c,v 1.41 2008/10/22 14:36:08 markus Exp $ */ +/* $OpenBSD: ip6_forward.c,v 1.42 2008/11/23 13:30:59 claudio Exp $ */ /* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */ /* @@ -261,8 +261,9 @@ ip6_forward(struct mbuf *m, int srcrt) m_freem(m); return; } - } else if ((rt = ip6_forward_rt.ro_rt) == 0 || - !IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &dst->sin6_addr)) { + } else if (ip6_forward_rt.ro_rt == 0 || + (ip6_forward_rt.ro_rt->rt_flags & RTF_UP) == 0 || + !IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, &dst->sin6_addr)) { if (ip6_forward_rt.ro_rt) { RTFREE(ip6_forward_rt.ro_rt); ip6_forward_rt.ro_rt = 0; diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 94a20b2e640..94ebaee050e 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: raw_ip6.c,v 1.37 2008/09/17 05:43:15 chl Exp $ */ +/* $OpenBSD: raw_ip6.c,v 1.38 2008/11/23 13:30:59 claudio Exp $ */ /* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */ /* @@ -437,10 +437,9 @@ rip6_output(struct mbuf *m, ...) goto bad; } ip6->ip6_src = *in6a; - if (in6p->in6p_route.ro_rt) { - /* what if oifp contradicts ? */ - oifp = ifindex2ifnet[in6p->in6p_route.ro_rt->rt_ifp->if_index]; - } + if (in6p->in6p_route.ro_rt && + in6p->in6p_route.ro_rt->rt_flags & RTF_UP) + oifp = in6p->in6p_route.ro_rt->rt_ifp; } ip6->ip6_flow = in6p->in6p_flowinfo & IPV6_FLOWINFO_MASK; diff --git a/sys/netinet6/udp6_output.c b/sys/netinet6/udp6_output.c index f6c6315a3db..358814c97e3 100644 --- a/sys/netinet6/udp6_output.c +++ b/sys/netinet6/udp6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udp6_output.c,v 1.15 2008/06/11 19:00:50 mcbride Exp $ */ +/* $OpenBSD: udp6_output.c,v 1.16 2008/11/23 13:30:59 claudio Exp $ */ /* $KAME: udp6_output.c,v 1.21 2001/02/07 11:51:54 itojun Exp $ */ /* @@ -128,6 +128,7 @@ udp6_output(struct in6pcb *in6p, struct mbuf *m, struct mbuf *addr6, int flags; struct sockaddr_in6 tmp; struct proc *p = curproc; /* XXX */ + struct ifnet *ifp; priv = 0; if ((in6p->in6p_socket->so_state & SS_PRIV) != 0) @@ -249,9 +250,11 @@ udp6_output(struct in6pcb *in6p, struct mbuf *m, struct mbuf *addr6, ip6->ip6_plen = htons((u_short)plen); #endif ip6->ip6_nxt = IPPROTO_UDP; - ip6->ip6_hlim = in6_selecthlim(in6p, - in6p->in6p_route.ro_rt ? - in6p->in6p_route.ro_rt->rt_ifp : NULL); + ifp = NULL; + if (in6p->in6p_route.ro_rt && + in6p->in6p_route.ro_rt->rt_flags & RTF_UP) + ifp = in6p->in6p_route.ro_rt->rt_ifp; + ip6->ip6_hlim = in6_selecthlim(in6p, ifp); ip6->ip6_src = *laddr; ip6->ip6_dst = *faddr; |