fix: usr: Fix read UAF in BIND9 dns_client_resolve() via DNAME Response

An attacker controlling a malicious DNS server returns a DNAME record,
and the we stores a pointer to resp->foundname, frees the response
structure, then uses the dangling pointer in dns_name_fullcompare()
possibly causing invalid match.  Only the `delv`is affected.  This has
been fixed.

Closes #5728

Merge branch '5728-heap-uaf-in-bind9-dns_client_resolve-via-dname-response' into 'main'

See merge request isc-projects/bind9!11570
This commit is contained in:
Ondřej Surý 2026-02-20 12:51:41 +01:00
commit 254d41f733

View file

@ -490,7 +490,7 @@ client_resfind(resctx_t *rctx, dns_fetchresponse_t *resp) {
name = dns_fixedname_name(&rctx->name);
do {
dns_name_t *fname = NULL;
dns_name_t *fname = dns_fixedname_initname(&foundname);
dns_name_t *ansname = NULL;
dns_db_t *db = NULL;
dns_dbnode_t *node = NULL;
@ -499,7 +499,6 @@ client_resfind(resctx_t *rctx, dns_fetchresponse_t *resp) {
want_restart = false;
if (resp == NULL) {
fname = dns_fixedname_initname(&foundname);
INSIST(!dns_rdataset_isassociated(rctx->rdataset));
INSIST(rctx->sigrdataset == NULL ||
!dns_rdataset_isassociated(rctx->sigrdataset));
@ -528,14 +527,13 @@ client_resfind(resctx_t *rctx, dns_fetchresponse_t *resp) {
goto done;
}
} else {
INSIST(resp != NULL);
INSIST(resp->fetch == rctx->fetch);
dns_resolver_destroyfetch(&rctx->fetch);
db = resp->cache;
node = resp->node;
result = resp->result;
vresult = resp->vresult;
fname = resp->foundname;
dns_name_copy(resp->foundname, fname);
INSIST(resp->rdataset == rctx->rdataset);
INSIST(resp->sigrdataset == rctx->sigrdataset);
dns_resolver_freefresp(&resp);