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 revisions 1.3-1.4 (requested ...
details: https://anonhg.NetBSD.org/src/rev/e11237027144
branches: netbsd-1-6
changeset: 528195:e11237027144
user: lukem <lukem%NetBSD.org@localhost>
date: Fri Jun 28 11:46:16 2002 +0000
description:
Pull up revisions 1.3-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/dns_ho.c | 1175 +++++++++++++++++++++++++++++++++++++++----
1 files changed, 1056 insertions(+), 119 deletions(-)
diffs (truncated from 1515 to 300 lines):
diff -r 327681b6d89d -r e11237027144 dist/bind/lib/irs/dns_ho.c
--- a/dist/bind/lib/irs/dns_ho.c Fri Jun 28 11:46:06 2002 +0000
+++ b/dist/bind/lib/irs/dns_ho.c Fri Jun 28 11:46:16 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: dns_ho.c,v 1.2 2001/01/27 07:22:03 itojun Exp $ */
+/* $NetBSD: dns_ho.c,v 1.2.2.1 2002/06/28 11:46:16 lukem Exp $ */
/*
* Copyright (c) 1985, 1988, 1993
@@ -54,7 +54,7 @@
/* BIND Id: gethnamaddr.c,v 8.15 1996/05/22 04:56:30 vixie Exp $ */
#if defined(LIBC_SCCS) && !defined(lint)
-static const char rcsid[] = "Id: dns_ho.c,v 1.28 2000/04/20 07:47:54 vixie Exp";
+static const char rcsid[] = "Id: dns_ho.c,v 1.39 2002/06/27 03:56:32 marka Exp";
#endif /* LIBC_SCCS and not lint */
/* Imports. */
@@ -76,6 +76,7 @@
#include <resolv.h>
#include <stdio.h>
#include <string.h>
+#include <syslog.h>
#include <isc/memcluster.h>
#include <irs.h>
@@ -96,11 +97,7 @@
#define MAXALIASES 35
#define MAXADDRS 35
-#if PACKETSZ > 1024
-#define MAXPACKET PACKETSZ
-#else
-#define MAXPACKET 1024
-#endif
+#define MAXPACKET (1024*64)
#define BOUNDS_CHECK(ptr, count) \
if ((ptr) + (count) > eom) { \
@@ -108,6 +105,26 @@
continue; \
} else (void)0
+typedef union {
+ HEADER hdr;
+ u_char buf[MAXPACKET];
+} querybuf;
+
+struct dns_res_target {
+ struct dns_res_target *next;
+ querybuf qbuf; /* query buffer */
+ u_char *answer; /* buffer to put answer */
+ int anslen; /* size of answer buffer */
+ int qclass, qtype; /* class and type of query */
+ int action; /* condition whether query is really issued */
+ char qname[MAXDNAME +1]; /* domain name */
+#if 0
+ int n; /* result length */
+#endif
+};
+enum {RESTGT_DOALWAYS, RESTGT_AFTERFAILURE, RESTGT_IGNORE};
+enum {RESQRY_SUCCESS, RESQRY_FAIL};
+
struct pvt {
struct hostent host;
char * h_addr_ptrs[MAXADDRS + 1];
@@ -143,14 +160,29 @@
static void ho_res_set(struct irs_ho *this,
struct __res_state *res,
void (*free_res)(void *));
+static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
+ const struct addrinfo *pai);
static void map_v4v6_hostent(struct hostent *hp, char **bp,
- int *len);
+ char *ep);
static void addrsort(res_state, char **, int);
static struct hostent * gethostans(struct irs_ho *this,
const u_char *ansbuf, int anslen,
const char *qname, int qtype,
- int af, int size);
+ int af, int size,
+ struct addrinfo **ret_aip,
+ const struct addrinfo *pai);
+static int add_hostent(struct pvt *pvt, char *bp, char **hap,
+ struct addrinfo *ai);
+static const u_char * ar_head(const u_char *, int, const u_char *,
+ const u_char *, struct pvt *,
+ int (*)(const char *));
+static struct addrinfo * a6_expand(const u_char *, const u_char *, int,
+ const u_char *, const u_char *,
+ const struct in6_addr *, int,
+ const struct addrinfo *,
+ struct pvt *, int (*)(const char *), int *);
+static const char *dname_subst(const char *, const char *, const char *);
static int init(struct irs_ho *this);
/* Exports. */
@@ -160,6 +192,8 @@
struct irs_ho *ho;
struct pvt *pvt;
+ UNUSED(this);
+
if (!(pvt = memget(sizeof *pvt))) {
errno = ENOMEM;
return (NULL);
@@ -182,6 +216,7 @@
ho->minimize = ho_minimize;
ho->res_get = ho_res_get;
ho->res_set = ho_res_set;
+ ho->addrinfo = ho_addrinfo;
return (ho);
}
@@ -216,29 +251,63 @@
}
static struct hostent *
-ho_byname2(struct irs_ho *this, const char *name, int af) {
+ho_byname2(struct irs_ho *this, const char *name, int af)
+{
struct pvt *pvt = (struct pvt *)this->private;
- int n, size, type;
- u_char buf[MAXPACKET];
+ struct hostent *hp = NULL;
+ int n, size;
char tmp[NS_MAXDNAME];
const char *cp;
+ struct addrinfo ai;
+ struct dns_res_target *q, *q2, *p;
+ int querystate = RESQRY_FAIL;
if (init(this) == -1)
return (NULL);
+ q = memget(sizeof(*q));
+ q2 = memget(sizeof(*q2));
+ if (q == NULL || q2 == NULL) {
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
+ errno = ENOMEM;
+ goto cleanup;
+ }
+ memset(q, 0, sizeof(q));
+ memset(q2, 0, sizeof(q2));
+
switch (af) {
case AF_INET:
size = INADDRSZ;
- type = T_A;
+ q->qclass = C_IN;
+ q->qtype = T_A;
+ q->answer = q->qbuf.buf;
+ q->anslen = sizeof(q->qbuf);
+ q->action = RESTGT_DOALWAYS;
break;
case AF_INET6:
size = IN6ADDRSZ;
- type = T_AAAA;
+ q->qclass = C_IN;
+ q->qtype = ns_t_a6;
+ q->answer = q->qbuf.buf;
+ q->anslen = sizeof(q->qbuf);
+ q->next = q2;
+#ifdef RES_USE_A6
+ if ((pvt->res->options & RES_USE_A6) == 0)
+ q->action = RESTGT_IGNORE;
+ else
+#endif
+ q->action = RESTGT_DOALWAYS;
+ q2->qclass = C_IN;
+ q2->qtype = T_AAAA;
+ q2->answer = q2->qbuf.buf;
+ q2->anslen = sizeof(q2->qbuf);
+ q2->action = RESTGT_AFTERFAILURE;
break;
default:
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
errno = EAFNOSUPPORT;
- return (NULL);
+ hp = NULL;
+ goto cleanup;
}
/*
@@ -250,30 +319,74 @@
tmp, sizeof tmp)))
name = cp;
- if ((n = res_nsearch(pvt->res, name, C_IN, type,
- buf, sizeof buf)) < 0)
- return (NULL);
- return (gethostans(this, buf, n, name, type, af, size));
+ for (p = q; p; p = p->next) {
+ switch(p->action) {
+ case RESTGT_DOALWAYS:
+ break;
+ case RESTGT_AFTERFAILURE:
+ if (querystate == RESQRY_SUCCESS)
+ continue;
+ break;
+ case RESTGT_IGNORE:
+ continue;
+ }
+
+ if ((n = res_nsearch(pvt->res, name, p->qclass, p->qtype,
+ p->answer, p->anslen)) < 0) {
+ querystate = RESQRY_FAIL;
+ continue;
+ }
+
+ memset(&ai, 0, sizeof(ai));
+ ai.ai_family = af;
+ if ((hp = gethostans(this, p->answer, n, name, p->qtype,
+ af, size, NULL,
+ (const struct addrinfo *)&ai)) != NULL)
+ goto cleanup; /* no more loop is necessary */
+
+ querystate = RESQRY_FAIL;
+ continue;
+ }
+
+ cleanup:
+ if (q != NULL)
+ memput(q, sizeof(*q));
+ if (q2 != NULL)
+ memput(q2, sizeof(*q2));
+ return(hp);
}
static struct hostent *
-ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
+ho_byaddr(struct irs_ho *this, const void *addr, int len, int af)
+{
struct pvt *pvt = (struct pvt *)this->private;
const u_char *uaddr = addr;
- char qbuf[MAXDNAME+1], *qp;
- u_char buf[MAXPACKET];
- struct hostent *hp;
+ char *qp;
+ struct hostent *hp = NULL;
+ struct addrinfo ai;
+ struct dns_res_target *q, *q2, *p;
int n, size;
+ int querystate = RESQRY_FAIL;
if (init(this) == -1)
return (NULL);
+ q = memget(sizeof(*q));
+ q2 = memget(sizeof(*q2));
+ if (q == NULL || q2 == NULL) {
+ RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
+ errno = ENOMEM;
+ goto cleanup;
+ }
+ memset(q, 0, sizeof(q));
+ memset(q2, 0, sizeof(q2));
+
if (af == AF_INET6 && len == IN6ADDRSZ &&
(!memcmp(uaddr, mapped, sizeof mapped) ||
(!memcmp(uaddr, tunnelled, sizeof tunnelled) &&
memcmp(&uaddr[sizeof tunnelled], v6local, sizeof(v6local))))) {
/* Unmap. */
- addr = (char *)addr + sizeof mapped;
+ addr = (const char *)addr + sizeof mapped;
uaddr += sizeof mapped;
af = AF_INET;
len = INADDRSZ;
@@ -281,65 +394,137 @@
switch (af) {
case AF_INET:
size = INADDRSZ;
+ q->qclass = C_IN;
+ q->qtype = T_PTR;
+ q->answer = q->qbuf.buf;
+ q->anslen = sizeof(q->qbuf);
+ q->action = RESTGT_DOALWAYS;
break;
case AF_INET6:
size = IN6ADDRSZ;
+ q->qclass = C_IN;
+ q->qtype = T_PTR;
+ q->answer = q->qbuf.buf;
+ q->anslen = sizeof(q->qbuf);
+ q->next = q2;
+ q->action = RESTGT_DOALWAYS;
+ q2->qclass = C_IN;
+ q2->qtype = T_PTR;
+ q2->answer = q2->qbuf.buf;
+ q2->anslen = sizeof(q2->qbuf);
+ if ((pvt->res->options & RES_NO_NIBBLE2) != 0)
+ q2->action = RESTGT_IGNORE;
+ else
+ q2->action = RESTGT_AFTERFAILURE;
break;
default:
errno = EAFNOSUPPORT;
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
- return (NULL);
Home |
Main Index |
Thread Index |
Old Index