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));

Reply via email to