Source-Changes-HG archive

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

[src/trunk]: src/lib/libc/net Fix buffer copy without checking the size of in...



details:   https://anonhg.NetBSD.org/src/rev/2ee61891ed77
branches:  trunk
changeset: 819467:2ee61891ed77
user:      christos <christos%NetBSD.org@localhost>
date:      Tue Dec 06 18:41:02 2016 +0000

description:
Fix buffer copy without checking the size of input:
https://www.kb.cert.org/vuls/id/548487

diffstat:

 lib/libc/net/linkaddr.c |  31 ++++++++++++++++++++-----------
 1 files changed, 20 insertions(+), 11 deletions(-)

diffs (78 lines):

diff -r 75b8bebb160e -r 2ee61891ed77 lib/libc/net/linkaddr.c
--- a/lib/libc/net/linkaddr.c   Tue Dec 06 15:09:04 2016 +0000
+++ b/lib/libc/net/linkaddr.c   Tue Dec 06 18:41:02 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linkaddr.c,v 1.16 2012/03/20 17:44:18 matt Exp $       */
+/*     $NetBSD: linkaddr.c,v 1.17 2016/12/06 18:41:02 christos Exp $   */
 
 /*-
  * Copyright (c) 1990, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)linkaddr.c 8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: linkaddr.c,v 1.16 2012/03/20 17:44:18 matt Exp $");
+__RCSID("$NetBSD: linkaddr.c,v 1.17 2016/12/06 18:41:02 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -59,7 +59,7 @@
 void
 link_addr(const char *addr, struct sockaddr_dl *sdl)
 {
-       register char *cp = sdl->sdl_data;
+       char *cp = sdl->sdl_data;
        char *cplim = sdl->sdl_len + (char *)(void *)sdl;
        int byte = 0, state = NAMING;
        size_t newaddr = 0;     /* pacify gcc */
@@ -138,33 +138,42 @@
 link_ntoa(const struct sockaddr_dl *sdl)
 {
        static char obuf[64];
-       register char *out = obuf; 
-       register size_t i;
+       char *out = obuf; 
+       size_t i;
        const u_char *in = (const u_char *)CLLADDR(sdl);
        const u_char *inlim = in + sdl->sdl_alen;
        int firsttime = 1;
 
        _DIAGASSERT(sdl != NULL);
 
+#define ADDC(ch) \
+       do { \
+               if (out >= obuf + sizeof(obuf)) \
+                       return NULL; \
+               *out++ = (ch); \
+       } while (/*CONSTCOND*/0)
+
        if (sdl->sdl_nlen) {
+               if (sdl->sdl_nlen >= sizeof(obuf))
+                       return NULL;
                (void)memcpy(obuf, sdl->sdl_data, (size_t)sdl->sdl_nlen);
                out += sdl->sdl_nlen;
                if (sdl->sdl_alen)
-                       *out++ = ':';
+                       ADDC(':');
        }
        while (in < inlim) {
                if (firsttime)
                        firsttime = 0;
                else
-                       *out++ = '.';
+                       ADDC('.');
                i = *in++;
                if (i > 0xf) {
-                       out[1] = hexlist[i & 0xf];
+                       size_t j = i & 0xf;
                        i >>= 4;
-                       out[0] = hexlist[i];
-                       out += 2;
+                       ADDC(hexlist[i]);
+                       ADDC(hexlist[j]);
                } else
-                       *out++ = hexlist[i];
+                       ADDC(hexlist[i]);
        }
        *out = 0;
        return (obuf);



Home | Main Index | Thread Index | Old Index