From 017fa4d58eb857ef97c01955b0b1fb20dedaa797 Mon Sep 17 00:00:00 2001 From: bz Date: Wed, 23 Nov 2011 18:04:53 +0000 Subject: [PATCH] MFC r227061 (by mlaier): Fix a use-after-free/redzone issue in the routing code. Approved by: re (kib) git-svn-id: svn://svn.freebsd.org/base/releng/9.0@227895 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/net/rtsock.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index fdd017cd..48a527e5 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -166,7 +166,7 @@ static void rt_setmetrics(u_long which, const struct rt_metrics *in, struct rt_metrics_lite *out); static void rt_getmetrics(const struct rt_metrics_lite *in, struct rt_metrics *out); -static void rt_dispatch(struct mbuf *, const struct sockaddr *); +static void rt_dispatch(struct mbuf *, sa_family_t); static struct netisr_handler rtsock_nh = { .nh_name = "rtsock", @@ -545,6 +545,7 @@ route_output(struct mbuf *m, struct socket *so) int len, error = 0; struct ifnet *ifp = NULL; union sockaddr_union saun; + sa_family_t saf = AF_UNSPEC; #define senderr(e) { error = e; goto flush;} if (m == NULL || ((m->m_len < sizeof(long)) && @@ -581,6 +582,7 @@ route_output(struct mbuf *m, struct socket *so) (info.rti_info[RTAX_GATEWAY] != NULL && info.rti_info[RTAX_GATEWAY]->sa_family >= AF_MAX)) senderr(EINVAL); + saf = info.rti_info[RTAX_DST]->sa_family; /* * Verify that the caller has the appropriate privilege; RTM_GET * is the only operation the non-superuser is allowed. @@ -926,10 +928,10 @@ flush: */ unsigned short family = rp->rcb_proto.sp_family; rp->rcb_proto.sp_family = 0; - rt_dispatch(m, info.rti_info[RTAX_DST]); + rt_dispatch(m, saf); rp->rcb_proto.sp_family = family; } else - rt_dispatch(m, info.rti_info[RTAX_DST]); + rt_dispatch(m, saf); } /* info.rti_info[RTAX_DST] (used above) can point inside of rtm */ if (rtm) @@ -1185,7 +1187,7 @@ rt_missmsg_fib(int type, struct rt_addrinfo *rtinfo, int flags, int error, rtm->rtm_flags = RTF_DONE | flags; rtm->rtm_errno = error; rtm->rtm_addrs = rtinfo->rti_addrs; - rt_dispatch(m, sa); + rt_dispatch(m, sa ? sa->sa_family : AF_UNSPEC); } void @@ -1217,7 +1219,7 @@ rt_ifmsg(struct ifnet *ifp) ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags; ifm->ifm_data = ifp->if_data; ifm->ifm_addrs = 0; - rt_dispatch(m, NULL); + rt_dispatch(m, AF_UNSPEC); } /* @@ -1295,7 +1297,7 @@ rt_newaddrmsg_fib(int cmd, struct ifaddr *ifa, int error, struct rtentry *rt, M_SETFIB(m, fibnum); m->m_flags |= RTS_FILTER_FIB; } - rt_dispatch(m, sa); + rt_dispatch(m, sa ? sa->sa_family : AF_UNSPEC); } } @@ -1338,7 +1340,7 @@ rt_newmaddrmsg(int cmd, struct ifmultiaddr *ifma) __func__)); ifmam->ifmam_index = ifp->if_index; ifmam->ifmam_addrs = info.rti_addrs; - rt_dispatch(m, ifma->ifma_addr); + rt_dispatch(m, ifma->ifma_addr ? ifma->ifma_addr->sa_family : AF_UNSPEC); } static struct mbuf * @@ -1398,7 +1400,7 @@ rt_ieee80211msg(struct ifnet *ifp, int what, void *data, size_t data_len) if (m->m_flags & M_PKTHDR) m->m_pkthdr.len += data_len; mtod(m, struct if_announcemsghdr *)->ifan_msglen += data_len; - rt_dispatch(m, NULL); + rt_dispatch(m, AF_UNSPEC); } } @@ -1414,11 +1416,11 @@ rt_ifannouncemsg(struct ifnet *ifp, int what) m = rt_makeifannouncemsg(ifp, RTM_IFANNOUNCE, what, &info); if (m != NULL) - rt_dispatch(m, NULL); + rt_dispatch(m, AF_UNSPEC); } static void -rt_dispatch(struct mbuf *m, const struct sockaddr *sa) +rt_dispatch(struct mbuf *m, sa_family_t saf) { struct m_tag *tag; @@ -1427,14 +1429,14 @@ rt_dispatch(struct mbuf *m, const struct sockaddr *sa) * use when injecting the mbuf into the routing socket buffer from * the netisr. */ - if (sa != NULL) { + if (saf != AF_UNSPEC) { tag = m_tag_get(PACKET_TAG_RTSOCKFAM, sizeof(unsigned short), M_NOWAIT); if (tag == NULL) { m_freem(m); return; } - *(unsigned short *)(tag + 1) = sa->sa_family; + *(unsigned short *)(tag + 1) = saf; m_tag_prepend(m, tag); } #ifdef VIMAGE -- 2.42.0