]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Fix a query reference counting issue in dig
authorAram Sargsyan <aram@isc.org>
Tue, 1 Jul 2025 10:42:30 +0000 (10:42 +0000)
committerArаm Sаrgsyаn <aram@isc.org>
Thu, 10 Jul 2025 11:16:45 +0000 (11:16 +0000)
When reusing a TCP connection (because of the '+keepopen' option),
dig detaches from the query after launching it. This can cause a
crash in dig in rare cases when the "receive" callback is called
earlier than the "send" callback.

The '_cancel_lookup()' function detaches a query only if it's
found in the 'lookup->q' list. Before this commit, with one
additional detach happening before recv_done() -> _cancel_lookup()
is called, it didn't cause problems because an earlier _query_detach()
was unlinking the query from 'lookup->q' (because it was the last
reference), so the additional detach and the skipped detach were
undoing each other.

That is unless the "receive" callback was called earlier than the
"send" callback, in which case the additional detach wasn't destroying
the query (and wasn't unlinking it from 'lookup->q') because the "send"
callback's attachment was still there, and so _cancel_lookup() was
trying to "steal" the "send" callback's attachment and causing an
assertion on 'INSIST(query->sendhandle == NULL);'.

Delete the detachment which caused the described situation.

bin/dig/dighost.c

index 7756855b8a56f5f54dfc85e865dd1aed539ccf1e..c2e9b5488618c8987bdd09b2aa1342bb6fb92a2b 100644 (file)
@@ -2965,7 +2965,6 @@ start_tcp(dig_query_t *query) {
        if (keep != NULL && isc_sockaddr_equal(&keepaddr, &query->sockaddr)) {
                query->handle = keep;
                launch_next_query(query);
-               query_detach(&query);
                return;
        } else if (keep != NULL) {
                isc_nmhandle_detach(&keep);