]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Run resume_dslookup() from the correct task
authorOndřej Surý <ondrej@isc.org>
Fri, 22 Apr 2022 11:22:12 +0000 (13:22 +0200)
committerOndřej Surý <ondrej@isc.org>
Fri, 22 Apr 2022 12:25:32 +0000 (14:25 +0200)
The rctx_chaseds() function calls dns_resolver_createfetch(), passing
fctx->task as the target task to run resume_dslookup() from.  This
breaks task-based serialization of events as fctx->task is the task that
the dns_resolver_createfetch() caller wants to receive its fetch
completion event in; meanwhile, intermediate fetches started by the
resolver itself (e.g. related to QNAME minimization) must use
res->buckets[bucketnum].task instead.  This discrepancy may cause
trouble if the resume_dslookup() callback happens to be run concurrently
with e.g. fctx_doshutdown().

Fix by passing the correct task to dns_resolver_createfetch() in
rctx_chaseds().

lib/dns/resolver.c

index 0c69b47af13e126563aa9d5220c142a620471719..cd647fea82f21eb50757edf6d826a9d8ec5d2821 100644 (file)
@@ -9713,6 +9713,7 @@ rctx_chaseds(respctx_t *rctx, dns_message_t *message,
        fetchctx_t *fctx = rctx->fctx;
        unsigned int n;
        fetchctx_t *ev_fctx = NULL;
+       isc_task_t *task = NULL;
 
        add_bad(fctx, message, addrinfo, result, rctx->broken_type);
        fctx_cancelqueries(fctx, true, false);
@@ -9725,10 +9726,11 @@ rctx_chaseds(respctx_t *rctx, dns_message_t *message,
 
        fctx_attach(fctx, &ev_fctx);
 
+       task = fctx->res->buckets[fctx->bucketnum].task;
        result = dns_resolver_createfetch(
                fctx->res, fctx->nsname, dns_rdatatype_ns, NULL, NULL, NULL,
-               NULL, 0, fctx->options, 0, NULL, fctx->task, resume_dslookup,
-               ev_fctx, &fctx->nsrrset, NULL, &fctx->nsfetch);
+               NULL, 0, fctx->options, 0, NULL, task, resume_dslookup, ev_fctx,
+               &fctx->nsrrset, NULL, &fctx->nsfetch);
        if (result != ISC_R_SUCCESS) {
                if (result == DNS_R_DUPLICATE) {
                        result = DNS_R_SERVFAIL;