NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/47502: avoid possible buffer overflow in dhcpcd.



>Number:         47502
>Category:       bin
>Synopsis:       possible buffer overflow in dhcpcd.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jan 24 18:10:00 +0000 2013
>Originator:     Christos Zoulas
>Release:        NetBSD 5.99.59
>Organization:
        Irrational Thinking, LLC
>Environment:
System: NetBSD rebar.astron.com 5.99.59 NetBSD 5.99.59 (GENERIC) #7: Fri Dec 30 
15:19:49 EST 2011 
christos%rebar.astron.com@localhost:/usr/src/sys/arch/amd64/compile/GENERIC 
amd64
Architecture: x86_64
Machine: amd64
>Description:
        The arp buffer is fixed length and iface->hwlen is not checked here.
        
>How-To-Repeat:
        inspect code.
>Fix:
Index: arp.c
===================================================================
RCS file: /cvsroot/src/external/bsd/dhcpcd/dist/arp.c,v
retrieving revision 1.1.1.8
diff -u -u -r1.1.1.8 arp.c
--- arp.c       25 Jan 2012 14:33:03 -0000      1.1.1.8
+++ arp.c       24 Jan 2013 18:04:56 -0000
@@ -51,28 +51,39 @@
        struct arphdr ar;
        size_t len;
        uint8_t *p;
-       int retval;
 
        ar.ar_hrd = htons(iface->family);
        ar.ar_pro = htons(ETHERTYPE_IP);
        ar.ar_hln = iface->hwlen;
        ar.ar_pln = sizeof(sip);
        ar.ar_op = htons(op);
-       memcpy(arp_buffer, &ar, sizeof(ar));
-       p = arp_buffer + sizeof(ar);
-       memcpy(p, iface->hwaddr, iface->hwlen);
-       p += iface->hwlen;
-       memcpy(p, &sip, sizeof(sip));
-       p += sizeof(sip);
+
+       p = arp_buffer;
+       len = sizeof(arp_buffer);
+
+#define CHECK(fun, b, l) \
+       do { \
+               if (len < (l)) \
+                       goto out; \
+               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(iface->hwaddr, iface->hwlen);
+       APPEND(&sip, sizeof(sip));
        /* ARP requests should ignore this */
-       retval = iface->hwlen;
-       while (retval--)
-               *p++ = '\0';
-       memcpy(p, &tip, sizeof(tip));
-       p += sizeof(tip);
+       ZERO(iface->hwlen);
+       APPEND(&tip, sizeof(tip));
        len = p - arp_buffer;
-       retval = send_raw_packet(iface, ETHERTYPE_ARP, arp_buffer, len);
-       return retval;
+       return send_raw_packet(iface, ETHERTYPE_ARP, arp_buffer, len);
+out:
+       errno = ENOSPC;
+       return -1;
 }
 
 static void



Home | Main Index | Thread Index | Old Index