Module Name: src Committed By: snj Date: Sun Feb 5 19:20:23 UTC 2017
Modified Files: src/sys/netinet [netbsd-7]: if_arp.c Log Message: Pull up following revision(s) (requested by maxv in ticket #1356): sys/netinet/if_arp.c: revision 1.238, 1.239 via patch Make sure the protocol address length equals that of IPv4. Also, make sure the hardware address length equals that of the interface we received the packet on. Otherwise a packet could easily set them both to zero and make the kernel read beyond the allocated mbuf, which is terrible. Note: for the latter we drop the packet instead of replying, since it is malformed. Note: I also added an ugly hack in CARP, since it apparently expects at least six bytes. -- Add some checks, mostly same as in_arpinput. To generate a diff of this commit: cvs rdiff -u -r1.158.2.1 -r1.158.2.2 src/sys/netinet/if_arp.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netinet/if_arp.c diff -u src/sys/netinet/if_arp.c:1.158.2.1 src/sys/netinet/if_arp.c:1.158.2.2 --- src/sys/netinet/if_arp.c:1.158.2.1 Fri Nov 6 00:46:50 2015 +++ src/sys/netinet/if_arp.c Sun Feb 5 19:20:22 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: if_arp.c,v 1.158.2.1 2015/11/06 00:46:50 riz Exp $ */ +/* $NetBSD: if_arp.c,v 1.158.2.2 2017/02/05 19:20:22 snj Exp $ */ /*- * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.158.2.1 2015/11/06 00:46:50 riz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.158.2.2 2017/02/05 19:20:22 snj Exp $"); #include "opt_ddb.h" #include "opt_inet.h" @@ -974,6 +974,9 @@ in_arpinput(struct mbuf *m) break; } + if (ah->ar_pln != sizeof(struct in_addr)) + goto out; + memcpy(&isaddr, ar_spa(ah), sizeof (isaddr)); memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr)); @@ -1004,7 +1007,10 @@ in_arpinput(struct mbuf *m) ((ia->ia_ifp->if_flags & (IFF_UP|IFF_RUNNING)) == (IFF_UP|IFF_RUNNING))) { index++; + + /* XXX: ar_hln? */ if (ia->ia_ifp == m->m_pkthdr.rcvif && + (ah->ar_hln >= 6) && carp_iamatch(ia, ar_sha(ah), &count, index)) { break; @@ -1036,6 +1042,14 @@ in_arpinput(struct mbuf *m) } #endif + if (ah->ar_hln != ifp->if_addrlen) { + ARP_STATINC(ARP_STAT_RCVBADLEN); + log(LOG_WARNING, + "arp from %s: addr len: new %d, i/f %d (ignored)\n", + in_fmtaddr(isaddr), ah->ar_hln, ifp->if_addrlen); + goto out; + } + if (ia == NULL) { INADDR_TO_IA(isaddr, ia); while ((ia != NULL) && ia->ia_ifp != m->m_pkthdr.rcvif) @@ -1130,14 +1144,7 @@ in_arpinput(struct mbuf *m) "arp from %s: new addr len %d, was %d\n", in_fmtaddr(isaddr), ah->ar_hln, sdl->sdl_alen); } - if (ifp->if_addrlen != ah->ar_hln) { - ARP_STATINC(ARP_STAT_RCVBADLEN); - log(LOG_WARNING, - "arp from %s: addr len: new %d, i/f %d (ignored)\n", - in_fmtaddr(isaddr), ah->ar_hln, - ifp->if_addrlen); - goto reply; - } + #if NTOKEN > 0 /* * XXX uses m_data and assumes the complete answer including @@ -1436,6 +1443,10 @@ in_revarpinput(struct mbuf *m) tha = ar_tha(ah); if (tha == NULL) goto out; + if (ah->ar_pln != sizeof(struct in_addr)) + goto out; + if (ah->ar_hln != ifp->if_sadl->sdl_alen) + goto out; if (memcmp(tha, CLLADDR(ifp->if_sadl), ifp->if_sadl->sdl_alen)) goto out; memcpy(&srv_ip, ar_spa(ah), sizeof(srv_ip));