Module Name: src Committed By: roy Date: Wed Aug 21 17:12:19 UTC 2019
Modified Files: src/external/bsd/dhcpcd/dist/src: bpf.c dhcp.c dhcpcd.c if-bsd.c if-options.c ipv6.h Log Message: Sync To generate a diff of this commit: cvs rdiff -u -r1.11 -r1.12 src/external/bsd/dhcpcd/dist/src/bpf.c cvs rdiff -u -r1.23 -r1.24 src/external/bsd/dhcpcd/dist/src/dhcp.c \ src/external/bsd/dhcpcd/dist/src/dhcpcd.c cvs rdiff -u -r1.10 -r1.11 src/external/bsd/dhcpcd/dist/src/if-bsd.c cvs rdiff -u -r1.16 -r1.17 src/external/bsd/dhcpcd/dist/src/if-options.c cvs rdiff -u -r1.3 -r1.4 src/external/bsd/dhcpcd/dist/src/ipv6.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/bsd/dhcpcd/dist/src/bpf.c diff -u src/external/bsd/dhcpcd/dist/src/bpf.c:1.11 src/external/bsd/dhcpcd/dist/src/bpf.c:1.12 --- src/external/bsd/dhcpcd/dist/src/bpf.c:1.11 Tue Jul 30 10:25:03 2019 +++ src/external/bsd/dhcpcd/dist/src/bpf.c Wed Aug 21 17:12:19 2019 @@ -558,6 +558,15 @@ bpf_arp(struct interface *ifp, int fd) #define BPF_M_UDP 3 #define BPF_M_UDPLEN 4 +#ifdef ARPHRD_NONE +static const struct bpf_insn bpf_bootp_none[] = { + /* Set the frame header length to zero. */ + BPF_STMT(BPF_LD + BPF_IMM, 0), + BPF_STMT(BPF_ST, BPF_M_FHLEN), +}; +#define BPF_BOOTP_NONE_LEN __arraycount(bpf_bootp_none) +#endif + static const struct bpf_insn bpf_bootp_ether[] = { /* Make sure this is an IP packet. */ BPF_STMT(BPF_LD + BPF_H + BPF_ABS, @@ -665,6 +674,12 @@ bpf_bootp(struct interface *ifp, int fd) bp = bpf; /* Check frame header. */ switch(ifp->family) { +#ifdef ARPHRD_NONE + case ARPHRD_NONE: + memcpy(bp, bpf_bootp_none, sizeof(bpf_bootp_none)); + bp += BPF_BOOTP_NONE_LEN; + break; +#endif case ARPHRD_ETHER: memcpy(bp, bpf_bootp_ether, sizeof(bpf_bootp_ether)); bp += BPF_BOOTP_ETHER_LEN; Index: src/external/bsd/dhcpcd/dist/src/dhcp.c diff -u src/external/bsd/dhcpcd/dist/src/dhcp.c:1.23 src/external/bsd/dhcpcd/dist/src/dhcp.c:1.24 --- src/external/bsd/dhcpcd/dist/src/dhcp.c:1.23 Tue Jul 30 10:25:03 2019 +++ src/external/bsd/dhcpcd/dist/src/dhcp.c Wed Aug 21 17:12:19 2019 @@ -1584,24 +1584,24 @@ eexit: } static uint16_t -checksum(const void *data, size_t len) +in_cksum(void *data, size_t len, uint32_t *isum) { - const uint8_t *addr = data; - uint32_t sum = 0; + const uint16_t *word = data; + uint32_t sum = isum != NULL ? *isum : 0; - while (len > 1) { - sum += (uint32_t)(addr[0] * 256 + addr[1]); - addr += 2; - len -= 2; - } + for (; len > 1; len -= sizeof(*word)) + sum += *word++; if (len == 1) - sum += (uint32_t)(*addr * 256); + sum += *(const uint8_t *)word; + + if (isum != NULL) + *isum = sum; sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); - return (uint16_t)~htons((uint16_t)sum); + return (uint16_t)~sum; } static struct bootp_pkt * @@ -1639,14 +1639,16 @@ dhcp_makeudppacket(size_t *sz, const uin udp->uh_dport = htons(BOOTPS); udp->uh_ulen = htons((uint16_t)(sizeof(*udp) + length)); ip->ip_len = udp->uh_ulen; - udp->uh_sum = checksum(udpp, sizeof(*ip) + sizeof(*udp) + length); + udp->uh_sum = in_cksum(udpp, sizeof(*ip) + sizeof(*udp) + length, NULL); ip->ip_v = IPVERSION; ip->ip_hl = sizeof(*ip) >> 2; ip->ip_id = (uint16_t)arc4random_uniform(UINT16_MAX); ip->ip_ttl = IPDEFTTL; ip->ip_len = htons((uint16_t)(sizeof(*ip) + sizeof(*udp) + length)); - ip->ip_sum = checksum(ip, sizeof(*ip)); + ip->ip_sum = in_cksum(ip, sizeof(*ip), NULL); + if (ip->ip_sum == 0) + ip->ip_sum = 0xffff; /* RFC 768 */ *sz = sizeof(*ip) + sizeof(*udp) + length; return udpp; @@ -2363,7 +2365,10 @@ dhcp_arp_address(struct interface *ifp) return 0; } #else - if (ifp->options->options & DHCPCD_ARP && ia == NULL) { + if (!(ifp->flags & IFF_NOARP) && + ifp->options->options & DHCPCD_ARP && + ia == NULL) + { struct arp_state *astate; struct dhcp_lease l; @@ -3236,10 +3241,15 @@ valid_udp_packet(void *packet, size_t pl unsigned int flags) { struct ip *ip = packet; - char ip_hlv = *(char *)ip; + struct ip pseudo_ip = { + .ip_p = IPPROTO_UDP, + .ip_src = ip->ip_src, + .ip_dst = ip->ip_dst + }; size_t ip_hlen; uint16_t ip_len, uh_sum; struct udphdr *udp; + uint32_t csum; if (plen < sizeof(*ip)) { if (from != NULL) @@ -3252,13 +3262,13 @@ valid_udp_packet(void *packet, size_t pl from->s_addr = ip->ip_src.s_addr; ip_hlen = (size_t)ip->ip_hl * 4; - if (checksum(ip, ip_hlen) != 0) { + if (in_cksum(ip, ip_hlen, NULL) != 0) { errno = EINVAL; return -1; } - ip_len = ntohs(ip->ip_len); /* Check we have a payload */ + ip_len = ntohs(ip->ip_len); if (ip_len <= ip_hlen + sizeof(*udp)) { errno = ERANGE; return -1; @@ -3272,28 +3282,21 @@ valid_udp_packet(void *packet, size_t pl if (flags & BPF_PARTIALCSUM) return 0; - udp = (struct udphdr *)((char *)ip + ip_hlen); + /* UDP checksum is based on a pseudo IP header alongside + * the UDP header and payload. */ + udp = (struct udphdr *)(void *)((char *)ip + ip_hlen); if (udp->uh_sum == 0) return 0; - uh_sum = udp->uh_sum; - /* This does scribble on the packet, but at this point - * we don't care to keep it. */ + uh_sum = udp->uh_sum; udp->uh_sum = 0; - ip->ip_hl = 0; - ip->ip_v = 0; - ip->ip_tos = 0; - ip->ip_len = udp->uh_ulen; - ip->ip_id = 0; - ip->ip_off = 0; - ip->ip_ttl = 0; - ip->ip_sum = 0; - if (checksum(packet, ip_len) != uh_sum) { + pseudo_ip.ip_len = udp->uh_ulen; + csum = 0; + in_cksum(&pseudo_ip, sizeof(pseudo_ip), &csum); + if (in_cksum(udp, ntohs(udp->uh_ulen), &csum) != uh_sum) { errno = EINVAL; return -1; } - *(char *)ip = ip_hlv; - ip->ip_len = htons(ip_len); return 0; } @@ -3339,12 +3342,6 @@ dhcp_handlepacket(struct interface *ifp, ifp->name, inet_ntoa(from)); return; } - if (ifp->flags & IFF_POINTOPOINT && - (state->addr == NULL || state->addr->brd.s_addr != from.s_addr)) - { - logwarnx("%s: server %s is not destination", - ifp->name, inet_ntoa(from)); - } /* * DHCP has a variable option area rather than a fixed vendor area. @@ -3721,12 +3718,6 @@ dhcp_start1(void *arg) return; } - if (ifp->hwlen == 0 && ifo->clientid[0] == '\0') { - logwarnx("%s: needs a clientid to configure", ifp->name); - dhcp_drop(ifp, "FAIL"); - eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); - return; - } /* We don't want to read the old lease if we NAK an old test */ nolease = state->offer && ifp->ctx->options & DHCPCD_TEST; if (!nolease && ifo->options & DHCPCD_DHCP) { Index: src/external/bsd/dhcpcd/dist/src/dhcpcd.c diff -u src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.23 src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.24 --- src/external/bsd/dhcpcd/dist/src/dhcpcd.c:1.23 Tue Jul 30 10:25:03 2019 +++ src/external/bsd/dhcpcd/dist/src/dhcpcd.c Wed Aug 21 17:12:19 2019 @@ -458,11 +458,10 @@ configure_interface1(struct interface *i ifo->options &= ~DHCPCD_ARP; if (!(ifp->flags & IFF_MULTICAST)) ifo->options &= ~DHCPCD_IPV6RS; - if (!(ifo->options & DHCPCD_INFORM)) + if (!(ifo->options & (DHCPCD_INFORM | DHCPCD_WANTDHCP))) ifo->options |= DHCPCD_STATIC; } - if (ifp->flags & IFF_NOARP || - !(ifo->options & DHCPCD_ARP) || + if (!(ifo->options & DHCPCD_ARP) || ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)) ifo->options &= ~DHCPCD_IPV4LL; @@ -1440,10 +1439,10 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx * write callback on the fd */ if (strcmp(*argv, "--version") == 0) { return control_queue(fd, UNCONST(VERSION), - strlen(VERSION) + 1, 0); + strlen(VERSION) + 1, false); } else if (strcmp(*argv, "--getconfigfile") == 0) { return control_queue(fd, UNCONST(fd->ctx->cffile), - strlen(fd->ctx->cffile) + 1, 0); + strlen(fd->ctx->cffile) + 1, false); } else if (strcmp(*argv, "--getinterfaces") == 0) { eloop_event_add_w(fd->ctx->eloop, fd->fd, dhcpcd_getinterfaces, fd); Index: src/external/bsd/dhcpcd/dist/src/if-bsd.c diff -u src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.10 src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.11 --- src/external/bsd/dhcpcd/dist/src/if-bsd.c:1.10 Tue Jul 30 10:25:03 2019 +++ src/external/bsd/dhcpcd/dist/src/if-bsd.c Wed Aug 21 17:12:19 2019 @@ -191,6 +191,8 @@ if_opensockets_os(struct dhcpcd_ctx *ctx if (setsockopt(ctx->link_fd, PF_ROUTE, ROUTE_MSGFILTER, &msgfilter_mask, sizeof(msgfilter_mask)) == -1) logerr(__func__); +#else +#warning kernel does not support route message filtering #endif return 0; @@ -660,11 +662,8 @@ if_copyrt(struct dhcpcd_ctx *ctx, struct } #endif - /* 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) + if (get_addrs(rtm->rtm_addrs, (const char *)rtm + sizeof(*rtm), + rtm->rtm_msglen - sizeof(*rtm), rti_info) == -1) return -1; memset(rt, 0, sizeof(*rt)); @@ -1115,10 +1114,7 @@ if_ifa(struct dhcpcd_ctx *ctx, const str if ((ifp = if_findindex(ctx->ifaces, ifam->ifam_index)) == NULL) 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, + if (get_addrs(ifam->ifam_addrs, (const char *)ifam + sizeof(*ifam), ifam->ifam_msglen - sizeof(*ifam), rti_info) == -1) return -1; @@ -1314,32 +1310,41 @@ if_dispatch(struct dhcpcd_ctx *ctx, cons #ifdef RTM_DESYNC case RTM_DESYNC: dhcpcd_linkoverflow(ctx); +#elif !defined(SO_RERROR) +#warning cannot detect route socket overflow within kernel #endif } return 0; } +__CTASSERT(offsetof(struct rt_msghdr, rtm_msglen) == 0); int if_handlelink(struct dhcpcd_ctx *ctx) { struct rtm rtm; - struct iovec iov = { .iov_base = &rtm, .iov_len = sizeof(rtm) }; - struct msghdr msg = { .msg_iov = &iov, .msg_iovlen = 1 }; ssize_t len; - len = recvmsg(ctx->link_fd, &msg, 0); + len = read(ctx->link_fd, &rtm, sizeof(rtm)); if (len == -1) return -1; if (len == 0) return 0; - if (len < rtm.hdr.rtm_msglen) { + if ((size_t)len < sizeof(rtm.hdr.rtm_msglen) || + len != rtm.hdr.rtm_msglen) + { errno = EINVAL; return -1; } - /* We generally treat rtm.hdr has an array so we can easily - * access the following data. */ - /* coverity[callee_ptr_arith] */ + /* + * Coverity thinks that the data could be tainted from here. + * I have no idea how because the length of the data we read + * is guarded by len and checked to match rtm_msglen. + * The issue seems to be related to extracting the addresses + * at the end of the header, but seems to have no issues with the + * equivalent call in if_initrt. + */ + /* coverity[tainted_data] */ return if_dispatch(ctx, &rtm.hdr); } Index: src/external/bsd/dhcpcd/dist/src/if-options.c diff -u src/external/bsd/dhcpcd/dist/src/if-options.c:1.16 src/external/bsd/dhcpcd/dist/src/if-options.c:1.17 --- src/external/bsd/dhcpcd/dist/src/if-options.c:1.16 Tue Jul 30 10:25:03 2019 +++ src/external/bsd/dhcpcd/dist/src/if-options.c Wed Aug 21 17:12:19 2019 @@ -2062,7 +2062,7 @@ err_sla: ifo->auth.options &= ~DHCPCD_AUTH_REQUIRE; break; case O_DHCP: - ifo->options |= DHCPCD_DHCP | DHCPCD_IPV4; + ifo->options |= DHCPCD_DHCP | DHCPCD_WANTDHCP | DHCPCD_IPV4; break; case O_NODHCP: ifo->options &= ~DHCPCD_DHCP; @@ -2281,7 +2281,7 @@ default_config(struct dhcpcd_ctx *ctx) ifo->script = UNCONST(default_script); ifo->metric = -1; ifo->auth.options |= DHCPCD_AUTH_REQUIRE; - rb_tree_init(&ifo->routes, &rt_compare_proto_ops); + rb_tree_init(&ifo->routes, &rt_compare_list_ops); #ifdef AUTH TAILQ_INIT(&ifo->auth.tokens); #endif Index: src/external/bsd/dhcpcd/dist/src/ipv6.h diff -u src/external/bsd/dhcpcd/dist/src/ipv6.h:1.3 src/external/bsd/dhcpcd/dist/src/ipv6.h:1.4 --- src/external/bsd/dhcpcd/dist/src/ipv6.h:1.3 Tue Jul 30 10:25:03 2019 +++ src/external/bsd/dhcpcd/dist/src/ipv6.h Wed Aug 21 17:12:19 2019 @@ -100,7 +100,8 @@ #endif /* This was fixed in NetBSD */ -#if defined(__NetBSD_Version__) && __NetBSD_Version__ >= 699002000 +#if (defined(__DragonFly_version) && __DragonFly_version >= 500704) || \ + (defined(__NetBSD_Version__) && __NetBSD_Version__ >= 699002000) # undef IPV6_POLLADDRFLAG #endif @@ -153,9 +154,12 @@ * ND6 Advertising is only used for IP address sharing to prefer * the address on a specific interface. * This just fails to work on OpenBSD and causes erroneous duplicate - * address messages on BSD's other then NetBSD. + * address messages on BSD's other then DragonFly and NetBSD. */ -#if !defined(SMALL) && (defined(__NetBSD__) || defined(__linux__)) +#if !defined(SMALL) && \ + ((defined(__DragonFly_version) && __DragonFly_version >= 500703) || \ + (defined(__NetBSD_Version__) && __NetBSD_Version__ >= 899002800) || \ + defined(__linux__)) # define ND6_ADVERTISE #endif