Merge branch '2288-dig-interrupt-crash' into 'main'

Resolve ""dig" crashes when interrupted while waiting for a TCP connection"

Closes #2288

See merge request isc-projects/bind9!4397
This commit is contained in:
Evan Hunt 2020-11-23 20:28:46 +00:00
commit dbb4c3a0e8
3 changed files with 15 additions and 24 deletions

View file

@ -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]

View file

@ -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(&current_lookup);
}
l = ISC_LIST_HEAD(lookup_list);

View file

@ -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 <foo>" message */
identify_previous_line, /*% Prepend a "Nameserver <foo>:"
* message, with newline and tab */