mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 07:40:00 -04:00
4531. [security] 'is_zone' was not being properly updated by redirect2
and subsequently preserved leading to an assertion
failure. (CVE-2016-9778) [RT #43837]
This commit is contained in:
parent
eff07b51df
commit
d376792dae
3 changed files with 17 additions and 9 deletions
4
CHANGES
4
CHANGES
|
|
@ -42,7 +42,9 @@
|
|||
4532. [contrib] Make gen-data-queryperf.py python 3 compatible.
|
||||
[RT #43836]
|
||||
|
||||
4531. [placeholder]
|
||||
4531. [security] 'is_zone' was not being properly updated by redirect2
|
||||
and subsequently preserved leading to an assertion
|
||||
failure. (CVE-2016-9778) [RT #43837]
|
||||
|
||||
4530. [bug] Change 4489 broke the handling of CNAME -> DNAME
|
||||
in responses resulting in SERVFAIL being returned.
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ struct ns_query {
|
|||
dns_rdataset_t * rdataset;
|
||||
dns_rdataset_t * sigrdataset;
|
||||
isc_boolean_t authoritative;
|
||||
isc_boolean_t is_zone;
|
||||
} redirect;
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -701,6 +701,8 @@ ns_query_init(ns_client_t *client) {
|
|||
client->query.redirect.result = ISC_R_SUCCESS;
|
||||
client->query.redirect.rdataset = NULL;
|
||||
client->query.redirect.sigrdataset = NULL;
|
||||
client->query.redirect.authoritative = ISC_FALSE;
|
||||
client->query.redirect.is_zone = ISC_FALSE;
|
||||
dns_fixedname_init(&client->query.redirect.fixed);
|
||||
client->query.redirect.fname =
|
||||
dns_fixedname_name(&client->query.redirect.fixed);
|
||||
|
|
@ -1176,7 +1178,6 @@ query_getcachedb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
|
|||
return (result);
|
||||
}
|
||||
|
||||
|
||||
static inline isc_result_t
|
||||
query_getdb(ns_client_t *client, dns_name_t *name, dns_rdatatype_t qtype,
|
||||
unsigned int options, dns_zone_t **zonep, dns_db_t **dbp,
|
||||
|
|
@ -6306,7 +6307,7 @@ redirect(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
|
|||
static isc_result_t
|
||||
redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
|
||||
dns_dbnode_t **nodep, dns_db_t **dbp, dns_dbversion_t **versionp,
|
||||
dns_rdatatype_t qtype)
|
||||
dns_rdatatype_t qtype, isc_boolean_t *is_zonep)
|
||||
{
|
||||
dns_db_t *db = NULL;
|
||||
dns_dbnode_t *node = NULL;
|
||||
|
|
@ -6320,8 +6321,8 @@ redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
|
|||
dns_clientinfo_t ci;
|
||||
dns_dbversion_t *version = NULL;
|
||||
dns_zone_t *zone = NULL;
|
||||
isc_boolean_t is_zone;
|
||||
unsigned int options;
|
||||
isc_boolean_t is_zonep = ISC_FALSE;
|
||||
|
||||
CTRACE(ISC_LOG_DEBUG(3), "redirect2");
|
||||
|
||||
|
|
@ -6381,7 +6382,7 @@ redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
|
|||
|
||||
options = 0;
|
||||
result = query_getdb(client, redirectname, qtype, options, &zone,
|
||||
&db, &version, &is_zonep);
|
||||
&db, &version, &is_zone);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (ISC_R_NOTFOUND);
|
||||
if (zone != NULL)
|
||||
|
|
@ -6459,6 +6460,7 @@ redirect2(ns_client_t *client, dns_name_t *name, dns_rdataset_t *rdataset,
|
|||
dns_db_attach(db, dbp);
|
||||
dns_db_detachnode(db, &node);
|
||||
dns_db_detach(&db);
|
||||
*is_zonep = is_zone;
|
||||
*versionp = version;
|
||||
|
||||
client->query.attributes |= (NS_QUERYATTR_NOAUTHORITY |
|
||||
|
|
@ -6651,6 +6653,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
RESTORE(node, client->query.redirect.node);
|
||||
RESTORE(zone, client->query.redirect.zone);
|
||||
authoritative = client->query.redirect.authoritative;
|
||||
is_zone = client->query.redirect.is_zone;
|
||||
|
||||
/*
|
||||
* Free resources used while recursing.
|
||||
|
|
@ -6746,7 +6749,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
isc_event_free(ISC_EVENT_PTR(&event));
|
||||
} else if (REDIRECT(client)) {
|
||||
result = client->query.redirect.result;
|
||||
is_zone = ISC_TF(result == DNS_R_NXDOMAIN);
|
||||
is_zone = client->query.redirect.is_zone;
|
||||
} else {
|
||||
result = event->result;
|
||||
}
|
||||
|
|
@ -7785,7 +7788,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
/* FALLTHROUGH */
|
||||
|
||||
case DNS_R_NXDOMAIN:
|
||||
INSIST(is_zone);
|
||||
INSIST(is_zone || REDIRECT(client));
|
||||
if (!empty_wild) {
|
||||
tresult = redirect(client, fname, rdataset, &node,
|
||||
&db, &version, type);
|
||||
|
|
@ -7804,7 +7807,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
goto ncache_nxrrset;
|
||||
}
|
||||
tresult = redirect2(client, fname, rdataset, &node,
|
||||
&db, &version, type);
|
||||
&db, &version, type, &is_zone);
|
||||
if (tresult == DNS_R_CONTINUE) {
|
||||
inc_stats(client,
|
||||
dns_nsstatscounter_nxdomainredirect_rlookup);
|
||||
|
|
@ -7822,6 +7825,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
NULL);
|
||||
client->query.redirect.authoritative =
|
||||
authoritative;
|
||||
client->query.redirect.is_zone = is_zone;
|
||||
goto cleanup;
|
||||
}
|
||||
if (tresult == ISC_R_SUCCESS) {
|
||||
|
|
@ -7919,7 +7923,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
goto ncache_nxrrset;
|
||||
}
|
||||
tresult = redirect2(client, fname, rdataset, &node,
|
||||
&db, &version, type);
|
||||
&db, &version, type, &is_zone);
|
||||
if (tresult == DNS_R_CONTINUE) {
|
||||
inc_stats(client,
|
||||
dns_nsstatscounter_nxdomainredirect_rlookup);
|
||||
|
|
@ -7934,6 +7938,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
|||
dns_name_copy(fname, client->query.redirect.fname,
|
||||
NULL);
|
||||
client->query.redirect.authoritative = authoritative;
|
||||
client->query.redirect.is_zone = is_zone;
|
||||
goto cleanup;
|
||||
}
|
||||
if (tresult == ISC_R_SUCCESS) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue