Author: markj
Date: Mon Nov 26 13:42:18 2018
New Revision: 340968
URL: https://svnweb.freebsd.org/changeset/base/340968

Log:
  Plug routing sysctl leaks.
  
  Various structures exported by sysctl_rtsock() contain padding fields
  which were not being zeroed.
  
  Reported by:  Thomas Barabosch, Fraunhofer FKIE
  Reviewed by:  ae
  MFC after:    3 days
  Security:     kernel memory disclosure
  Sponsored by: The FreeBSD Foundation
  Differential Revision:        https://reviews.freebsd.org/D18333

Modified:
  head/sys/net/if.h
  head/sys/net/route.h
  head/sys/net/rtsock.c

Modified: head/sys/net/if.h
==============================================================================
--- head/sys/net/if.h   Mon Nov 26 13:36:30 2018        (r340967)
+++ head/sys/net/if.h   Mon Nov 26 13:42:18 2018        (r340968)
@@ -271,6 +271,7 @@ struct if_msghdr {
        int     ifm_addrs;      /* like rtm_addrs */
        int     ifm_flags;      /* value of if_flags */
        u_short ifm_index;      /* index for associated ifp */
+       u_short _ifm_spare1;
        struct  if_data ifm_data;/* statistics and other data about if */
 };
 
@@ -296,6 +297,7 @@ struct if_msghdrl {
        u_short _ifm_spare1;    /* spare space to grow if_index, see if_var.h */
        u_short ifm_len;        /* length of if_msghdrl incl. if_data */
        u_short ifm_data_off;   /* offset of if_data from beginning */
+       int     _ifm_spare2;
        struct  if_data ifm_data;/* statistics and other data about if */
 };
 
@@ -311,6 +313,7 @@ struct ifa_msghdr {
        int     ifam_addrs;     /* like rtm_addrs */
        int     ifam_flags;     /* value of ifa_flags */
        u_short ifam_index;     /* index for associated ifp */
+       u_short _ifam_spare1;
        int     ifam_metric;    /* value of ifa_ifp->if_metric */
 };
 
@@ -352,6 +355,7 @@ struct ifma_msghdr {
        int     ifmam_addrs;    /* like rtm_addrs */
        int     ifmam_flags;    /* value of ifa_flags */
        u_short ifmam_index;    /* index for associated ifp */
+       u_short _ifmam_spare1;
 };
 
 /*

Modified: head/sys/net/route.h
==============================================================================
--- head/sys/net/route.h        Mon Nov 26 13:36:30 2018        (r340967)
+++ head/sys/net/route.h        Mon Nov 26 13:42:18 2018        (r340968)
@@ -251,6 +251,7 @@ struct rt_msghdr {
        u_char  rtm_version;    /* future binary compatibility */
        u_char  rtm_type;       /* message type */
        u_short rtm_index;      /* index for associated ifp */
+       u_short _rtm_spare1;
        int     rtm_flags;      /* flags, incl. kern & message, e.g. DONE */
        int     rtm_addrs;      /* bitmask identifying sockaddrs in msg */
        pid_t   rtm_pid;        /* identify sender */

Modified: head/sys/net/rtsock.c
==============================================================================
--- head/sys/net/rtsock.c       Mon Nov 26 13:36:30 2018        (r340967)
+++ head/sys/net/rtsock.c       Mon Nov 26 13:42:18 2018        (r340968)
@@ -83,6 +83,7 @@ struct if_msghdr32 {
        int32_t ifm_addrs;
        int32_t ifm_flags;
        uint16_t ifm_index;
+       uint16_t _ifm_spare1;
        struct  if_data ifm_data;
 };
 
@@ -96,6 +97,7 @@ struct if_msghdrl32 {
        uint16_t _ifm_spare1;
        uint16_t ifm_len;
        uint16_t ifm_data_off;
+       uint32_t _ifm_spare2;
        struct  if_data ifm_data;
 };
 
@@ -1219,8 +1221,11 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo
                dlen = ALIGN(len) - len;
                if (buflen < dlen)
                        cp = NULL;
-               else
+               else {
+                       bzero(cp, dlen);
+                       cp += dlen;
                        buflen -= dlen;
+               }
        }
        len = ALIGN(len);
 
@@ -1577,6 +1582,8 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
        if (w->w_req && w->w_tmem) {
                struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem;
 
+               bzero(&rtm->rtm_index,
+                   sizeof(*rtm) - offsetof(struct rt_msghdr, rtm_index));
                if (rt->rt_flags & RTF_GWFLAG_COMPAT)
                        rtm->rtm_flags = RTF_GATEWAY | 
                                (rt->rt_flags & ~RTF_GWFLAG_COMPAT);
@@ -1584,7 +1591,6 @@ sysctl_dumpentry(struct radix_node *rn, void *vw)
                        rtm->rtm_flags = rt->rt_flags;
                rt_getmetrics(rt, &rtm->rtm_rmx);
                rtm->rtm_index = rt->rt_ifp->if_index;
-               rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0;
                rtm->rtm_addrs = info.rti_addrs;
                error = SYSCTL_OUT(w->w_req, (caddr_t)rtm, size);
                return (error);
@@ -1612,6 +1618,7 @@ sysctl_iflist_ifml(struct ifnet *ifp, const struct if_
                ifm32->_ifm_spare1 = 0;
                ifm32->ifm_len = sizeof(*ifm32);
                ifm32->ifm_data_off = offsetof(struct if_msghdrl32, ifm_data);
+               ifm32->_ifm_spare2 = 0;
                ifd = &ifm32->ifm_data;
        } else
 #endif
@@ -1622,6 +1629,7 @@ sysctl_iflist_ifml(struct ifnet *ifp, const struct if_
                ifm->_ifm_spare1 = 0;
                ifm->ifm_len = sizeof(*ifm);
                ifm->ifm_data_off = offsetof(struct if_msghdrl, ifm_data);
+               ifm->_ifm_spare2 = 0;
                ifd = &ifm->ifm_data;
        }
 
@@ -1647,6 +1655,7 @@ sysctl_iflist_ifm(struct ifnet *ifp, const struct if_d
                ifm32->ifm_addrs = info->rti_addrs;
                ifm32->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
                ifm32->ifm_index = ifp->if_index;
+               ifm32->_ifm_spare1 = 0;
                ifd = &ifm32->ifm_data;
        } else
 #endif
@@ -1654,6 +1663,7 @@ sysctl_iflist_ifm(struct ifnet *ifp, const struct if_d
                ifm->ifm_addrs = info->rti_addrs;
                ifm->ifm_flags = ifp->if_flags | ifp->if_drv_flags;
                ifm->ifm_index = ifp->if_index;
+               ifm->_ifm_spare1 = 0;
                ifd = &ifm->ifm_data;
        }
 
@@ -1722,6 +1732,7 @@ sysctl_iflist_ifam(struct ifaddr *ifa, struct rt_addri
        ifam->ifam_addrs = info->rti_addrs;
        ifam->ifam_flags = ifa->ifa_flags;
        ifam->ifam_index = ifa->ifa_ifp->if_index;
+       ifam->_ifam_spare1 = 0;
        ifam->ifam_metric = ifa->ifa_ifp->if_metric;
 
        return (SYSCTL_OUT(w->w_req, w->w_tmem, len));
@@ -1833,6 +1844,7 @@ sysctl_ifmalist(int af, struct walkarg *w)
                                ifmam->ifmam_index = ifma->ifma_ifp->if_index;
                                ifmam->ifmam_flags = 0;
                                ifmam->ifmam_addrs = info.rti_addrs;
+                               ifmam->_ifmam_spare1 = 0;
                                error = SYSCTL_OUT(w->w_req, w->w_tmem, len);
                                if (error != 0)
                                        break;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to