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/irs Pull up revision 1.4 (requested by it...



details:   https://anonhg.NetBSD.org/src/rev/d8abeda9df30
branches:  netbsd-1-6
changeset: 528204:d8abeda9df30
user:      lukem <lukem%NetBSD.org@localhost>
date:      Fri Jun 28 11:48:20 2002 +0000

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

diffstat:

 dist/bind/lib/irs/gethostent.c |  246 +++++++++++++++++++++++++++++++++--------
 1 files changed, 198 insertions(+), 48 deletions(-)

diffs (truncated from 354 to 300 lines):

diff -r ffb0cbf57737 -r d8abeda9df30 dist/bind/lib/irs/gethostent.c
--- a/dist/bind/lib/irs/gethostent.c    Fri Jun 28 11:48:02 2002 +0000
+++ b/dist/bind/lib/irs/gethostent.c    Fri Jun 28 11:48:20 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: gethostent.c,v 1.3 2001/05/17 23:00:19 itojun Exp $    */
+/*     $NetBSD: gethostent.c,v 1.3.2.1 2002/06/28 11:48:20 lukem Exp $ */
 
 /*
  * Copyright (c) 1996-1999 by Internet Software Consortium.
@@ -18,7 +18,7 @@
  */
 
 #if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "Id: gethostent.c,v 1.28 2001/03/01 05:47:44 marka Exp";
+static const char rcsid[] = "Id: gethostent.c,v 1.32 2002/05/27 06:50:55 marka Exp";
 #endif
 
 /* Imports */
@@ -217,10 +217,6 @@
                (*ho->minimize)(ho);
 }
 
-#if !defined(HAS_INET6_STRUCTS) || defined(MISSING_IN6ADDR_ANY)
-static const struct in6_addr in6addr_any;
-#endif
-
 #ifndef IN6_IS_ADDR_V4COMPAT
 static const unsigned char in6addr_compat[12] = {
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -301,7 +297,7 @@
                char *addr_list[2];
                char *aliases[1];
 
-               he.h_name = (char *)name;
+               DE_CONST(name, he.h_name);
                he.h_addr_list = addr_list;
                he.h_addr_list[0] = (v4 == 1) ? (char *)&in4 : (char *)&in6;
                he.h_addr_list[1] = NULL;
@@ -381,8 +377,10 @@
        /*
         * Lookup IPv4 and IPv4 mapped/compatible addresses
         */
-       if ((af == AF_INET6 && IN6_IS_ADDR_V4COMPAT((struct in6_addr *)src)) ||
-           (af == AF_INET6 && IN6_IS_ADDR_V4MAPPED((struct in6_addr *)src)) ||
+       if ((af == AF_INET6 &&
+            IN6_IS_ADDR_V4COMPAT((const struct in6_addr *)src)) ||
+           (af == AF_INET6 &&
+            IN6_IS_ADDR_V4MAPPED((const struct in6_addr *)src)) ||
            (af == AF_INET)) {
                const char *cp = src;
 
@@ -407,7 +405,7 @@
        /*
         * Lookup IPv6 address.
         */
-       if (memcmp((struct in6_addr *)src, &in6addr_any, 16) == 0) {
+       if (memcmp((const struct in6_addr *)src, &in6addr_any, 16) == 0) {
                *error_num = HOST_NOT_FOUND;
                return (NULL);
        }
@@ -462,45 +460,45 @@
  *     -1 on failure.
  */
 
-static int
-scan_interfaces(int *have_v4, int *have_v6) {
-#ifndef SIOCGLIFCONF
-/* map new to old */
-#define SIOCGLIFCONF SIOCGIFCONF
-#define lifc_len ifc_len
-#define lifc_buf ifc_buf
-       struct ifconf lifc;
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
+    !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) 
+
+#ifdef __hpux
+#define lifc_len iflc_len
+#define lifc_buf iflc_buf
+#define lifc_req iflc_req
+#define LIFCONF if_laddrconf
 #else
 #define SETFAMILYFLAGS
-       struct lifconf lifc;
+#define LIFCONF lifconf
+#endif
+ 
+#ifdef __hpux
+#define lifr_addr iflr_addr
+#define lifr_name iflr_name
+#define lifr_dstaddr iflr_dstaddr
+#define lifr_flags iflr_flags
+#define ss_family sa_family
+#define LIFREQ if_laddrreq
+#else
+#define LIFREQ lifreq
 #endif
 
-#ifndef SIOCGLIFADDR
-/* map new to old */
-#define SIOCGLIFADDR SIOCGIFADDR
-#endif
-
-#ifndef SIOCGLIFFLAGS
-#define SIOCGLIFFLAGS SIOCGIFFLAGS
-#define lifr_addr ifr_addr
-#define lifr_name ifr_name
-#define lifr_flags ifr_flags
-#define ss_family sa_family
-       struct ifreq lifreq;
-#else
-       struct lifreq lifreq;
-#endif
+static int
+scan_interfaces6(int *have_v4, int *have_v6) {
+       struct LIFCONF lifc;
+       struct LIFREQ lifreq;
        struct in_addr in4;
        struct in6_addr in6;
        char *buf = NULL, *cp, *cplim;
-       static int bufsiz = 4095;
+       static unsigned int bufsiz = 4095;
        int s, cpsize, n;
 
        /* Set to zero.  Used as loop terminators below. */
        *have_v4 = *have_v6 = 0;
 
        /* Get interface list from system. */
-       if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+       if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) == -1)
                goto err_ret;
 
        /*
@@ -512,20 +510,11 @@
                if (buf == NULL)
                        goto err_ret;
 #ifdef SETFAMILYFLAGS
-               lifc.lifc_family = AF_UNSPEC;
+               lifc.lifc_family = AF_UNSPEC;   /* request all families */
                lifc.lifc_flags = 0;
 #endif
                lifc.lifc_len = bufsiz;
                lifc.lifc_buf = buf;
-#ifdef IRIX_EMUL_IOCTL_SIOCGIFCONF
-               /*
-                * This is a fix for IRIX OS in which the call to ioctl with
-                * the flag SIOCGIFCONF may not return an entry for all the
-                * interfaces like most flavors of Unix.
-                */
-               if (emul_ioctl(&lifc) >= 0)
-                       break;
-#else
                if ((n = ioctl(s, SIOCGLIFCONF, (char *)&lifc)) != -1) {
                        /*
                         * Some OS's just return what will fit rather
@@ -538,7 +527,6 @@
                        if (lifc.lifc_len + 2 * sizeof(lifreq) < bufsiz)
                                break;
                }
-#endif
                if ((n == -1) && errno != EINVAL)
                        goto err_ret;
 
@@ -573,7 +561,7 @@
 #else
                cpsize = sizeof lifreq.lifr_name;
                /* XXX maybe this should be a hard error? */
-               if (ioctl(s, SOICGLIFADDR, (char *)&lifreq) < 0)
+               if (ioctl(s, SIOCGLIFADDR, (char *)&lifreq) < 0)
                        continue;
 #endif
                switch (lifreq.lifr_addr.ss_family) {
@@ -624,6 +612,158 @@
        return (-1);
 }
 
+#endif
+
+static int
+scan_interfaces(int *have_v4, int *have_v6) {
+       struct ifconf ifc;
+       union {
+               char _pad[256];         /* leave space for IPv6 addresses */
+               struct ifreq ifreq;
+       } u;
+       struct in_addr in4;
+       struct in6_addr in6;
+       char *buf = NULL, *cp, *cplim;
+       static unsigned int bufsiz = 4095;
+       int s, n;
+       size_t cpsize;
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) && \
+    !defined(IRIX_EMUL_IOCTL_SIOCGIFCONF) 
+       /*
+        * Try to scan the interfaces using IPv6 ioctls().
+        */
+       if (!scan_interfaces6(have_v4, have_v6))
+               return (0);
+#endif
+
+       /* Set to zero.  Used as loop terminators below. */
+       *have_v4 = *have_v6 = 0;
+
+       /* Get interface list from system. */
+       if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+               goto err_ret;
+
+       /*
+        * Grow buffer until large enough to contain all interface
+        * descriptions.
+        */
+       for (;;) {
+               buf = memget(bufsiz);
+               if (buf == NULL)
+                       goto err_ret;
+               ifc.ifc_len = bufsiz;
+               ifc.ifc_buf = buf;
+#ifdef IRIX_EMUL_IOCTL_SIOCGIFCONF
+               /*
+                * This is a fix for IRIX OS in which the call to ioctl with
+                * the flag SIOCGIFCONF may not return an entry for all the
+                * interfaces like most flavors of Unix.
+                */
+               if (emul_ioctl(&ifc) >= 0)
+                       break;
+#else
+               if ((n = ioctl(s, SIOCGIFCONF, (char *)&ifc)) != -1) {
+                       /*
+                        * Some OS's just return what will fit rather
+                        * than set EINVAL if the buffer is too small
+                        * to fit all the interfaces in.  If 
+                        * ifc.ifc_len is too near to the end of the
+                        * buffer we will grow it just in case and
+                        * retry.
+                        */
+                       if (ifc.ifc_len + 2 * sizeof(u.ifreq) < bufsiz)
+                               break;
+               }
+#endif
+               if ((n == -1) && errno != EINVAL)
+                       goto err_ret;
+
+               if (bufsiz > 1000000)
+                       goto err_ret;
+
+               memput(buf, bufsiz);
+               bufsiz += 4096;
+       }
+
+       /* Parse system's interface list. */
+       cplim = buf + ifc.ifc_len;    /* skip over if's with big ifr_addr's */
+       for (cp = buf;
+            (*have_v4 == 0 || *have_v6 == 0) && cp < cplim;
+            cp += cpsize) {
+               memcpy(&u.ifreq, cp, sizeof u.ifreq);
+#ifdef HAVE_SA_LEN
+#ifdef FIX_ZERO_SA_LEN
+               if (u.ifreq.ifr_addr.sa_len == 0)
+                       u.ifreq.ifr_addr.sa_len = 16;
+#endif
+#ifdef HAVE_MINIMUM_IFREQ
+               cpsize = sizeof u.ifreq;
+               if (u.ifreq.ifr_addr.sa_len > sizeof (struct sockaddr))
+                       cpsize += (int)u.ifreq.ifr_addr.sa_len -
+                               (int)(sizeof (struct sockaddr));
+#else
+               cpsize = sizeof u.ifreq.ifr_name + u.ifreq.ifr_addr.sa_len;
+#endif /* HAVE_MINIMUM_IFREQ */
+               if (cpsize > sizeof u.ifreq && cpsize <= sizeof u)
+                       memcpy(&u.ifreq, cp, cpsize);
+#elif defined SIOCGIFCONF_ADDR
+               cpsize = sizeof u.ifreq;
+#else
+               cpsize = sizeof u.ifreq.ifr_name;
+               /* XXX maybe this should be a hard error? */
+               if (ioctl(s, SIOCGIFADDR, (char *)&u.ifreq) < 0)
+                       continue;
+#endif
+               switch (u.ifreq.ifr_addr.sa_family) {
+               case AF_INET:
+                       if (*have_v4 == 0) {
+                               memcpy(&in4,
+                                      &((struct sockaddr_in *)
+                                      &u.ifreq.ifr_addr)->sin_addr,
+                                      sizeof in4);
+                               if (in4.s_addr == INADDR_ANY)
+                                       break;
+                               n = ioctl(s, SIOCGIFFLAGS, (char *)&u.ifreq);
+                               if (n < 0)
+                                       break;
+                               if ((u.ifreq.ifr_flags & IFF_UP) == 0)
+                                       break;
+                               *have_v4 = 1;
+                       } 
+                       break;
+               case AF_INET6:
+                       if (*have_v6 == 0) {
+                               memcpy(&in6,
+                                      &((struct sockaddr_in6 *)
+                                      &u.ifreq.ifr_addr)->sin6_addr,



Home | Main Index | Thread Index | Old Index