2
0
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:
Ondřej Surý
2025-04-02 16:41:57 +00:00
4 changed files with 20 additions and 7 deletions

View File

@@ -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;

View File

@@ -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;
}; };
/*% /*%

View File

@@ -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

View File

@@ -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);