From: Ondřej Surý Date: Tue, 13 Dec 2022 10:02:47 +0000 (+0100) Subject: Fix intermittent memory leak in dns_resolver unit X-Git-Tag: v9.19.9~84^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7292ee6d92943963a4a09d0f3044af2f4658cf09;p=thirdparty%2Fbind9.git Fix intermittent memory leak in dns_resolver unit A rdataset could have been left unassociated on the error path in the resume_dslookup() in the dns_resolver unit. Clone the rdataset after the error check, so it's not cloned before we check whether we can make further progress chasing DS records. --- diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index bb68d6db586..02b527365c0 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -7213,8 +7213,6 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) { dns_resolver_t *res = NULL; dns_rdataset_t *nsrdataset = NULL; dns_rdataset_t nameservers; - dns_fixedname_t fixed; - dns_name_t *domain = NULL; unsigned int n; dns_fetch_t *fetch = NULL; @@ -7278,29 +7276,25 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) { goto cleanup; default: - /* Get nameservers from fctx->nsfetch before we destroy it. */ - dns_rdataset_init(&nameservers); - if (dns_rdataset_isassociated(&fetch->private->nameservers)) { - dns_rdataset_clone(&fetch->private->nameservers, - &nameservers); - nsrdataset = &nameservers; - } - - /* Get domain from nsfetch before we destroy it. */ - domain = dns_fixedname_initname(&fixed); - dns_name_copy(fetch->private->domain, domain); - /* * If the chain of resume_dslookup() invocations managed to * chop off enough labels from the original DS owner name to * reach the top of the namespace, no further progress can be * made. Interrupt the DS chasing process, returning SERVFAIL. */ - if (dns_name_equal(fctx->nsname, domain)) { + if (dns_name_equal(fctx->nsname, fetch->private->domain)) { result = DNS_R_SERVFAIL; goto cleanup; } + /* Get nameservers from fctx->nsfetch before we destroy it. */ + dns_rdataset_init(&nameservers); + if (dns_rdataset_isassociated(&fetch->private->nameservers)) { + dns_rdataset_clone(&fetch->private->nameservers, + &nameservers); + nsrdataset = &nameservers; + } + n = dns_name_countlabels(fctx->nsname); dns_name_getlabelsequence(fctx->nsname, 1, n - 1, fctx->nsname); @@ -7308,10 +7302,10 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) { fetchctx_ref(fctx); result = dns_resolver_createfetch( - res, fctx->nsname, dns_rdatatype_ns, domain, nsrdataset, - NULL, NULL, 0, fctx->options, 0, NULL, task, - resume_dslookup, fctx, &fctx->nsrrset, NULL, - &fctx->nsfetch); + res, fctx->nsname, dns_rdatatype_ns, + fetch->private->domain, nsrdataset, NULL, NULL, 0, + fctx->options, 0, NULL, task, resume_dslookup, fctx, + &fctx->nsrrset, NULL, &fctx->nsfetch); if (result != ISC_R_SUCCESS) { fetchctx_unref(fctx); if (result == DNS_R_DUPLICATE) {