From 568a64c5ecd10f0ade550bc0065a59e1b1623a59 Mon Sep 17 00:00:00 2001 From: roy Date: Mon, 27 Jan 2020 20:41:58 +0000 Subject: [PATCH] Update to dhcpcd-8.1.6 with the following changes: * INET6: Support a /128 prefix advertised via RA * BSD: More address validation from route(4) messages * DHCP: Fix a potential segfault on DaD failure * IPv4LL: Fix a potential segfault when dropping IPv4LL addresses --- external/bsd/dhcpcd/dist/src/defs.h | 2 +- external/bsd/dhcpcd/dist/src/dhcp.c | 5 +- external/bsd/dhcpcd/dist/src/if-bsd.c | 127 +++++++++++--------------- external/bsd/dhcpcd/dist/src/ipv6.c | 9 +- external/bsd/dhcpcd/dist/src/ipv6.h | 3 + external/bsd/dhcpcd/dist/src/ipv6nd.c | 3 +- external/bsd/dhcpcd/dist/src/script.c | 2 +- 7 files changed, 70 insertions(+), 81 deletions(-) diff --git a/external/bsd/dhcpcd/dist/src/defs.h b/external/bsd/dhcpcd/dist/src/defs.h index eb4b7271be8e..c7464b4dd3cf 100644 --- a/external/bsd/dhcpcd/dist/src/defs.h +++ b/external/bsd/dhcpcd/dist/src/defs.h @@ -29,7 +29,7 @@ #define CONFIG_H #define PACKAGE "dhcpcd" -#define VERSION "8.1.5" +#define VERSION "8.1.6" #ifndef CONFIG # define CONFIG SYSCONFDIR "/" PACKAGE ".conf" diff --git a/external/bsd/dhcpcd/dist/src/dhcp.c b/external/bsd/dhcpcd/dist/src/dhcp.c index ccd39b996ef1..b9757be0affc 100644 --- a/external/bsd/dhcpcd/dist/src/dhcp.c +++ b/external/bsd/dhcpcd/dist/src/dhcp.c @@ -2335,9 +2335,10 @@ dhcp_message_new(struct bootp **bootp, static void dhcp_arp_defend_failed(struct arp_state *astate) { + struct interface *ifp = astate->iface; - dhcp_drop(astate->iface, "EXPIRED"); - dhcp_start1(astate->iface); + dhcp_drop(ifp, "EXPIRED"); + dhcp_start1(ifp); } #endif diff --git a/external/bsd/dhcpcd/dist/src/if-bsd.c b/external/bsd/dhcpcd/dist/src/if-bsd.c index 9f93f66fc093..badaa1957589 100644 --- a/external/bsd/dhcpcd/dist/src/if-bsd.c +++ b/external/bsd/dhcpcd/dist/src/if-bsd.c @@ -860,8 +860,6 @@ if_address(unsigned char cmd, const struct ipv4_addr *ia) return r; } - - #if !(defined(HAVE_IFADDRS_ADDRFLAGS) && defined(HAVE_IFAM_ADDRFLAGS)) int if_addrflags(const struct interface *ifp, const struct in_addr *addr, @@ -1194,7 +1192,7 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam) { struct interface *ifp; const struct sockaddr *rti_info[RTAX_MAX]; - int addrflags; + int flags; pid_t pid; if (ifam->ifam_msglen < sizeof(*ifam)) { @@ -1216,9 +1214,6 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam) pid = 0; #endif -#ifdef HAVE_IFAM_ADDRFLAGS - addrflags = ifam->ifam_addrflags; -#endif switch (rti_info[RTAX_IFA]->sa_family) { case AF_LINK: { @@ -1252,78 +1247,70 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam) bcast.s_addr = sin != NULL && sin->sin_family == AF_INET ? sin->sin_addr.s_addr : INADDR_ANY; -#if defined(__NetBSD_Version__) && __NetBSD_Version__ < 800000000 /* * NetBSD-7 and older send an invalid broadcast address. * So we need to query the actual address to get * the right one. + * We can also use this to test if the address + * has really been added or deleted. */ - { -#else - /* - * If the address was deleted, lets check if it's - * a late message and it still exists (maybe modified). - * If so, ignore it as deleting an address causes - * dhcpcd to drop any lease to which it belongs. - */ - if (ifam->ifam_type == RTM_DELADDR) { -#endif #ifdef SIOCGIFALIAS - struct in_aliasreq ifra; + struct in_aliasreq ifra; - memset(&ifra, 0, sizeof(ifra)); - strlcpy(ifra.ifra_name, ifp->name, - sizeof(ifra.ifra_name)); - ifra.ifra_addr.sin_family = AF_INET; - ifra.ifra_addr.sin_len = sizeof(ifra.ifra_addr); - ifra.ifra_addr.sin_addr = addr; - if (ioctl(ctx->pf_inet_fd, SIOCGIFALIAS, &ifra) == -1) { - if (errno != ENXIO && errno != EADDRNOTAVAIL) - logerr("%s: SIOCGIFALIAS", __func__); - if (ifam->ifam_type != RTM_DELADDR) - break; - } + memset(&ifra, 0, sizeof(ifra)); + strlcpy(ifra.ifra_name, ifp->name, sizeof(ifra.ifra_name)); + ifra.ifra_addr.sin_family = AF_INET; + ifra.ifra_addr.sin_len = sizeof(ifra.ifra_addr); + ifra.ifra_addr.sin_addr = addr; + if (ioctl(ctx->pf_inet_fd, SIOCGIFALIAS, &ifra) == -1) { + if (errno != ENXIO && errno != EADDRNOTAVAIL) + logerr("%s: SIOCGIFALIAS", __func__); + if (ifam->ifam_type != RTM_DELADDR) + break; + } else { + if (ifam->ifam_type == RTM_DELADDR) + break; #if defined(__NetBSD_Version__) && __NetBSD_Version__ < 800000000 - else - bcast = ifra.ifra_broadaddr.sin_addr; + bcast = ifra.ifra_broadaddr.sin_addr; #endif + } #else #warning No SIOCGIFALIAS support - /* - * No SIOCGIFALIAS? That sucks! - * This makes this call very heavy weight, but we - * really need to know if the message is late or not. - */ - const struct sockaddr *sa; - struct ifaddrs *ifaddrs = NULL, *ifa; + /* + * No SIOCGIFALIAS? That sucks! + * This makes this call very heavy weight, but we + * really need to know if the message is late or not. + */ + const struct sockaddr *sa; + struct ifaddrs *ifaddrs = NULL, *ifa; - sa = rti_info[RTAX_IFA]; - getifaddrs(&ifaddrs); - for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) { - if (ifa->ifa_addr == NULL) - continue; - if (sa_cmp(ifa->ifa_addr, sa) == 0 && - strcmp(ifa->ifa_name, ifp->name) == 0) - break; - } - freeifaddrs(ifaddrs); + sa = rti_info[RTAX_IFA]; + getifaddrs(&ifaddrs); + for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) + continue; + if (sa_cmp(ifa->ifa_addr, sa) == 0 && + strcmp(ifa->ifa_name, ifp->name) == 0) + break; + } + freeifaddrs(ifaddrs); + if (ifam->ifam_type == RTM_DELADDR) { if (ifa != NULL) - return 0; + break; + } else { + if (ifa == NULL) + break; + } #endif - } -#ifndef HAVE_IFAM_ADDRFLAGS - if (ifam->ifam_type == RTM_DELADDR) - addrflags = 0 ; - else if ((addrflags = if_addrflags(ifp, &addr, NULL)) == -1) { - if (errno != EADDRNOTAVAIL) - logerr("%s: if_addrflags", __func__); - break; - } +#ifdef HAVE_IFAM_ADDRFLAGS + flags = ifam->ifam_addrflags; +#else + flags = 0; #endif ipv4_handleifa(ctx, ifam->ifam_type, NULL, ifp->name, - &addr, &mask, &bcast, addrflags, pid); + &addr, &mask, &bcast, flags, pid); break; } #endif @@ -1332,7 +1319,6 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam) { struct in6_addr addr6, mask6; const struct sockaddr_in6 *sin6; - int flags; sin6 = (const void *)rti_info[RTAX_IFA]; addr6 = sin6->sin6_addr; @@ -1344,20 +1330,17 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam) * a late message and it still exists (maybe modified). * If so, ignore it as deleting an address causes * dhcpcd to drop any lease to which it belongs. + * Also check an added address was really added. */ - if (ifam->ifam_type == RTM_DELADDR) { - flags = if_addrflags6(ifp, &addr6, NULL); - if (flags != -1) - break; - addrflags = 0; - } -#ifndef HAVE_IFAM_ADDRFLAGS - else if ((addrflags = if_addrflags6(ifp, &addr6, NULL)) == -1) { + flags = if_addrflags6(ifp, &addr6, NULL); + if (flags == -1) { if (errno != EADDRNOTAVAIL) logerr("%s: if_addrflags6", __func__); + if (ifam->ifam_type != RTM_DELADDR) + break; + flags = 0; + } else if (ifam->ifam_type == RTM_DELADDR) break; - } -#endif #ifdef __KAME__ if (IN6_IS_ADDR_LINKLOCAL(&addr6)) @@ -1366,7 +1349,7 @@ if_ifa(struct dhcpcd_ctx *ctx, const struct ifa_msghdr *ifam) #endif ipv6_handleifa(ctx, ifam->ifam_type, NULL, - ifp->name, &addr6, ipv6_prefixlen(&mask6), addrflags, pid); + ifp->name, &addr6, ipv6_prefixlen(&mask6), flags, pid); break; } #endif diff --git a/external/bsd/dhcpcd/dist/src/ipv6.c b/external/bsd/dhcpcd/dist/src/ipv6.c index 1e82cf0ca4bc..288f822a9d57 100644 --- a/external/bsd/dhcpcd/dist/src/ipv6.c +++ b/external/bsd/dhcpcd/dist/src/ipv6.c @@ -1565,7 +1565,9 @@ ipv6_newaddr(struct interface *ifp, const struct in6_addr *addr, tempaddr = false; #endif - if (ia->flags & IPV6_AF_AUTOCONF && !tempaddr) { + if (prefix_len == 128) + goto makepfx; + else if (ia->flags & IPV6_AF_AUTOCONF && !tempaddr) { ia->prefix = *addr; ia->dadcounter = ipv6_makeaddr(&ia->addr, ifp, &ia->prefix, @@ -1581,13 +1583,12 @@ ipv6_newaddr(struct interface *ifp, const struct in6_addr *addr, #else return ia; #endif - } else if (ia->flags & (IPV6_AF_REQUEST | IPV6_AF_DELEGATEDPFX) && - prefix_len != 128) - { + } else if (ia->flags & (IPV6_AF_REQUEST | IPV6_AF_DELEGATEDPFX)) { ia->prefix = *addr; cbp = inet_ntop(AF_INET6, &ia->prefix, buf, sizeof(buf)); goto paddr; } else { +makepfx: ia->addr = *addr; if (ipv6_makeprefix(&ia->prefix, &ia->addr, ia->prefix_len) == -1) diff --git a/external/bsd/dhcpcd/dist/src/ipv6.h b/external/bsd/dhcpcd/dist/src/ipv6.h index a7dc50a97031..047e4bef76a3 100644 --- a/external/bsd/dhcpcd/dist/src/ipv6.h +++ b/external/bsd/dhcpcd/dist/src/ipv6.h @@ -67,6 +67,9 @@ #define IDGEN_RETRIES 3 #define IDGEN_DELAY 1 /* second */ +/* Interface identifier length. Prefix + this == 128 for autoconf */ +#define ipv6_ifidlen(ifp) 64 + #ifndef IN6_ARE_MASKED_ADDR_EQUAL #define IN6_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \ (((d)->s6_addr32[0] ^ (a)->s6_addr32[0]) & (m)->s6_addr32[0]) == 0 && \ diff --git a/external/bsd/dhcpcd/dist/src/ipv6nd.c b/external/bsd/dhcpcd/dist/src/ipv6nd.c index 798f23b7449e..55f8c993f043 100644 --- a/external/bsd/dhcpcd/dist/src/ipv6nd.c +++ b/external/bsd/dhcpcd/dist/src/ipv6nd.c @@ -1262,7 +1262,8 @@ ipv6nd_handlera(struct dhcpcd_ctx *ctx, #ifdef IPV6_MANAGETEMPADDR /* RFC4941 Section 3.3.3 */ if (ap->flags & IPV6_AF_AUTOCONF && - ip6_use_tempaddr(ap->iface->name)) + ip6_use_tempaddr(ap->iface->name) && + ipv6_ifidlen(ap->iface) + ap->prefix_len == 128) { if (!new_ap) { if (ipv6_settemptime(ap, 1) == NULL) diff --git a/external/bsd/dhcpcd/dist/src/script.c b/external/bsd/dhcpcd/dist/src/script.c index 4d0ba447cfdc..3fdb1f6bf68d 100644 --- a/external/bsd/dhcpcd/dist/src/script.c +++ b/external/bsd/dhcpcd/dist/src/script.c @@ -453,7 +453,7 @@ make_env(const struct interface *ifp, const char *reason) dumplease: #ifdef INET #ifdef IPV4LL - if (protocol == PROTO_IPV4LL) { + if (protocol == PROTO_IPV4LL && istate) { if (ipv4ll_env(fp, istate->down ? "old" : "new", ifp) == -1) goto eexit; }