]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
don't set DNS_DISPATCHSTATE_CONNECTED until attaching handle
authorEvan Hunt <each@isc.org>
Wed, 20 Oct 2021 18:39:13 +0000 (11:39 -0700)
committerEvan Hunt <each@isc.org>
Thu, 21 Oct 2021 08:28:14 +0000 (08:28 +0000)
there was a race possible in which a dispatch was put into
the 'connected' state before it had a TCP handle attached,
which could cause an assertion failure in dns_dispatch_gettcp().

lib/dns/dispatch.c

index f1301f76e21215b48264908c5fd80feaada3aa1b..cc7273bcb4c40a5be1674af4f262f550cd6dbac5 100644 (file)
@@ -1603,6 +1603,10 @@ startrecv(isc_nmhandle_t *handle, dns_dispatch_t *disp, dns_dispentry_t *resp) {
                REQUIRE(disp != NULL);
                LOCK(&disp->lock);
                REQUIRE(disp->handle == NULL);
+               REQUIRE(atomic_compare_exchange_strong(
+                       &disp->state,
+                       &(uint_fast32_t){ DNS_DISPATCHSTATE_CONNECTING },
+                       DNS_DISPATCHSTATE_CONNECTED));
 
                isc_nmhandle_attach(handle, &disp->handle);
                dns_dispatch_attach(disp, &(dns_dispatch_t *){ NULL });
@@ -1633,10 +1637,6 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
        }
 
        if (eresult == ISC_R_SUCCESS) {
-               REQUIRE(atomic_compare_exchange_strong(
-                       &disp->state,
-                       &(uint_fast32_t){ DNS_DISPATCHSTATE_CONNECTING },
-                       DNS_DISPATCHSTATE_CONNECTED));
                startrecv(handle, disp, NULL);
        }