⬢ DragonFlyBSD Kernel Audit
DF-3357 / fix.diff
← back to finding ↓ download raw
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1013,6 +1013,22 @@
 			goto release;
 		}
 		sin = (struct sockaddr_in *)dstaddr;
+		/*
+		 * Validate the destination sockaddr BEFORE using any field
+		 * beyond sa_family.  in_pcbladdr_find() performs these same
+		 * checks, but it is only called when the local address is
+		 * INADDR_ANY or multicast; a socket bound to a specific
+		 * address would otherwise read sin_port/sin_addr past a
+		 * sockaddr that can be as short as 2 bytes.
+		 */
+		if (sin->sin_len != sizeof(*sin)) {
+			error = EINVAL;
+			goto release;
+		}
+		if (sin->sin_family != AF_INET) {
+			error = EAFNOSUPPORT;
+			goto release;
+		}
 	} else {
 		if (inp->inp_faddr.s_addr == INADDR_ANY) {
 			/* no destination specified and not already connected */