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