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
 

Reply via email to