Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/bsd/dhcpcd/dist/src Import dhcpcd-7.2.2 with the fo...



details:   https://anonhg.NetBSD.org/src/rev/efa5cdf8f979
branches:  trunk
changeset: 451034:efa5cdf8f979
user:      roy <roy%NetBSD.org@localhost>
date:      Sat May 04 09:40:27 2019 +0000

description:
Import dhcpcd-7.2.2 with the following changes:
  *  DHCP: Ensure dhcp is running on the interface received from
  *  BSD: Link handling has been simplified, however it is expected
     that if an interface supports SIOCGIFMEDIA then it reports
     the correct link status via route(4) for reliable operations
  *  BPF: ARP filter is more robust
  *  BSD: Validate RTM message lengths

This security issue has been addressed:
  *  DHCPv6: Fix a potential read overflow with D6_OPTION_PD_EXCLUDE

Many thanks to Maxime Villard <max%m00nbsd.net@localhost> for discovering this issue.

diffstat:

 external/bsd/dhcpcd/dist/src/defs.h     |    2 +-
 external/bsd/dhcpcd/dist/src/dhcpcd.h   |    1 -
 external/bsd/dhcpcd/dist/src/if-linux.c |    9 +
 external/bsd/dhcpcd/dist/src/if-sun.c   |  160 +++++++++++++++++++++----------
 external/bsd/dhcpcd/dist/src/if.c       |   72 ++++----------
 external/bsd/dhcpcd/dist/src/if.h       |    2 +-
 6 files changed, 139 insertions(+), 107 deletions(-)

diffs (truncated from 523 to 300 lines):

diff -r d3333b0d58c8 -r efa5cdf8f979 external/bsd/dhcpcd/dist/src/defs.h
--- a/external/bsd/dhcpcd/dist/src/defs.h       Sat May 04 09:03:08 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/defs.h       Sat May 04 09:40:27 2019 +0000
@@ -28,7 +28,7 @@
 #define CONFIG_H
 
 #define PACKAGE                        "dhcpcd"
-#define VERSION                        "7.2.1"
+#define VERSION                        "7.2.2"
 
 #ifndef CONFIG
 # define CONFIG                        SYSCONFDIR "/" PACKAGE ".conf"
diff -r d3333b0d58c8 -r efa5cdf8f979 external/bsd/dhcpcd/dist/src/dhcpcd.h
--- a/external/bsd/dhcpcd/dist/src/dhcpcd.h     Sat May 04 09:03:08 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/dhcpcd.h     Sat May 04 09:40:27 2019 +0000
@@ -85,7 +85,6 @@
        unsigned short vlanid;
        unsigned int metric;
        int carrier;
-       bool media_valid;
        bool wireless;
        uint8_t ssid[IF_SSIDLEN];
        unsigned int ssid_len;
diff -r d3333b0d58c8 -r efa5cdf8f979 external/bsd/dhcpcd/dist/src/if-linux.c
--- a/external/bsd/dhcpcd/dist/src/if-linux.c   Sat May 04 09:03:08 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/if-linux.c   Sat May 04 09:40:27 2019 +0000
@@ -349,6 +349,15 @@
        }
 }
 
+int
+if_carrier(struct interface *ifp)
+{
+
+       if (if_getflags(ifp) == -1)
+               return LINK_UNKNOWN;
+       return ifp->flags & IFF_RUNNING ? LINK_UP : LINK_DOWN;
+}
+
 static int
 get_netlink(struct dhcpcd_ctx *ctx, struct iovec *iov,
     struct interface *ifp, int fd, int flags,
diff -r d3333b0d58c8 -r efa5cdf8f979 external/bsd/dhcpcd/dist/src/if-sun.c
--- a/external/bsd/dhcpcd/dist/src/if-sun.c     Sat May 04 09:03:08 2019 +0000
+++ b/external/bsd/dhcpcd/dist/src/if-sun.c     Sat May 04 09:40:27 2019 +0000
@@ -171,13 +171,16 @@
 }
 
 int
-if_carrier_os(struct interface *ifp)
+if_carrier(struct interface *ifp)
 {
        kstat_ctl_t             *kcp;
        kstat_t                 *ksp;
        kstat_named_t           *knp;
        link_state_t            linkstate;
 
+       if (if_getflags(ifp) == -1)
+               return LINK_UNKNOWN;
+
        kcp = kstat_open();
        if (kcp == NULL)
                goto err;
@@ -423,21 +426,26 @@
 }
 
 static int
-get_addrs(int type, const void *data, const struct sockaddr **sa)
+get_addrs(int type, const void *data, size_t data_len,
+    const struct sockaddr **sa)
 {
-       const char *cp;
+       const char *cp, *ep;
        int i;
-       const struct sockaddr **sap;
 
        cp = data;
+       ep = cp + data_len;
        for (i = 0; i < RTAX_MAX; i++) {
-               sap = &sa[i];
                if (type & (1 << i)) {
-                       *sap = (const struct sockaddr *)cp;
-                       RT_ADVANCE(cp, *sap);
+                       if (cp >= ep) {
+                               errno = EINVAL;
+                               return -1;
+                       }
+                       sa[i] = (const struct sockaddr *)cp;
+                       RT_ADVANCE(cp, sa[i]);
                } else
-                       *sap = NULL;
+                       sa[i] = NULL;
        }
+
        return 0;
 }
 
@@ -629,10 +637,16 @@
 {
        const struct sockaddr *rti_info[RTAX_MAX];
 
-       if (~rtm->rtm_addrs & (RTA_DST | RTA_GATEWAY))
+       if (~rtm->rtm_addrs & RTA_DST)
                return -1;
 
-       get_addrs(rtm->rtm_addrs, rtm + 1, rti_info);
+       /* We have already checked that at least one address must be
+        * present after the rtm structure. */
+       /* coverity[ptr_arith] */
+       if (get_addrs(rtm->rtm_addrs, rtm + 1,
+                     rtm->rtm_msglen - sizeof(*rtm), rti_info) == -1)
+               return -1;
+
        memset(rt, 0, sizeof(*rt));
 
        rt->rt_flags = (unsigned int)rtm->rtm_flags;
@@ -640,7 +654,7 @@
        if (rtm->rtm_addrs & RTA_NETMASK)
                COPYSA(&rt->rt_netmask, rti_info[RTAX_NETMASK]);
        /* dhcpcd likes an unspecified gateway to indicate via the link. */
-       if (rt->rt_flags & RTF_GATEWAY &&
+       if (rtm->rtm_addrs & RTA_GATEWAY &&
            rti_info[RTAX_GATEWAY]->sa_family != AF_LINK)
                COPYSA(&rt->rt_gateway, rti_info[RTAX_GATEWAY]);
        if (rtm->rtm_addrs & RTA_SRC)
@@ -696,7 +710,7 @@
        return rt;
 }
 
-static void
+static int
 if_finishrt(struct dhcpcd_ctx *ctx, struct rt *rt)
 {
        int mtu;
@@ -740,10 +754,8 @@
        if (rt->rt_ifp == NULL) {
                if (if_route_get(ctx, rt) == NULL) {
                        rt->rt_ifp = if_loopback(ctx);
-                       if (rt->rt_ifp == NULL) {
-                               logerr(__func__);
-                               return;
-                       }
+                       if (rt->rt_ifp == NULL)
+                               return - 1;
                }
        }
 
@@ -752,8 +764,12 @@
         * This confuses dhcpcd as it expects MTU to be 0
         * when no explicit MTU has been set. */
        mtu = if_getmtu(rt->rt_ifp);
+       if (mtu == -1)
+               return -1;
        if (rt->rt_mtu == (unsigned int)mtu)
                rt->rt_mtu = 0;
+
+       return 0;
 }
 
 static uint64_t
@@ -773,12 +789,17 @@
        return lifr.lifr_flags;
 }
 
-static void
+static int
 if_rtm(struct dhcpcd_ctx *ctx, const struct rt_msghdr *rtm)
 {
        const struct sockaddr *sa;
        struct rt rt;
 
+       if (rtm->rtm_msglen < sizeof(*rtm) + sizeof(*sa)) {
+               errno = EINVAL;
+               return -1;
+       }
+
        sa = (const void *)(rtm + 1);
        switch (sa->sa_family) {
 #ifdef INET6
@@ -796,7 +817,9 @@
                        struct in6_addr dst6;
                        struct sockaddr_dl sdl;
 
-                       get_addrs(rtm->rtm_addrs, sa, rti_info);
+                       if (get_addrs(rtm->rtm_addrs, sa,
+                           rtm->rtm_msglen - sizeof(*rtm), rti_info) == -1)
+                               return -1;
                        COPYOUT6(dst6, rti_info[RTAX_DST]);
                        if (rti_info[RTAX_GATEWAY]->sa_family == AF_LINK)
                                memcpy(&sdl, rti_info[RTAX_GATEWAY],
@@ -811,10 +834,12 @@
        }
 #endif
 
-       if (if_copyrt(ctx, &rt, rtm) == 0) {
-               if_finishrt(ctx, &rt);
-               rt_recvrt(rtm->rtm_type, &rt, rtm->rtm_pid);
-       }
+       if (if_copyrt(ctx, &rt, rtm) == -1 && errno != ESRCH)
+               return -1;
+       if (if_finishrt(ctx, &rt) == -1)
+               return -1;
+       rt_recvrt(rtm->rtm_type, &rt, rtm->rtm_pid);
+       return 0;
 }
 
 static bool
@@ -860,7 +885,7 @@
        return r;
 }
 
-static void
+static int
 if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam)
 {
        struct interface        *ifp;
@@ -868,16 +893,26 @@
        int                     flags;
        char                    ifalias[IF_NAMESIZE];
 
+       if (ifam->ifam_msglen < sizeof(*ifam)) {
+               errno = EINVAL;
+               return -1;
+       }
+       if (~ifam->ifam_addrs & RTA_IFA)
+               return 0;
+
+       /* We have already checked that at least one address must be
+        * present after the ifam structure. */
+       /* coverity[ptr_arith] */
+       if (get_addrs(ifam->ifam_addrs, ifam + 1,
+                     ifam->ifam_msglen - sizeof(*ifam), rti_info) == -1)
+               return -1;
+       sa = rti_info[RTAX_IFA];
+
        /* XXX We have no way of knowing who generated these
         * messages wich truely sucks because we want to
         * avoid listening to our own delete messages. */
        if ((ifp = if_findindex(ctx->ifaces, ifam->ifam_index)) == NULL)
-               return;
-       sa = (const void *)(ifam + 1);
-       get_addrs(ifam->ifam_addrs, sa, rti_info);
-
-       if ((sa = rti_info[RTAX_IFA]) == NULL)
-               return;
+               return 0;
 
        /*
         * ifa_msghdr does not supply the alias, just the interface index.
@@ -893,7 +928,7 @@
         *   ifam_pid
         */
        if (ifam->ifam_type != RTM_DELADDR && !if_getalias(ifp, sa, ifalias))
-               return;
+               return 0;
 
        switch (sa->sa_family) {
        case AF_LINK:
@@ -921,20 +956,20 @@
 
                        ia = ipv4_iffindaddr(ifp, &addr, &mask);
                        if (ia == NULL)
-                               return;
+                               return 0;
                        strlcpy(ifalias, ia->alias, sizeof(ifalias));
                } else if (bcast.s_addr == INADDR_ANY) {
                        /* Work around a bug where broadcast
                         * address is not correctly reported. */
                        if (if_getbrdaddr(ctx, ifalias, &bcast) == -1)
-                               return;
+                               return 0;
                }
                flags = if_addrflags(ifp, &addr, ifalias);
                if (ifam->ifam_type == RTM_DELADDR) {
                        if (flags != -1)
-                               return;
+                               return 0;
                } else if (flags == -1)
-                       return;
+                       return 0;
 
                ipv4_handleifa(ctx,
                    ifam->ifam_type == RTM_CHGADDR ?
@@ -959,15 +994,15 @@
 
                        ia = ipv6_iffindaddr(ifp, &addr6, 0);
                        if (ia == NULL)
-                               return;
+                               return 0;
                        strlcpy(ifalias, ia->alias, sizeof(ifalias));
                }
                flags = if_addrflags6(ifp, &addr6, ifalias);
                if (ifam->ifam_type == RTM_DELADDR) {
                        if (flags != -1)
-                               return;
+                               return 0;
                } else if (flags == -1)
-                       return;
+                       return 0;
 



Home | Main Index | Thread Index | Old Index