From: Evan Hunt Date: Wed, 18 Nov 2020 21:08:03 +0000 (-0800) Subject: dig could crash on interrupt X-Git-Tag: v9.17.8~33^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=17145e4ef46d629ad9025942b259c41e43d80701;p=thirdparty%2Fbind9.git dig could crash on interrupt dig could crash if it was shut down by an interrupt while a connection was pending. --- diff --git a/CHANGES b/CHANGES index 90a7585b92e..4a7a8d9ff0b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +5535. [bug] dig/nslookup/host could crash on shutdown after an + interrupt. [GL #2288] + 5534. [bug] The synthesised CNAME from a DNAME was incorrectly followed when the QTYPE was CNAME or ANY. [GL #2280] diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index f4a1b905c2b..7eaa453791c 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -701,7 +701,6 @@ make_empty_lookup(void) { dns_fixedname_init(&looknew->fdomain); ISC_LINK_INIT(looknew, link); ISC_LIST_INIT(looknew->q); - ISC_LIST_INIT(looknew->connecting); ISC_LIST_INIT(looknew->my_server_list); isc_refcount_init(&looknew->references, 1); @@ -1598,7 +1597,6 @@ _destroy_lookup(dig_lookup_t *lookup) { isc_refcount_destroy(&lookup->references); REQUIRE(ISC_LIST_EMPTY(lookup->q)); - REQUIRE(ISC_LIST_EMPTY(lookup->connecting)); s = ISC_LIST_HEAD(lookup->my_server_list); while (s != NULL) { @@ -1743,9 +1741,6 @@ _query_detach(dig_query_t **queryp, const char *file, unsigned int line) { if (ISC_LINK_LINKED(query, link)) { ISC_LIST_UNLINK(lookup->q, query, link); } - if (ISC_LINK_LINKED(query, clink)) { - ISC_LIST_UNLINK(lookup->connecting, query, clink); - } debug("%s:%u:query_detach(%p) = %" PRIuFAST32, file, line, query, isc_refcount_current(&query->references) - 1); @@ -1808,7 +1803,6 @@ clear_current_lookup() { dig_lookup_t *lookup = current_lookup; INSIST(!free_now); - INSIST(lookup != NULL); debug("clear_current_lookup()"); @@ -2860,7 +2854,6 @@ start_tcp(dig_query_t *query) { } else { next = NULL; } - ISC_LIST_ENQUEUE(query->lookup->connecting, query, clink); if (next != NULL) { start_tcp(next); } @@ -3229,11 +3222,15 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) { char sockstr[ISC_SOCKADDR_FORMATSIZE]; dig_lookup_t *l = NULL; + debug("tcp_connected()"); + + if (atomic_load(&cancel_now)) { + return; + } + REQUIRE(DIG_VALID_QUERY(query)); REQUIRE(query->handle == NULL); - INSIST(!free_now); - - debug("tcp_connected()"); + REQUIRE(!free_now); LOCK_LOOKUP; lookup_attach(query->lookup, &l); @@ -3584,14 +3581,14 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, LOCK_LOOKUP; lookup_attach(query->lookup, &l); + isc_refcount_decrement0(&recvcount); + debug("recvcount=%" PRIuFAST32, isc_refcount_current(&recvcount)); + if (eresult == ISC_R_CANCELED) { debug("recv_done: cancel"); goto detach_query; } - isc_refcount_decrement0(&recvcount); - debug("recvcount=%" PRIuFAST32, isc_refcount_current(&recvcount)); - TIME_NOW(&query->time_recv); if (eresult == ISC_R_TIMEDOUT && !l->tcp_mode && l->retries > 1) { @@ -4210,13 +4207,6 @@ cancel_all(void) { } query_detach(&q); } - for (q = ISC_LIST_HEAD(current_lookup->connecting); q != NULL; - q = nq) { - nq = ISC_LIST_NEXT(q, clink); - debug("canceling connecting query %p, belonging to %p", - q, current_lookup); - query_detach(&q); - } lookup_detach(¤t_lookup); } l = ISC_LIST_HEAD(lookup_list); diff --git a/bin/dig/dighost.h b/bin/dig/dighost.h index 08fdf12b17b..c91c850e888 100644 --- a/bin/dig/dighost.h +++ b/bin/dig/dighost.h @@ -101,10 +101,8 @@ typedef struct dig_searchlist dig_searchlist_t; struct dig_lookup { unsigned int magic; isc_refcount_t references; - bool pending, /*%< Pending a successful answer */ - waiting_connect, doing_xfr, ns_search_only, /*%< dig - * +nssearch, - * host -C */ + bool pending, /*%< Pending a successful answer */ + doing_xfr, ns_search_only, /*%< dig +nssearch, host -C */ identify, /*%< Append an "on server " message */ identify_previous_line, /*% Prepend a "Nameserver :" * message, with newline and tab */