DragonFlyBSD Kernel Audit
DF-0494 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index 0000000..1111111 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -658,6 +658,19 @@
 	switch (ntohs(ar->ar_pro)) {
 #ifdef INET
 	case ETHERTYPE_IP:
+		/*
+		 * Reject ARP with bogus hardware/protocol address lengths.
+		 * For Ethernet/IPv4 ARP these MUST equal the receiving
+		 * interface link-layer address length and sizeof(struct
+		 * in_addr); otherwise in_arpinput()/in_arpreply() use
+		 * ar_hln/ar_pln as memcpy lengths and over-read kernel
+		 * heap/stack memory into the ARP reply (OOB read, DF-0494).
+		 */
+		if (ar->ar_hln != m->m_pkthdr.rcvif->if_addrlen ||
+		    ar->ar_pln != sizeof(struct in_addr)) {
+			m_freem(m);
+			return;
+		}
 		in_arpinput(m);
 		return;
 #endif