Source-Changes-HG archive

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

[src/netbsd-1-6]: src/dist/bind/lib/inet Pull up revision 1.2 (requested by i...



details:   https://anonhg.NetBSD.org/src/rev/5788cd9eaa81
branches:  netbsd-1-6
changeset: 528190:5788cd9eaa81
user:      lukem <lukem%NetBSD.org@localhost>
date:      Fri Jun 28 11:45:11 2002 +0000

description:
Pull up revision 1.2 (requested by itojun in ticket #387):
Update to BIND 8.3.3.  Fixes buffer overrun in resolver code.

diffstat:

 dist/bind/lib/inet/inet_net_pton.c |  274 ++++++++++++++++++++++++++++++------
 dist/bind/lib/inet/inet_network.c  |   11 +-
 2 files changed, 235 insertions(+), 50 deletions(-)

diffs (truncated from 363 to 300 lines):

diff -r dc15c2d2b362 -r 5788cd9eaa81 dist/bind/lib/inet/inet_net_pton.c
--- a/dist/bind/lib/inet/inet_net_pton.c        Fri Jun 28 11:45:03 2002 +0000
+++ b/dist/bind/lib/inet/inet_net_pton.c        Fri Jun 28 11:45:11 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: inet_net_pton.c,v 1.1.1.1 1999/11/20 18:54:08 veego Exp $      */
+/*     $NetBSD: inet_net_pton.c,v 1.1.1.1.10.1 2002/06/28 11:45:11 lukem Exp $ */
 
 /*
  * Copyright (c) 1996,1999 by Internet Software Consortium.
@@ -18,7 +18,7 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "Id: inet_net_pton.c,v 1.11 1999/01/08 19:23:44 vixie Exp";
+static const char rcsid[] = "Id: inet_net_pton.c,v 1.13 2001/09/27 15:08:38 marka Exp";
 #endif
 
 #include "port_before.h"
@@ -26,6 +26,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <arpa/nameser.h>
 #include <arpa/inet.h>
 
 #include <isc/assertions.h>
@@ -43,38 +44,6 @@
 # define SPRINTF(x) ((size_t)sprintf x)
 #endif
 
-static int     inet_net_pton_ipv4 __P((const char *src, u_char *dst,
-                                       size_t size));
-
-/*
- * static int
- * inet_net_pton(af, src, dst, size)
- *     convert network number from presentation to network format.
- *     accepts hex octets, hex strings, decimal octets, and /CIDR.
- *     "size" is in bytes and describes "dst".
- * return:
- *     number of bits, either imputed classfully or specified with /CIDR,
- *     or -1 if some failure occurred (check errno).  ENOENT means it was
- *     not a valid network specification.
- * author:
- *     Paul Vixie (ISC), June 1996
- */
-int
-inet_net_pton(af, src, dst, size)
-       int af;
-       const char *src;
-       void *dst;
-       size_t size;
-{
-       switch (af) {
-       case AF_INET:
-               return (inet_net_pton_ipv4(src, dst, size));
-       default:
-               errno = EAFNOSUPPORT;
-               return (-1);
-       }
-}
-
 /*
  * static int
  * inet_net_pton_ipv4(src, dst, size)
@@ -92,20 +61,16 @@
  *     Paul Vixie (ISC), June 1996
  */
 static int
-inet_net_pton_ipv4(src, dst, size)
-       const char *src;
-       u_char *dst;
-       size_t size;
-{
-       static const char
-               xdigits[] = "0123456789abcdef",
-               digits[] = "0123456789";
-       int n, ch, tmp, dirty, bits;
+inet_net_pton_ipv4( const char *src, u_char *dst, size_t size) {
+       static const char xdigits[] = "0123456789abcdef";
+       static const char digits[] = "0123456789";
+       int n, ch, tmp = 0, dirty, bits;
        const u_char *odst = dst;
 
        ch = *src++;
        if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
-           && isascii(src[1]) && isxdigit(src[1])) {
+           && isascii((unsigned char)(src[1]))
+           && isxdigit((unsigned char)(src[1]))) {
                /* Hexadecimal: Eat nybble string. */
                if (size <= 0)
                        goto emsgsize;
@@ -160,7 +125,8 @@
                goto enoent;
 
        bits = -1;
-       if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {
+       if (ch == '/' && isascii((unsigned char)(src[0])) &&
+           isdigit((unsigned char)(src[0])) && dst > odst) {
                /* CIDR width specifier.  Nothing can follow it. */
                ch = *src++;    /* Skip over the /. */
                bits = 0;
@@ -215,3 +181,221 @@
        errno = EMSGSIZE;
        return (-1);
 }
+
+static int
+getbits(const char *src, int *bitsp) {
+       static const char digits[] = "0123456789";
+       int n;
+       int val;
+       char ch;
+
+       val = 0;
+       n = 0;
+       while ((ch = *src++) != '\0') {
+               const char *pch;
+
+               pch = strchr(digits, ch);
+               if (pch != NULL) {
+                       if (n++ != 0 && val == 0)       /* no leading zeros */
+                               return (0);
+                       val *= 10;
+                       val += (pch - digits);
+                       if (val > 128)                  /* range */
+                               return (0);
+                       continue;
+               }
+               return (0);
+       }
+       if (n == 0)
+               return (0);
+       *bitsp = val;
+       return (1);
+}
+
+static int
+getv4(const char *src, u_char *dst, int *bitsp) {
+       static const char digits[] = "0123456789";
+       u_char *odst = dst;
+       int n;
+       u_int val;
+       char ch;
+
+       val = 0;
+       n = 0;
+       while ((ch = *src++) != '\0') {
+               const char *pch;
+
+               pch = strchr(digits, ch);
+               if (pch != NULL) {
+                       if (n++ != 0 && val == 0)       /* no leading zeros */
+                               return (0);
+                       val *= 10;
+                       val += (pch - digits);
+                       if (val > 255)                  /* range */
+                               return (0);
+                       continue;
+               }
+               if (ch == '.' || ch == '/') {
+                       if (dst - odst > 3)             /* too many octets? */
+                               return (0);
+                       *dst++ = val;
+                       if (ch == '/')
+                               return (getbits(src, bitsp));
+                       val = 0;
+                       n = 0;
+                       continue;
+               }
+               return (0);
+       }
+       if (n == 0)
+               return (0);
+       if (dst - odst > 3)             /* too many octets? */
+               return (0);
+       *dst++ = val;
+       return (1);
+}
+
+static int
+inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) {
+       static const char xdigits_l[] = "0123456789abcdef",
+                         xdigits_u[] = "0123456789ABCDEF";
+       u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+       const char *xdigits, *curtok;
+       int ch, saw_xdigit;
+       u_int val;
+       int digits;
+       int bits;
+       size_t bytes;
+       int words;
+       int ipv4;
+
+       memset((tp = tmp), '\0', NS_IN6ADDRSZ);
+       endp = tp + NS_IN6ADDRSZ;
+       colonp = NULL;
+       /* Leading :: requires some special handling. */
+       if (*src == ':')
+               if (*++src != ':')
+                       goto enoent;
+       curtok = src;
+       saw_xdigit = 0;
+       val = 0;
+       digits = 0;
+       bits = -1;
+       ipv4 = 0;
+       while ((ch = *src++) != '\0') {
+               const char *pch;
+
+               if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+                       pch = strchr((xdigits = xdigits_u), ch);
+               if (pch != NULL) {
+                       val <<= 4;
+                       val |= (pch - xdigits);
+                       if (++digits > 4)
+                               goto enoent;
+                       saw_xdigit = 1;
+                       continue;
+               }
+               if (ch == ':') {
+                       curtok = src;
+                       if (!saw_xdigit) {
+                               if (colonp)
+                                       goto enoent;
+                               colonp = tp;
+                               continue;
+                       } else if (*src == '\0')
+                               goto enoent;
+                       if (tp + NS_INT16SZ > endp)
+                               return (0);
+                       *tp++ = (u_char) (val >> 8) & 0xff;
+                       *tp++ = (u_char) val & 0xff;
+                       saw_xdigit = 0;
+                       digits = 0;
+                       val = 0;
+                       continue;
+               }
+               if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+                    getv4(curtok, tp, &bits) > 0) {
+                       tp += NS_INADDRSZ;
+                       saw_xdigit = 0;
+                       ipv4 = 1;
+                       break;  /* '\0' was seen by inet_pton4(). */
+               }
+               if (ch == '/' && getbits(src, &bits) > 0)
+                       break;
+               goto enoent;
+       }
+       if (saw_xdigit) {
+               if (tp + NS_INT16SZ > endp)
+                       goto enoent;
+               *tp++ = (u_char) (val >> 8) & 0xff;
+               *tp++ = (u_char) val & 0xff;
+       }
+       if (bits == -1)
+               bits = 128;
+
+       words = (bits + 15) / 16;
+       if (words < 2)
+               words = 2;
+       if (ipv4)
+               words = 8;
+       endp =  tmp + 2 * words;
+
+       if (colonp != NULL) {
+               /*
+                * Since some memmove()'s erroneously fail to handle
+                * overlapping regions, we'll do the shift by hand.
+                */
+               const int n = tp - colonp;
+               int i;
+
+               if (tp == endp)
+                       goto enoent;
+               for (i = 1; i <= n; i++) {
+                       endp[- i] = colonp[n - i];
+                       colonp[n - i] = 0;
+               }
+               tp = endp;
+       }
+       if (tp != endp)
+               goto enoent;
+
+       bytes = (bits + 7) / 8;
+       if (bytes > size)
+               goto emsgsize;
+       memcpy(dst, tmp, bytes);
+       return (bits);
+
+ enoent:
+       errno = ENOENT;
+       return (-1);
+
+ emsgsize:
+       errno = EMSGSIZE;
+       return (-1);
+}
+
+/*



Home | Main Index | Thread Index | Old Index