From a2685696aad44f53286c0432bb73c481ea56e539 Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Tue, 1 Jul 2025 10:42:30 +0000 Subject: [PATCH] Fix a query reference counting issue in dig 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 | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 7756855b8a..c2e9b54886 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -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);