⬢ DragonFlyBSD Kernel Audit
DF-3318 / fix.diff
← back to finding ↓ download raw
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -900,6 +900,18 @@
 	 */
 	if (ifra->ifra_prefixmask.sin6_len > sizeof(struct sockaddr_in6))
 		return (EINVAL);
+
+	/*
+	 * Validate ifra_dstaddr length.  The kernel keeps copying the
+	 * whole sockaddr_in6 -- including the bogus sin6_len -- into
+	 * ia->ia_dstaddr, and in6_lifaddr_ioctl() later uses
+	 * ia_dstaddr.sin6_len as a bcopy() length (SIOCGLIFADDR /
+	 * SIOCDLIFADDR), causing an out-of-bounds read past the
+	 * in6_ifaddr allocation and an out-of-bounds write past the
+	 * 128-byte on-stack struct in6_aliasreq.
+	 */
+	if (ifra->ifra_dstaddr.sin6_len > sizeof(struct sockaddr_in6))
+		return (EINVAL);
 	/*
 	 * Because the IPv6 address architecture is classless, we require
 	 * users to specify a (non 0) prefix length (mask) for a new address.