From owner-svn-src-all@FreeBSD.ORG Thu Nov 3 18:33:30 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D6905106564A; Thu, 3 Nov 2011 18:33:30 +0000 (UTC) (envelope-from mlaier@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id BC5C48FC15; Thu, 3 Nov 2011 18:33:30 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pA3IXUPT081869; Thu, 3 Nov 2011 18:33:30 GMT (envelope-from mlaier@svn.freebsd.org) Received: (from mlaier@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pA3IXUpk081867; Thu, 3 Nov 2011 18:33:30 GMT (envelope-from mlaier@svn.freebsd.org) Message-Id: <201111031833.pA3IXUpk081867@svn.freebsd.org> From: Max Laier Date: Thu, 3 Nov 2011 18:33:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r227061 - head/sys/net X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Nov 2011 18:33:31 -0000 Author: mlaier Date: Thu Nov 3 18:33:30 2011 New Revision: 227061 URL: http://svn.freebsd.org/changeset/base/227061 Log: Fix a use-after-free/redzone issue in the routing code. Reported by (repeatedly): Mike Tancsa Prodded by (repeatedly): bz Forgotten by (repeatedly): mlaier MFC after: 2 weeks Modified: head/sys/net/rtsock.c Modified: head/sys/net/rtsock.c ============================================================================== --- head/sys/net/rtsock.c Thu Nov 3 18:09:11 2011 (r227060) +++ head/sys/net/rtsock.c Thu Nov 3 18:33:30 2011 (r227061) @@ -166,7 +166,7 @@ static void rt_setmetrics(u_long which, 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 sock 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 sock (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_addri 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 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 ifmultiad __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 w 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 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 * 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