changeset 1866:6aa0c2598a20 draft

Avoid a potential buffer overflow.
author Roy Marples <roy@marples.name>
date Tue, 19 Feb 2013 16:22:04 +0000
parents efadc01f51dd
children 1dcf847ba8f1
files arp.c
diffstat 1 files changed, 25 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/arp.c	Tue Feb 19 16:05:12 2013 +0000
+++ b/arp.c	Tue Feb 19 16:22:04 2013 +0000
@@ -52,28 +52,37 @@
 	struct arphdr ar;
 	size_t len;
 	uint8_t *p;
-	int retval;
 
 	ar.ar_hrd = htons(ifp->family);
 	ar.ar_pro = htons(ETHERTYPE_IP);
 	ar.ar_hln = ifp->hwlen;
 	ar.ar_pln = sizeof(sip);
 	ar.ar_op = htons(op);
-	memcpy(arp_buffer, &ar, sizeof(ar));
-	p = arp_buffer + sizeof(ar);
-	memcpy(p, ifp->hwaddr, ifp->hwlen);
-	p += ifp->hwlen;
-	memcpy(p, &sip, sizeof(sip));
-	p += sizeof(sip);
-	/* ARP requests should ignore this */
-	retval = ifp->hwlen;
-	while (retval--)
-		*p++ = '\0';
-	memcpy(p, &tip, sizeof(tip));
-	p += sizeof(tip);
-	len = p - arp_buffer;
-	retval = ipv4_sendrawpacket(ifp, ETHERTYPE_ARP, arp_buffer, len);
-	return retval;
+
+	p = arp_buffer;
+	len = sizeof(arp_buffer);
+
+#define CHECK(fun, b, l)						\
+	do {								\
+		if (len < (l))						\
+			goto eexit;					\
+		fun(p, (b), (l));					\
+		p += (l);						\
+		len -= (l);						\
+	} while (/* CONSTCOND */ 0)
+#define APPEND(b, l)	CHECK(memcpy, b, l)
+#define ZERO(l)		CHECK(memset, 0, l)
+
+	APPEND(&ar, sizeof(ar));
+	APPEND(ifp->hwaddr, ifp->hwlen);
+	APPEND(&sip, sizeof(sip));
+	ZERO(ifp->hwlen);
+	APPEND(&tip, sizeof(tip));
+	return ipv4_sendrawpacket(ifp, ETHERTYPE_ARP, arp_buffer, len);
+
+eexit:
+	errno = ENOSPC;
+	return -1;
 }
 
 static void