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