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/resolv Pull up revision 1.5 (requested by...



details:   https://anonhg.NetBSD.org/src/rev/629f0de635db
branches:  netbsd-1-6
changeset: 528242:629f0de635db
user:      lukem <lukem%NetBSD.org@localhost>
date:      Fri Jun 28 11:58:40 2002 +0000

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

diffstat:

 dist/bind/lib/resolv/res_send.c   |  287 +++++++++++++++++++++++++++++--------
 dist/bind/lib/resolv/res_update.c |   69 ++------
 2 files changed, 243 insertions(+), 113 deletions(-)

diffs (truncated from 706 to 300 lines):

diff -r c7e2cd3bc230 -r 629f0de635db dist/bind/lib/resolv/res_send.c
--- a/dist/bind/lib/resolv/res_send.c   Fri Jun 28 11:58:30 2002 +0000
+++ b/dist/bind/lib/resolv/res_send.c   Fri Jun 28 11:58:40 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: res_send.c,v 1.4 2001/05/17 23:00:20 itojun Exp $      */
+/*     $NetBSD: res_send.c,v 1.4.2.1 2002/06/28 11:58:40 lukem Exp $   */
 
 /*
  * Copyright (c) 1985, 1989, 1993
@@ -72,7 +72,7 @@
 
 #if defined(LIBC_SCCS) && !defined(lint)
 static const char sccsid[] = "@(#)res_send.c   8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "Id: res_send.c,v 8.42 2001/03/07 06:48:03 marka Exp";
+static const char rcsid[] = "Id: res_send.c,v 8.49 2002/03/29 21:50:51 marka Exp";
 #endif /* LIBC_SCCS and not lint */
 
 /*
@@ -108,6 +108,7 @@
 /* Options.  Leave them on. */
 #define DEBUG
 #include "res_debug.h"
+#include "res_private.h"
 
 #define EXT(res) ((res)->_u._ext)
 
@@ -115,20 +116,25 @@
 
 /* Forward. */
 
+static int             get_salen __P((const struct sockaddr *));
+static struct sockaddr * get_nsaddr __P((res_state, size_t));
 static int             send_vc(res_state, const u_char *, int,
                                u_char *, int, int *, int);
 static int             send_dg(res_state, const u_char *, int,
                                u_char *, int, int *, int,
                                int *, int *);
 static void            Aerror(const res_state, FILE *, const char *, int,
-                              struct sockaddr_in);
+                              const struct sockaddr *, int);
 static void            Perror(const res_state, FILE *, const char *, int);
-static int             sock_eq(struct sockaddr_in *, struct sockaddr_in *);
+static int             sock_eq(struct sockaddr *, struct sockaddr *);
 #ifdef NEED_PSELECT
 static int             pselect(int, void *, void *, void *,
                                struct timespec *,
                                const sigset_t *);
 #endif
+void res_pquery(const res_state, const u_char *, int, FILE *);
+
+static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
 
 /* Public. */
 
@@ -142,19 +148,38 @@
  *     paul vixie, 29may94
  */
 int
-res_ourserver_p(const res_state statp, const struct sockaddr_in *inp) {
-       struct sockaddr_in ina;
+res_ourserver_p(const res_state statp, const struct sockaddr *sa) {
+       const struct sockaddr_in *inp, *srv;
+       const struct sockaddr_in6 *in6p, *srv6;
        int ns;
 
-       ina = *inp;
-       for (ns = 0; ns < statp->nscount; ns++) {
-               const struct sockaddr_in *srv = &statp->nsaddr_list[ns];
-
-               if (srv->sin_family == ina.sin_family &&
-                   srv->sin_port == ina.sin_port &&
-                   (srv->sin_addr.s_addr == INADDR_ANY ||
-                    srv->sin_addr.s_addr == ina.sin_addr.s_addr))
-                       return (1);
+       switch (sa->sa_family) {
+       case AF_INET:
+               inp = (const struct sockaddr_in *)sa;
+               for (ns = 0;  ns < statp->nscount;  ns++) {
+                       srv = (struct sockaddr_in *)get_nsaddr(statp, ns);
+                       if (srv->sin_family == inp->sin_family &&
+                           srv->sin_port == inp->sin_port &&
+                           (srv->sin_addr.s_addr == INADDR_ANY ||
+                            srv->sin_addr.s_addr == inp->sin_addr.s_addr))
+                               return (1);
+               }
+               break;
+       case AF_INET6:
+               if (EXT(statp).ext == NULL)
+                       break;
+               in6p = (const struct sockaddr_in6 *)sa;
+               for (ns = 0;  ns < statp->nscount;  ns++) {
+                       srv6 = (struct sockaddr_in6 *)get_nsaddr(statp, ns);
+                       if (srv6->sin6_family == in6p->sin6_family &&
+                           srv6->sin6_port == in6p->sin6_port &&
+                           (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
+                            IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr)))
+                               return (1);
+               }
+               break;
+       default:
+               break;
        }
        return (0);
 }
@@ -176,7 +201,7 @@
                const u_char *buf, const u_char *eom)
 {
        const u_char *cp = buf + HFIXEDSZ;
-       int qdcount = ntohs(((HEADER*)buf)->qdcount);
+       int qdcount = ntohs(((const HEADER*)buf)->qdcount);
 
        while (qdcount-- > 0) {
                char tname[MAXDNAME+1];
@@ -213,7 +238,7 @@
                 const u_char *buf2, const u_char *eom2)
 {
        const u_char *cp = buf1 + HFIXEDSZ;
-       int qdcount = ntohs(((HEADER*)buf1)->qdcount);
+       int qdcount = ntohs(((const HEADER*)buf1)->qdcount);
 
        if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)
                return (-1);
@@ -222,11 +247,11 @@
         * Only header section present in replies to
         * dynamic update packets.
         */
-       if ((((HEADER *)buf1)->opcode == ns_o_update) &&
-           (((HEADER *)buf2)->opcode == ns_o_update))
+       if ((((const HEADER *)buf1)->opcode == ns_o_update) &&
+           (((const HEADER *)buf2)->opcode == ns_o_update))
                return (1);
 
-       if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
+       if (qdcount != ntohs(((const HEADER*)buf2)->qdcount))
                return (0);
        while (qdcount-- > 0) {
                char tname[MAXDNAME+1];
@@ -251,6 +276,7 @@
          const u_char *buf, int buflen, u_char *ans, int anssiz)
 {
        int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
+       char abuf[NI_MAXHOST];
 
        if (statp->nscount == 0) {
                errno = ESRCH;
@@ -272,16 +298,34 @@
         */
        if (EXT(statp).nscount != 0) {
                int needclose = 0;
+               struct sockaddr_storage peer;
+               ISC_SOCKLEN_T peerlen;
 
                if (EXT(statp).nscount != statp->nscount)
                        needclose++;
                else
-                       for (ns = 0; ns < statp->nscount; ns++)
-                               if (!sock_eq(&statp->nsaddr_list[ns],
-                                            &EXT(statp).nsaddrs[ns])) {
+                       for (ns = 0; ns < statp->nscount; ns++) {
+                               if (statp->nsaddr_list[ns].sin_family &&
+                                   !sock_eq((struct sockaddr *)&statp->nsaddr_list[ns],
+                                            (struct sockaddr *)&EXT(statp).ext->nsaddrs[ns])) {
                                        needclose++;
                                        break;
                                }
+
+                               if (EXT(statp).nssocks[ns] == -1)
+                                       continue;
+                               peerlen = sizeof(peer);
+                               if (getsockname(EXT(statp).nssocks[ns],
+                                   (struct sockaddr *)&peer, &peerlen) < 0) {
+                                       needclose++;
+                                       break;
+                               }
+                               if (!sock_eq((struct sockaddr *)&peer,
+                                   get_nsaddr(statp, ns))) {
+                                       needclose++;
+                                       break;
+                               }
+                       }
                if (needclose) {
                        res_nclose(statp);
                        EXT(statp).nscount = 0;
@@ -293,9 +337,12 @@
         */
        if (EXT(statp).nscount == 0) {
                for (ns = 0; ns < statp->nscount; ns++) {
-                       EXT(statp).nsaddrs[ns] = statp->nsaddr_list[ns];
                        EXT(statp).nstimes[ns] = RES_MAXTIME;
                        EXT(statp).nssocks[ns] = -1;
+                       if (!statp->nsaddr_list[ns].sin_family)
+                               continue;
+                       EXT(statp).ext->nsaddrs[ns].sin =
+                                statp->nsaddr_list[ns];
                }
                EXT(statp).nscount = statp->nscount;
        }
@@ -306,19 +353,27 @@
         */
        if ((statp->options & RES_ROTATE) != 0 &&
            (statp->options & RES_BLAST) == 0) {
+               union res_sockaddr_union inu;
                struct sockaddr_in ina;
                int lastns = statp->nscount - 1;
                int fd;
                u_int16_t nstime;
 
+               if (EXT(statp).ext != NULL)
+                       inu = EXT(statp).ext->nsaddrs[0];
                ina = statp->nsaddr_list[0];
                fd = EXT(statp).nssocks[0];
-               nstime = EXT(statp).nstimes[ns];
+               nstime = EXT(statp).nstimes[0];
                for (ns = 0; ns < lastns; ns++) {
+                       if (EXT(statp).ext != NULL)
+                                EXT(statp).ext->nsaddrs[ns] = 
+                                       EXT(statp).ext->nsaddrs[ns + 1];
                        statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
                        EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
                        EXT(statp).nstimes[ns] = EXT(statp).nstimes[ns + 1];
                }
+               if (EXT(statp).ext != NULL)
+                       EXT(statp).ext->nsaddrs[lastns] = inu;
                statp->nsaddr_list[lastns] = ina;
                EXT(statp).nssocks[lastns] = fd;
                EXT(statp).nstimes[lastns] = nstime;
@@ -329,7 +384,10 @@
         */
        for (try = 0; try < statp->retry; try++) {
            for (ns = 0; ns < statp->nscount; ns++) {
-               struct sockaddr_in *nsap = &statp->nsaddr_list[ns];
+               struct sockaddr *nsap;
+               int nsaplen;
+               nsap = get_nsaddr(statp, ns);
+               nsaplen = get_salen(nsap);
  same_ns:
                if (statp->qhook) {
                        int done = 0, loops = 0;
@@ -361,9 +419,12 @@
                        } while (!done);
                }
 
-               Dprint(statp->options & RES_DEBUG,
+               Dprint(((statp->options & RES_DEBUG) &&
+                       getnameinfo(nsap, nsaplen, abuf, sizeof(abuf),
+                                   NULL, 0, niflags) == 0),
                       (stdout, ";; Querying server (# %d) address = %s\n",
-                       ns + 1, inet_ntoa(nsap->sin_addr)));
+                       ns + 1, abuf));
+
 
                if (v_circuit) {
                        /* Use VC; at most one attempt per server. */
@@ -395,7 +456,7 @@
 
                DprintQ((statp->options & RES_DEBUG) ||
                        (statp->pfcode & RES_PRF_REPLY),
-                       (stdout, ""),
+                       (stdout, "%s", ""),
                        ans, (resplen > anssiz) ? anssiz : resplen);
 
                /*
@@ -457,17 +518,67 @@
 /* Private */
 
 static int
+get_salen(sa)
+       const struct sockaddr *sa;
+{
+
+#ifdef HAVE_SA_LEN
+       /* There are people do not set sa_len.  Be forgiving to them. */
+       if (sa->sa_len)
+               return (sa->sa_len);
+#endif
+
+       if (sa->sa_family == AF_INET)
+               return (sizeof(struct sockaddr_in));
+       else if (sa->sa_family == AF_INET6)
+               return (sizeof(struct sockaddr_in6));
+       else
+               return (0);     /* unknown, die on connect */
+}
+
+/*
+ * pick appropriate nsaddr_list for use.  see res_init() for initialization.
+ */
+static struct sockaddr *
+get_nsaddr(statp, n)
+       res_state statp;
+       size_t n;
+{
+
+       if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) {
+               /*
+                * - EXT(statp).ext->nsaddrs[n] holds an address that is larger
+                *   than struct sockaddr, and
+                * - user code did not update statp->nsaddr_list[n].
+                */
+               return (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[n];



Home | Main Index | Thread Index | Old Index