mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
fix: usr: Nested DNS validation could cause assertion failure
When multiple nested DNS validations were destroyed out of order, the EDE context could be freed before all EDE codes were copied, which could cause an assertion failure. This has been fixed. Closes #5213 Merge branch '5213-use-dns_ede_copy-in-dns_validator' into 'main' See merge request isc-projects/bind9!10365
This commit is contained in:
@@ -134,6 +134,10 @@ dns_ede_copy(dns_edectx_t *edectx_to, const dns_edectx_t *edectx_from) {
|
|||||||
REQUIRE(DNS_EDE_VALID(edectx_to));
|
REQUIRE(DNS_EDE_VALID(edectx_to));
|
||||||
REQUIRE(DNS_EDE_VALID(edectx_from));
|
REQUIRE(DNS_EDE_VALID(edectx_from));
|
||||||
|
|
||||||
|
if (edectx_to == edectx_from) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t pos = 0; pos < DNS_EDE_MAX_ERRORS; pos++) {
|
for (size_t pos = 0; pos < DNS_EDE_MAX_ERRORS; pos++) {
|
||||||
uint16_t fromcode;
|
uint16_t fromcode;
|
||||||
|
|
||||||
|
@@ -156,7 +156,9 @@ struct dns_validator {
|
|||||||
isc_counter_t *qc;
|
isc_counter_t *qc;
|
||||||
isc_counter_t *gqc;
|
isc_counter_t *gqc;
|
||||||
|
|
||||||
dns_edectx_t *edectx;
|
dns_edectx_t edectx;
|
||||||
|
|
||||||
|
dns_edectx_t *cb_edectx;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
|
@@ -243,6 +243,8 @@ validator_done(dns_validator_t *val, isc_result_t result) {
|
|||||||
val->attributes |= VALATTR_COMPLETE;
|
val->attributes |= VALATTR_COMPLETE;
|
||||||
val->result = result;
|
val->result = result;
|
||||||
|
|
||||||
|
dns_ede_copy(val->cb_edectx, &val->edectx);
|
||||||
|
|
||||||
isc_async_run(val->loop, val->cb, val);
|
isc_async_run(val->loop, val->cb, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -951,7 +953,7 @@ create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
|
|||||||
result = dns_resolver_createfetch(
|
result = dns_resolver_createfetch(
|
||||||
val->view->resolver, name, type, NULL, NULL, NULL, NULL, 0,
|
val->view->resolver, name, type, NULL, NULL, NULL, NULL, 0,
|
||||||
fopts, 0, val->qc, val->gqc, val->loop, callback, val,
|
fopts, 0, val->qc, val->gqc, val->loop, callback, val,
|
||||||
val->edectx, &val->frdataset, &val->fsigrdataset, &val->fetch);
|
&val->edectx, &val->frdataset, &val->fsigrdataset, &val->fetch);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
dns_validator_detach(&val);
|
dns_validator_detach(&val);
|
||||||
}
|
}
|
||||||
@@ -988,7 +990,7 @@ create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
|
|||||||
result = dns_validator_create(
|
result = dns_validator_create(
|
||||||
val->view, name, type, rdataset, sig, NULL, vopts, val->loop,
|
val->view, name, type, rdataset, sig, NULL, vopts, val->loop,
|
||||||
cb, val, val->nvalidations, val->nfails, val->qc, val->gqc,
|
cb, val, val->nvalidations, val->nfails, val->qc, val->gqc,
|
||||||
val->edectx, &val->subvalidator);
|
&val->edectx, &val->subvalidator);
|
||||||
if (result == ISC_R_SUCCESS) {
|
if (result == ISC_R_SUCCESS) {
|
||||||
dns_validator_attach(val, &val->subvalidator->parent);
|
dns_validator_attach(val, &val->subvalidator->parent);
|
||||||
val->subvalidator->depth = val->depth + 1;
|
val->subvalidator->depth = val->depth + 1;
|
||||||
@@ -3391,6 +3393,7 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
|
|||||||
REQUIRE(rdataset != NULL ||
|
REQUIRE(rdataset != NULL ||
|
||||||
(rdataset == NULL && sigrdataset == NULL && message != NULL));
|
(rdataset == NULL && sigrdataset == NULL && message != NULL));
|
||||||
REQUIRE(validatorp != NULL && *validatorp == NULL);
|
REQUIRE(validatorp != NULL && *validatorp == NULL);
|
||||||
|
REQUIRE(edectx != NULL);
|
||||||
|
|
||||||
result = dns_view_getsecroots(view, &kt);
|
result = dns_view_getsecroots(view, &kt);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
@@ -3412,9 +3415,11 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
|
|||||||
.cb = cb,
|
.cb = cb,
|
||||||
.arg = arg,
|
.arg = arg,
|
||||||
.rdata = DNS_RDATA_INIT,
|
.rdata = DNS_RDATA_INIT,
|
||||||
.edectx = edectx,
|
.cb_edectx = edectx,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dns_ede_init(view->mctx, &val->edectx);
|
||||||
|
|
||||||
isc_refcount_init(&val->references, 1);
|
isc_refcount_init(&val->references, 1);
|
||||||
dns_view_attach(view, &val->view);
|
dns_view_attach(view, &val->view);
|
||||||
if (message != NULL) {
|
if (message != NULL) {
|
||||||
@@ -3534,6 +3539,8 @@ destroy_validator(dns_validator_t *val) {
|
|||||||
isc_counter_detach(&val->gqc);
|
isc_counter_detach(&val->gqc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dns_ede_invalidate(&val->edectx);
|
||||||
|
|
||||||
dns_view_detach(&val->view);
|
dns_view_detach(&val->view);
|
||||||
isc_loop_detach(&val->loop);
|
isc_loop_detach(&val->loop);
|
||||||
|
|
||||||
@@ -3654,7 +3661,7 @@ validator_addede(dns_validator_t *val, uint16_t code, const char *extra) {
|
|||||||
dns_rdatatype_totext(val->type, &b);
|
dns_rdatatype_totext(val->type, &b);
|
||||||
isc_buffer_putuint8(&b, '\0');
|
isc_buffer_putuint8(&b, '\0');
|
||||||
|
|
||||||
dns_ede_add(val->edectx, code, bdata);
|
dns_ede_add(&val->edectx, code, bdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -2804,8 +2804,8 @@ fetch_and_forget(ns_client_t *client, dns_name_t *qname, dns_rdatatype_t qtype,
|
|||||||
result = dns_resolver_createfetch(
|
result = dns_resolver_createfetch(
|
||||||
client->view->resolver, qname, qtype, NULL, NULL, NULL,
|
client->view->resolver, qname, qtype, NULL, NULL, NULL,
|
||||||
peeraddr, client->message->id, options, 0, NULL,
|
peeraddr, client->message->id, options, 0, NULL,
|
||||||
client->query.qc, client->manager->loop, cb, client,
|
client->query.qc, client->manager->loop, cb, client, NULL,
|
||||||
&client->edectx, tmprdataset, NULL, fetchp);
|
tmprdataset, NULL, fetchp);
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
ns_client_putrdataset(client, &tmprdataset);
|
ns_client_putrdataset(client, &tmprdataset);
|
||||||
isc_nmhandle_detach(handlep);
|
isc_nmhandle_detach(handlep);
|
||||||
|
Reference in New Issue
Block a user