File bind-CVE-2021-25220.patch of Package bind.37294
Index: bind-9.9.9-P1/bin/named/include/named/query.h
===================================================================
--- bind-9.9.9-P1.orig/bin/named/include/named/query.h
+++ bind-9.9.9-P1/bin/named/include/named/query.h
@@ -66,6 +66,19 @@ struct ns_query {
unsigned int dns64_aaaaoklen;
unsigned int dns64_options;
unsigned int dns64_ttl;
+ struct {
+ dns_db_t * db;
+ dns_zone_t * zone;
+ dns_dbnode_t * node;
+ dns_rdatatype_t qtype;
+ dns_name_t * fname;
+ dns_fixedname_t fixed;
+ isc_result_t result;
+ dns_rdataset_t * rdataset;
+ dns_rdataset_t * sigrdataset;
+ isc_boolean_t authoritative;
+ isc_boolean_t is_zone;
+ } redirect;
};
#define NS_QUERYATTR_RECURSIONOK 0x0001
Index: bind-9.9.9-P1/bin/named/query.c
===================================================================
--- bind-9.9.9-P1.orig/bin/named/query.c
+++ bind-9.9.9-P1/bin/named/query.c
@@ -661,6 +661,17 @@ ns_query_init(ns_client_t *client) {
client->query.dns64_sigaaaa = NULL;
client->query.dns64_aaaaok = NULL;
client->query.dns64_aaaaoklen = 0;
+ client->query.redirect.db = NULL;
+ client->query.redirect.node = NULL;
+ client->query.redirect.zone = NULL;
+ client->query.redirect.qtype = dns_rdatatype_none;
+ client->query.redirect.result = ISC_R_SUCCESS;
+ client->query.redirect.rdataset = NULL;
+ client->query.redirect.sigrdataset = NULL;
+ client->query.redirect.authoritative = isc_boolean_false;
+ client->query.redirect.is_zone = isc_boolean_false;
+ client->query.redirect.fname =
+ dns_fixedname_initname(&client->query.redirect.fixed);
query_reset(client, ISC_FALSE);
result = query_newdbversion(client, 3);
if (result != ISC_R_SUCCESS) {
@@ -2676,8 +2687,7 @@ query_addsoa(ns_client_t *client, dns_db
dns_fixedname_t foundname;
dns_name_t *fname;
- dns_fixedname_init(&foundname);
- fname = dns_fixedname_name(&foundname);
+ fname = dns_fixedname_initname(&foundname);
result = dns_db_findext(db, name, version, dns_rdatatype_soa,
client->query.dboptions, 0, &node,
@@ -2761,8 +2771,7 @@ query_addns(ns_client_t *client, dns_db_
name = NULL;
rdataset = NULL;
node = NULL;
- dns_fixedname_init(&foundname);
- fname = dns_fixedname_name(&foundname);
+ fname = dns_fixedname_initname(&foundname);
dns_clientinfomethods_init(&cm, ns_client_sourceip);
dns_clientinfo_init(&ci, client);
@@ -3492,8 +3501,7 @@ query_addwildcardproof(ns_client_t *clie
* wild *.example
*/
options = client->query.dboptions | DNS_DBFIND_NOWILD;
- dns_fixedname_init(&wfixed);
- wname = dns_fixedname_name(&wfixed);
+ wname = dns_fixedname_initname(&wfixed);
again:
have_wname = ISC_FALSE;
/*
@@ -3518,8 +3526,7 @@ query_addwildcardproof(ns_client_t *clie
/*
* No NSEC proof available, return NSEC3 proofs instead.
*/
- dns_fixedname_init(&cfixed);
- cname = dns_fixedname_name(&cfixed);
+ cname = dns_fixedname_initname(&cfixed);
/*
* Find the closest encloser.
*/
@@ -4097,8 +4104,7 @@ rpz_rrset_find(ns_client_t *client, dns_
}
node = NULL;
- dns_fixedname_init(&fixed);
- found = dns_fixedname_name(&fixed);
+ found = dns_fixedname_initname(&fixed);
result = dns_db_findext(*dbp, name, version, type, DNS_DBFIND_GLUEOK,
client->now, &node, found,
&cm, &ci, *rdatasetp, NULL);
@@ -4335,8 +4341,7 @@ rpz_find(ns_client_t *client, dns_rdatat
return (DNS_R_NXDOMAIN);
}
- dns_fixedname_init(&fixed);
- found = dns_fixedname_name(&fixed);
+ found = dns_fixedname_initname(&fixed);
result = dns_db_findext(*dbp, qnamef, *versionp, dns_rdatatype_any, 0,
client->now, nodep, found, &cm, &ci,
*rdatasetp, NULL);
@@ -4491,15 +4496,13 @@ rpz_rewrite_name(ns_client_t *client, dn
/*
* Construct the policy's owner name.
*/
- dns_fixedname_init(&prefixf);
- prefix = dns_fixedname_name(&prefixf);
+ prefix = dns_fixedname_initname(&prefixf);
dns_name_split(qname, 1, prefix, NULL);
if (rpz_type == DNS_RPZ_TYPE_NSDNAME)
suffix = &rpz->nsdname;
else
suffix = &rpz->origin;
- dns_fixedname_init(&rpz_qnamef);
- rpz_qname = dns_fixedname_name(&rpz_qnamef);
+ rpz_qname = dns_fixedname_initname(&rpz_qnamef);
for (;;) {
result = dns_name_concatenate(prefix, suffix,
rpz_qname, NULL);
@@ -4674,12 +4677,9 @@ rpz_rewrite(ns_client_t *client, dns_rda
st->m.ttl = ~0;
memset(&st->r, 0, sizeof(st->r));
memset(&st->q, 0, sizeof(st->q));
- dns_fixedname_init(&st->_qnamef);
- dns_fixedname_init(&st->_r_namef);
- dns_fixedname_init(&st->_fnamef);
- st->qname = dns_fixedname_name(&st->_qnamef);
- st->r_name = dns_fixedname_name(&st->_r_namef);
- st->fname = dns_fixedname_name(&st->_fnamef);
+ st->qname = dns_fixedname_initname(&st->_qnamef);
+ st->r_name = dns_fixedname_initname(&st->_r_namef);
+ st->fname = dns_fixedname_initname(&st->_fnamef);
client->query.rpz_st = st;
}
@@ -4957,8 +4957,7 @@ rpz_ck_dnssec(ns_client_t *client, isc_r
*/
if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) == 0)
return (ISC_TRUE);
- dns_fixedname_init(&fixed);
- found = dns_fixedname_name(&fixed);
+ found = dns_fixedname_initname(&fixed);
dns_rdataset_init(&trdataset);
for (result = dns_rdataset_first(rdataset);
result == ISC_R_SUCCESS;
@@ -5544,8 +5543,7 @@ redirect(ns_client_t *client, dns_name_t
if (client->view->redirect == NULL)
return (ISC_R_NOTFOUND);
- dns_fixedname_init(&fixed);
- found = dns_fixedname_name(&fixed);
+ found = dns_fixedname_initname(&fixed);
dns_rdataset_init(&trdataset);
dns_clientinfomethods_init(&cm, ns_client_sourceip);
@@ -6709,8 +6707,7 @@ query_find(ns_client_t *client, dns_fetc
dns_name_t *found;
dns_name_t *qname;
- dns_fixedname_init(&fixed);
- found = dns_fixedname_name(&fixed);
+ found = dns_fixedname_initname(&fixed);
qname = client->query.qname;
query_findclosestnsec3(qname, db, version,
@@ -7153,8 +7150,7 @@ query_find(ns_client_t *client, dns_fetc
* Construct the new qname consisting of
* <found name prefix>.<dname target>
*/
- dns_fixedname_init(&fixed);
- prefix = dns_fixedname_name(&fixed);
+ prefix = dns_fixedname_initname(&fixed);
dns_name_split(client->query.qname, nlabels, prefix, NULL);
INSIST(fname == NULL);
dbuf = query_getnamebuf(client);
Index: bind-9.9.9-P1/bin/named/tkeyconf.c
===================================================================
--- bind-9.9.9-P1.orig/bin/named/tkeyconf.c
+++ bind-9.9.9-P1/bin/named/tkeyconf.c
@@ -75,8 +75,7 @@ ns_tkeyctx_fromconfig(const cfg_obj_t *o
n = cfg_obj_asuint32(cfg_tuple_get(obj, "keyid"));
isc_buffer_constinit(&b, s, strlen(s));
isc_buffer_add(&b, strlen(s));
- dns_fixedname_init(&fname);
- name = dns_fixedname_name(&fname);
+ name = dns_fixedname_initname(&fname);
RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
type = DST_TYPE_PUBLIC|DST_TYPE_PRIVATE|DST_TYPE_KEY;
RETERR(dst_key_fromfile(name, (dns_keytag_t) n, DNS_KEYALG_DH,
@@ -89,8 +88,7 @@ ns_tkeyctx_fromconfig(const cfg_obj_t *o
s = cfg_obj_asstring(obj);
isc_buffer_constinit(&b, s, strlen(s));
isc_buffer_add(&b, strlen(s));
- dns_fixedname_init(&fname);
- name = dns_fixedname_name(&fname);
+ name = dns_fixedname_initname(&fname);
RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
tctx->domain = isc_mem_get(mctx, sizeof(dns_name_t));
if (tctx->domain == NULL) {
@@ -108,8 +106,7 @@ ns_tkeyctx_fromconfig(const cfg_obj_t *o
isc_buffer_constinit(&b, s, strlen(s));
isc_buffer_add(&b, strlen(s));
- dns_fixedname_init(&fname);
- name = dns_fixedname_name(&fname);
+ name = dns_fixedname_initname(&fname);
RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL));
RETERR(dst_gssapi_acquirecred(name, ISC_FALSE, &tctx->gsscred));
}
Index: bind-9.9.9-P1/lib/dns/forward.c
===================================================================
--- bind-9.9.9-P1.orig/lib/dns/forward.c
+++ bind-9.9.9-P1/lib/dns/forward.c
@@ -81,12 +81,62 @@ dns_fwdtable_create(isc_mem_t *mctx, dns
}
isc_result_t
+dns_fwdtable_addfwd(dns_fwdtable_t *fwdtable, dns_name_t *name,
+ dns_forwarderlist_t *fwdrs, dns_fwdpolicy_t fwdpolicy)
+{
+ isc_result_t result;
+ dns_forwarders_t *forwarders;
+ dns_forwarder_t *fwd, *nfwd;
+
+ REQUIRE(VALID_FWDTABLE(fwdtable));
+
+ forwarders = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarders_t));
+ if (forwarders == NULL)
+ return (ISC_R_NOMEMORY);
+
+ ISC_LIST_INIT(forwarders->fwdrs);
+ for (fwd = ISC_LIST_HEAD(*fwdrs);
+ fwd != NULL;
+ fwd = ISC_LIST_NEXT(fwd, link))
+ {
+ nfwd = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarder_t));
+ if (nfwd == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ *nfwd = *fwd;
+ ISC_LINK_INIT(nfwd, link);
+ ISC_LIST_APPEND(forwarders->fwdrs, nfwd, link);
+ }
+ forwarders->fwdpolicy = fwdpolicy;
+
+ RWLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
+ result = dns_rbt_addname(fwdtable->table, name, forwarders);
+ RWUNLOCK(&fwdtable->rwlock, isc_rwlocktype_write);
+
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
+ fwd = ISC_LIST_HEAD(forwarders->fwdrs);
+ ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
+ isc_mem_put(fwdtable->mctx, fwd, sizeof(isc_sockaddr_t));
+ }
+ isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t));
+ return (result);
+}
+
+isc_result_t
dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name,
isc_sockaddrlist_t *addrs, dns_fwdpolicy_t fwdpolicy)
{
isc_result_t result;
dns_forwarders_t *forwarders;
- isc_sockaddr_t *sa, *nsa;
+ dns_forwarder_t *fwd;
+ isc_sockaddr_t *sa;
REQUIRE(VALID_FWDTABLE(fwdtable));
@@ -94,19 +144,20 @@ dns_fwdtable_add(dns_fwdtable_t *fwdtabl
if (forwarders == NULL)
return (ISC_R_NOMEMORY);
- ISC_LIST_INIT(forwarders->addrs);
+ ISC_LIST_INIT(forwarders->fwdrs);
for (sa = ISC_LIST_HEAD(*addrs);
sa != NULL;
sa = ISC_LIST_NEXT(sa, link))
{
- nsa = isc_mem_get(fwdtable->mctx, sizeof(isc_sockaddr_t));
- if (nsa == NULL) {
+ fwd = isc_mem_get(fwdtable->mctx, sizeof(dns_forwarder_t));
+ if (fwd == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup;
}
- *nsa = *sa;
- ISC_LINK_INIT(nsa, link);
- ISC_LIST_APPEND(forwarders->addrs, nsa, link);
+ fwd->addr = *sa;
+ fwd->dscp = -1;
+ ISC_LINK_INIT(fwd, link);
+ ISC_LIST_APPEND(forwarders->fwdrs, fwd, link);
}
forwarders->fwdpolicy = fwdpolicy;
@@ -120,10 +171,10 @@ dns_fwdtable_add(dns_fwdtable_t *fwdtabl
return (ISC_R_SUCCESS);
cleanup:
- while (!ISC_LIST_EMPTY(forwarders->addrs)) {
- sa = ISC_LIST_HEAD(forwarders->addrs);
- ISC_LIST_UNLINK(forwarders->addrs, sa, link);
- isc_mem_put(fwdtable->mctx, sa, sizeof(isc_sockaddr_t));
+ while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
+ fwd = ISC_LIST_HEAD(forwarders->fwdrs);
+ ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
+ isc_mem_put(fwdtable->mctx, fwd, sizeof(dns_forwarder_t));
}
isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t));
return (result);
@@ -199,14 +250,14 @@ static void
auto_detach(void *data, void *arg) {
dns_forwarders_t *forwarders = data;
dns_fwdtable_t *fwdtable = arg;
- isc_sockaddr_t *sa;
+ dns_forwarder_t *fwd;
UNUSED(arg);
- while (!ISC_LIST_EMPTY(forwarders->addrs)) {
- sa = ISC_LIST_HEAD(forwarders->addrs);
- ISC_LIST_UNLINK(forwarders->addrs, sa, link);
- isc_mem_put(fwdtable->mctx, sa, sizeof(isc_sockaddr_t));
+ while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
+ fwd = ISC_LIST_HEAD(forwarders->fwdrs);
+ ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
+ isc_mem_put(fwdtable->mctx, fwd, sizeof(dns_forwarder_t));
}
isc_mem_put(fwdtable->mctx, forwarders, sizeof(dns_forwarders_t));
}
Index: bind-9.9.9-P1/lib/dns/include/dns/fixedname.h
===================================================================
--- bind-9.9.9-P1.orig/lib/dns/include/dns/fixedname.h
+++ bind-9.9.9-P1/lib/dns/include/dns/fixedname.h
@@ -83,4 +83,10 @@ struct dns_fixedname {
#define dns_fixedname_name(fn) (&((fn)->name))
+static inline dns_name_t *
+dns_fixedname_initname(dns_fixedname_t *fixed) {
+ dns_fixedname_init(fixed);
+ return (dns_fixedname_name(fixed));
+}
+
#endif /* DNS_FIXEDNAME_H */
Index: bind-9.9.9-P1/lib/dns/include/dns/forward.h
===================================================================
--- bind-9.9.9-P1.orig/lib/dns/include/dns/forward.h
+++ bind-9.9.9-P1/lib/dns/include/dns/forward.h
@@ -28,8 +28,16 @@
ISC_LANG_BEGINDECLS
+struct dns_forwarder {
+ isc_sockaddr_t addr;
+ isc_dscp_t dscp;
+ ISC_LINK(dns_forwarder_t) link;
+};
+
+typedef ISC_LIST(struct dns_forwarder) dns_forwarderlist_t;
+
struct dns_forwarders {
- isc_sockaddrlist_t addrs;
+ dns_forwarderlist_t fwdrs;
dns_fwdpolicy_t fwdpolicy;
};
@@ -48,17 +56,23 @@ dns_fwdtable_create(isc_mem_t *mctx, dns
*/
isc_result_t
+dns_fwdtable_addfwd(dns_fwdtable_t *fwdtable, dns_name_t *name,
+ dns_forwarderlist_t *fwdrs, dns_fwdpolicy_t policy);
+
+isc_result_t
dns_fwdtable_add(dns_fwdtable_t *fwdtable, dns_name_t *name,
isc_sockaddrlist_t *addrs, dns_fwdpolicy_t policy);
/*%<
* Adds an entry to the forwarding table. The entry associates
* a domain with a list of forwarders and a forwarding policy. The
- * addrs list is copied if not empty, so the caller should free its copy.
+ * addrs/fwdrs list is copied if not empty, so the caller should free
+ * its copy.
*
* Requires:
* \li fwdtable is a valid forwarding table.
* \li name is a valid name
- * \li addrs is a valid list of sockaddrs, which may be empty.
+ * \li addrs/fwdrs is a valid list of isc_sockaddr/dns_forwarder
+ * structures, which may be empty.
*
* Returns:
* \li #ISC_R_SUCCESS
Index: bind-9.9.9-P1/lib/dns/include/dns/types.h
===================================================================
--- bind-9.9.9-P1.orig/lib/dns/include/dns/types.h
+++ bind-9.9.9-P1/lib/dns/include/dns/types.h
@@ -77,6 +77,7 @@ typedef struct dns_ednsopt dns_ednsopt
typedef struct dns_fetch dns_fetch_t;
typedef struct dns_fixedname dns_fixedname_t;
typedef struct dns_forwarders dns_forwarders_t;
+typedef struct dns_forwarder dns_forwarder_t;
typedef struct dns_fwdtable dns_fwdtable_t;
typedef struct dns_iptable dns_iptable_t;
typedef isc_uint32_t dns_iterations_t;
Index: bind-9.9.9-P1/lib/dns/resolver.c
===================================================================
--- bind-9.9.9-P1.orig/lib/dns/resolver.c
+++ bind-9.9.9-P1/lib/dns/resolver.c
@@ -61,6 +61,7 @@
#include <dns/stats.h>
#include <dns/tsig.h>
#include <dns/validator.h>
+#include <dns/zone.h>
#ifdef WANT_QUERYTRACE
#define RTRACE(m) isc_log_write(dns_lctx, \
@@ -282,7 +283,7 @@ struct fetchctx {
dns_adbfind_t * altfind;
dns_adbaddrinfolist_t forwaddrs;
dns_adbaddrinfolist_t altaddrs;
- isc_sockaddrlist_t forwarders;
+ dns_forwarderlist_t forwarders;
dns_fwdpolicy_t fwdpolicy;
isc_sockaddrlist_t bad;
isc_sockaddrlist_t edns;
@@ -295,6 +296,8 @@ struct fetchctx {
isc_boolean_t ns_ttl_ok;
isc_uint32_t ns_ttl;
isc_counter_t * qc;
+ dns_fixedname_t fwdfname;
+ dns_name_t *fwdname;
/*%
* The number of events we're waiting for.
@@ -2887,7 +2890,7 @@ fctx_getaddresses(fetchctx_t *fctx, isc_
dns_resolver_t *res;
isc_stdtime_t now;
unsigned int stdoptions = 0;
- isc_sockaddr_t *sa;
+ dns_forwarder_t *fwd;
dns_adbaddrinfo_t *ai;
isc_boolean_t all_bad;
dns_rdata_ns_t ns;
@@ -2931,8 +2934,8 @@ fctx_getaddresses(fetchctx_t *fctx, isc_
* selective forwarders specified in the view; otherwise use the
* resolver's forwarders (if any).
*/
- sa = ISC_LIST_HEAD(fctx->forwarders);
- if (sa == NULL) {
+ fwd = ISC_LIST_HEAD(fctx->forwarders);
+ if (fwd == NULL) {
dns_forwarders_t *forwarders = NULL;
dns_name_t *name = &fctx->name;
dns_name_t suffix;
@@ -2952,13 +2955,13 @@ fctx_getaddresses(fetchctx_t *fctx, isc_
name = &suffix;
}
- dns_fixedname_init(&fixed);
- domain = dns_fixedname_name(&fixed);
+ domain = dns_fixedname_initname(&fixed);
result = dns_fwdtable_find2(res->view->fwdtable, name,
domain, &forwarders);
if (result == ISC_R_SUCCESS) {
- sa = ISC_LIST_HEAD(forwarders->addrs);
+ fwd = ISC_LIST_HEAD(forwarders->fwdrs);
fctx->fwdpolicy = forwarders->fwdpolicy;
+ dns_name_copy(domain, fctx->fwdname, NULL);
if (fctx->fwdpolicy == dns_fwdpolicy_only &&
isstrictsubdomain(domain, &fctx->domain)) {
#ifdef ENABLE_FETCHLIMIT
@@ -2981,17 +2984,16 @@ fctx_getaddresses(fetchctx_t *fctx, isc_
}
}
- while (sa != NULL) {
- if ((isc_sockaddr_pf(sa) == AF_INET &&
+ while (fwd != NULL) {
+ if ((isc_sockaddr_pf(&fwd->addr) == AF_INET &&
fctx->res->dispatches4 == NULL) ||
- (isc_sockaddr_pf(sa) == AF_INET6 &&
+ (isc_sockaddr_pf(&fwd->addr) == AF_INET6 &&
fctx->res->dispatches6 == NULL)) {
- sa = ISC_LIST_NEXT(sa, link);
+ fwd = ISC_LIST_NEXT(fwd, link);
continue;
}
ai = NULL;
- result = dns_adb_findaddrinfo(fctx->adb,
- sa, &ai, 0); /* XXXMLG */
+ result = dns_adb_findaddrinfo(fctx->adb, &fwd->addr, &ai, 0);
if (result == ISC_R_SUCCESS) {
dns_adbaddrinfo_t *cur;
ai->flags |= FCTX_ADDRINFO_FORWARDER;
@@ -3004,7 +3006,7 @@ fctx_getaddresses(fetchctx_t *fctx, isc_
else
ISC_LIST_APPEND(fctx->forwaddrs, ai, publink);
}
- sa = ISC_LIST_NEXT(sa, link);
+ fwd = ISC_LIST_NEXT(fwd, link);
}
/*
@@ -4012,6 +4014,9 @@ fctx_create(dns_resolver_t *res, dns_nam
fctx->restarts = 0;
fctx->querysent = 0;
fctx->referrals = 0;
+
+ fctx->fwdname = dns_fixedname_initname(&fctx->fwdfname);
+
TIME_NOW(&fctx->start);
fctx->timeouts = 0;
fctx->lamecount = 0;
@@ -5715,6 +5720,107 @@ mark_related(dns_name_t *name, dns_rdata
rdataset->attributes |= DNS_RDATASETATTR_EXTERNAL;
}
+/*
+ * Returns true if 'name' is external to the namespace for which
+ * the server being queried can answer, either because it's not a
+ * subdomain or because it's below a forward declaration or a
+ * locally served zone.
+ */
+static inline isc_boolean_t
+name_external(dns_name_t *name, dns_rdatatype_t type, fetchctx_t *fctx) {
+ isc_result_t result;
+ dns_forwarders_t *forwarders = NULL;
+ dns_fixedname_t fixed, zfixed;
+ dns_name_t *fname = dns_fixedname_initname(&fixed);
+ dns_name_t *zfname = dns_fixedname_initname(&zfixed);
+ dns_name_t *apex = NULL;
+ dns_name_t suffix;
+ dns_zone_t *zone = NULL;
+ unsigned int labels;
+ dns_namereln_t rel;
+
+ apex = ISFORWARDER(fctx->addrinfo) ? fctx->fwdname : &fctx->domain;
+
+ /*
+ * The name is outside the queried namespace.
+ */
+ rel = dns_name_fullcompare(name, apex, &(int){ 0 },
+ &(unsigned int){ 0U });
+ if (rel != dns_namereln_subdomain && rel != dns_namereln_equal) {
+ return (ISC_TRUE);
+ }
+
+ /*
+ * If the record lives in the parent zone, adjust the name so we
+ * look for the correct zone or forward clause.
+ */
+ labels = dns_name_countlabels(name);
+ if (dns_rdatatype_atparent(type) && labels > 1U) {
+ dns_name_init(&suffix, NULL);
+ dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
+ name = &suffix;
+ } else if (rel == dns_namereln_equal) {
+ /* If 'name' is 'apex', no further checking is needed. */
+ return (ISC_FALSE);
+ }
+
+ /*
+ * If there is a locally served zone between 'apex' and 'name'
+ * then don't cache.
+ */
+ LOCK(&fctx->res->view->lock);
+ if (fctx->res->view->zonetable != NULL) {
+ unsigned int options = DNS_ZTFIND_NOEXACT;
+ result = dns_zt_find(fctx->res->view->zonetable, name, options,
+ zfname, &zone);
+ if (zone != NULL) {
+ dns_zone_detach(&zone);
+ }
+ if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH) {
+ if (dns_name_fullcompare(zfname, apex, &(int){ 0 },
+ &(unsigned int){ 0U }) ==
+ dns_namereln_subdomain)
+ {
+ UNLOCK(&fctx->res->view->lock);
+ return (ISC_TRUE);
+ }
+ }
+ }
+ UNLOCK(&fctx->res->view->lock);
+
+ /*
+ * Look for a forward declaration below 'name'.
+ */
+ result = dns_fwdtable_find2(fctx->res->view->fwdtable, name, fname,
+ &forwarders);
+
+ if (ISFORWARDER(fctx->addrinfo)) {
+ /*
+ * See if the forwarder declaration is better.
+ */
+ if (result == ISC_R_SUCCESS) {
+ return (!dns_name_equal(fname, fctx->fwdname));
+ }
+
+ /*
+ * If the lookup failed, the configuration must have
+ * changed: play it safe and don't cache.
+ */
+ return (ISC_TRUE);
+ } else if (result == ISC_R_SUCCESS &&
+ forwarders->fwdpolicy == dns_fwdpolicy_only &&
+ !ISC_LIST_EMPTY(forwarders->fwdrs))
+ {
+ /*
+ * If 'name' is covered by a 'forward only' clause then we
+ * can't cache this repsonse.
+ */
+ return (ISC_TRUE);
+ }
+
+ return (ISC_FALSE);
+}
+
static isc_result_t
check_section(void *arg, dns_name_t *addname, dns_rdatatype_t type,
dns_section_t section)
@@ -5743,7 +5849,7 @@ check_section(void *arg, dns_name_t *add
result = dns_message_findname(fctx->rmessage, section, addname,
dns_rdatatype_any, 0, &name, NULL);
if (result == ISC_R_SUCCESS) {
- external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
+ external = ISC_TF(name_external(name, type, fctx));
if (type == dns_rdatatype_a) {
for (rdataset = ISC_LIST_HEAD(name->list);
rdataset != NULL;
@@ -6602,6 +6708,13 @@ answer_response(fetchctx_t *fctx) {
case dns_namereln_subdomain:
/*
+ * Don't accept DNAME from parent namespace.
+ */
+ if (name_external(name, dns_rdatatype_dname, fctx)) {
+ continue;
+ }
+
+ /*
* In-scope DNAME records must have at least
* as many labels as the domain being queried.
* They also must be less that qname's labels
@@ -6829,11 +6942,9 @@ answer_response(fetchctx_t *fctx) {
*/
result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);
while (!done && result == ISC_R_SUCCESS) {
- isc_boolean_t external;
name = NULL;
dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);
- external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
- if (!external) {
+ if (ISC_TF(!name_external(name, dns_rdatatype_ns, fctx))) {
/*
* We expect to find NS or SIG NS rdatasets, and
* nothing else.
Index: bind-9.9.9-P1/lib/isc/include/isc/types.h
===================================================================
--- bind-9.9.9-P1.orig/lib/isc/include/isc/types.h
+++ bind-9.9.9-P1/lib/isc/include/isc/types.h
@@ -51,6 +51,7 @@ typedef ISC_LIST(isc_buffer_t) isc_buff
typedef struct isc_constregion isc_constregion_t; /*%< Const region */
typedef struct isc_consttextregion isc_consttextregion_t; /*%< Const Text Region */
typedef struct isc_counter isc_counter_t; /*%< Counter */
+typedef int16_t isc_dscp_t; /*%< Diffserv code point */
typedef struct isc_entropy isc_entropy_t; /*%< Entropy */
typedef struct isc_entropysource isc_entropysource_t; /*%< Entropy Source */
typedef struct isc_event isc_event_t; /*%< Event */