mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 23:25:38 +00:00
fix crash in query_respond_any() from all records being hidden
in query_respond_any(), the assumption had previously been made that it was impossible to get past iterating the node with a return value of ISC_R_NOMORE but not have found any records, unless we were searching for RRSIG or SIG. however, it is possible for other types to exist but be hidden, such as when the zone is transitioning from insecure to secure and DNSSEC types are encountered, and this situation could trigger an assertion. removed the assertion and reorganized the code.
This commit is contained in:
@@ -6727,7 +6727,7 @@ query_addnoqnameproof(query_ctx_t *qctx) {
|
|||||||
*/
|
*/
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
query_respond_any(query_ctx_t *qctx) {
|
query_respond_any(query_ctx_t *qctx) {
|
||||||
bool found = false;
|
bool found = false, hidden = false;
|
||||||
dns_rdatasetiter_t *rdsiter = NULL;
|
dns_rdatasetiter_t *rdsiter = NULL;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
dns_rdatatype_t onetype = 0; /* type to use for minimal-any */
|
dns_rdatatype_t onetype = 0; /* type to use for minimal-any */
|
||||||
@@ -6782,11 +6782,11 @@ query_respond_any(query_ctx_t *qctx) {
|
|||||||
dns_rdatatype_isdnssec(qctx->rdataset->type))
|
dns_rdatatype_isdnssec(qctx->rdataset->type))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* The zone is transitioning from insecure
|
* The zone may be transitioning from insecure
|
||||||
* to secure. Hide the dnssec records from
|
* to secure. Hide DNSSEC records from ANY queries.
|
||||||
* ANY queries.
|
|
||||||
*/
|
*/
|
||||||
dns_rdataset_disassociate(qctx->rdataset);
|
dns_rdataset_disassociate(qctx->rdataset);
|
||||||
|
hidden = true;
|
||||||
} else if (qctx->view->minimal_any &&
|
} else if (qctx->view->minimal_any &&
|
||||||
!TCP(qctx->client) && !WANTDNSSEC(qctx->client) &&
|
!TCP(qctx->client) && !WANTDNSSEC(qctx->client) &&
|
||||||
qctx->qtype == dns_rdatatype_any &&
|
qctx->qtype == dns_rdatatype_any &&
|
||||||
@@ -6808,7 +6808,8 @@ query_respond_any(query_ctx_t *qctx) {
|
|||||||
qctx->rdataset->type == qctx->qtype) &&
|
qctx->rdataset->type == qctx->qtype) &&
|
||||||
qctx->rdataset->type != 0)
|
qctx->rdataset->type != 0)
|
||||||
{
|
{
|
||||||
if (NOQNAME(qctx->rdataset) && WANTDNSSEC(qctx->client))
|
if (NOQNAME(qctx->rdataset) &&
|
||||||
|
WANTDNSSEC(qctx->client))
|
||||||
{
|
{
|
||||||
qctx->noqname = qctx->rdataset;
|
qctx->noqname = qctx->rdataset;
|
||||||
} else {
|
} else {
|
||||||
@@ -6864,8 +6865,9 @@ query_respond_any(query_ctx_t *qctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
qctx->rdataset = ns_client_newrdataset(qctx->client);
|
qctx->rdataset = ns_client_newrdataset(qctx->client);
|
||||||
if (qctx->rdataset == NULL)
|
if (qctx->rdataset == NULL) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* We're not interested in this rdataset.
|
* We're not interested in this rdataset.
|
||||||
@@ -6886,30 +6888,30 @@ query_respond_any(query_ctx_t *qctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
CALL_HOOK(NS_QUERY_RESPOND_ANY_FOUND, qctx);
|
|
||||||
|
|
||||||
if (qctx->fname != NULL) {
|
|
||||||
dns_message_puttempname(qctx->client->message,
|
|
||||||
&qctx->fname);
|
|
||||||
}
|
|
||||||
|
|
||||||
query_addauth(qctx);
|
|
||||||
return (ns_query_done(qctx));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're here, no matching rdatasets were found. If we were
|
* Call hook if any answers were found.
|
||||||
* searching for RRSIG/SIG, that may be okay, but otherwise
|
* Do this before releasing qctx->fname, in case
|
||||||
* something's gone wrong.
|
* the hook function needs it.
|
||||||
*/
|
*/
|
||||||
INSIST(qctx->qtype == dns_rdatatype_rrsig ||
|
CALL_HOOK(NS_QUERY_RESPOND_ANY_FOUND, qctx);
|
||||||
qctx->qtype == dns_rdatatype_sig);
|
|
||||||
|
|
||||||
if (qctx->fname != NULL) {
|
|
||||||
dns_message_puttempname(qctx->client->message,
|
|
||||||
&qctx->fname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qctx->fname != NULL) {
|
||||||
|
dns_message_puttempname(qctx->client->message, &qctx->fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
/*
|
||||||
|
* At least one matching rdataset was found
|
||||||
|
*/
|
||||||
|
query_addauth(qctx);
|
||||||
|
} else if (qctx->qtype == dns_rdatatype_rrsig ||
|
||||||
|
qctx->qtype == dns_rdatatype_sig)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* No matching rdatasets were found, but we got
|
||||||
|
* here on a search for RRSIG/SIG, so that's okay.
|
||||||
|
*/
|
||||||
if (!qctx->is_zone) {
|
if (!qctx->is_zone) {
|
||||||
qctx->authoritative = false;
|
qctx->authoritative = false;
|
||||||
qctx->client->attributes &= ~NS_CLIENTATTR_RA;
|
qctx->client->attributes &= ~NS_CLIENTATTR_RA;
|
||||||
@@ -6917,7 +6919,9 @@ query_respond_any(query_ctx_t *qctx) {
|
|||||||
return (ns_query_done(qctx));
|
return (ns_query_done(qctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qctx->qtype == dns_rdatatype_rrsig && dns_db_issecure(qctx->db)) {
|
if (qctx->qtype == dns_rdatatype_rrsig &&
|
||||||
|
dns_db_issecure(qctx->db))
|
||||||
|
{
|
||||||
char namebuf[DNS_NAME_FORMATSIZE];
|
char namebuf[DNS_NAME_FORMATSIZE];
|
||||||
dns_name_format(qctx->client->query.qname,
|
dns_name_format(qctx->client->query.qname,
|
||||||
namebuf, sizeof(namebuf));
|
namebuf, sizeof(namebuf));
|
||||||
@@ -6928,6 +6932,15 @@ query_respond_any(query_ctx_t *qctx) {
|
|||||||
|
|
||||||
qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, &b);
|
qctx->fname = ns_client_newname(qctx->client, qctx->dbuf, &b);
|
||||||
return (query_sign_nodata(qctx));
|
return (query_sign_nodata(qctx));
|
||||||
|
} else if (!hidden) {
|
||||||
|
/*
|
||||||
|
* No matching rdatasets were found and nothing was
|
||||||
|
* deliberately hidden: something must have gone wrong.
|
||||||
|
*/
|
||||||
|
QUERY_ERROR(qctx, DNS_R_SERVFAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ns_query_done(qctx));
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
return (result);
|
return (result);
|
||||||
|
Reference in New Issue
Block a user