Author: bz
Date: Wed Nov 23 22:16:45 2011
New Revision: 227915
URL: http://svn.freebsd.org/changeset/base/227915

Log:
  MFC r227061 (by mlaier):
  
   Fix a use-after-free/redzone issue in the routing code.

Modified:
  stable/8/sys/net/rtsock.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/net/rtsock.c
==============================================================================
--- stable/8/sys/net/rtsock.c   Wed Nov 23 22:07:13 2011        (r227914)
+++ stable/8/sys/net/rtsock.c   Wed Nov 23 22:16:45 2011        (r227915)
@@ -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.
@@ -927,10 +929,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);
        }
     }
        return (error);
@@ -1183,7 +1185,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
@@ -1215,7 +1217,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);
 }
 
 /*
@@ -1293,7 +1295,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);
        }
 }
 
@@ -1336,7 +1338,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 *
@@ -1396,7 +1398,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);
        }
 }
 
@@ -1412,11 +1414,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;
 
@@ -1425,14 +1427,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
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to