78 lines
2.6 KiB
Diff
78 lines
2.6 KiB
Diff
From 1f2d2611ee23f0b9200dbea8a7b65fa9f3b86e3f Mon Sep 17 00:00:00 2001
|
|
From: Aram Sargsyan <aram@isc.org>
|
|
Date: Tue, 12 Apr 2022 13:00:45 +0000
|
|
Subject: [PATCH] Fix dig +nssearch race between recv_done() and send_done()
|
|
|
|
The `send_done()` callback needs to access query's `link.next` pointer
|
|
when running in `+nssearch` mode, even if the query is already canceled
|
|
or serviced, which can happen when `recv_done()` happens to be called
|
|
earlier than `send_done()`.
|
|
|
|
Keep the next query's pointer before unlinking the query from the
|
|
lookup's queries list in `clear_query()` so that `send_done()` can
|
|
use it even if the query is cleared.
|
|
Conflict: NA
|
|
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/1f2d2611ee23f0b9200dbea8a7b65fa9f3b86e3f
|
|
---
|
|
bin/dig/dighost.c | 8 ++++++--
|
|
bin/dig/include/dig/dig.h | 1 +
|
|
2 files changed, 7 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c
|
|
index 27af3c80f1..e0ba9c2aae 100644
|
|
--- a/bin/dig/dighost.c
|
|
+++ b/bin/dig/dighost.c
|
|
@@ -1591,6 +1591,7 @@ clear_query(dig_query_t *query) {
|
|
}
|
|
|
|
if (ISC_LINK_LINKED(query, link)) {
|
|
+ query->saved_next = ISC_LIST_NEXT(query, link);
|
|
ISC_LIST_UNLINK(lookup->q, query, link);
|
|
}
|
|
if (ISC_LINK_LINKED(query, clink)) {
|
|
@@ -1609,6 +1610,7 @@ clear_query(dig_query_t *query) {
|
|
isc_buffer_invalidate(&query->lengthbuf);
|
|
|
|
if (query->waiting_senddone) {
|
|
+ debug("waiting senddone, delay freeing query");
|
|
query->pending_free = true;
|
|
} else {
|
|
query->magic = 0;
|
|
@@ -2583,6 +2585,7 @@ setup_lookup(dig_lookup_t *lookup) {
|
|
|
|
ISC_LINK_INIT(query, clink);
|
|
ISC_LINK_INIT(query, link);
|
|
+ query->saved_next = NULL;
|
|
|
|
query->magic = DIG_QUERY_MAGIC;
|
|
|
|
@@ -2617,10 +2620,11 @@ send_done(isc_task_t *_task, isc_event_t *event) {
|
|
query->waiting_senddone = false;
|
|
l = query->lookup;
|
|
|
|
- if (!query->pending_free && l->ns_search_only && !l->trace_root &&
|
|
+ if (l == current_lookup && l->ns_search_only && !l->trace_root &&
|
|
!l->tcp_mode) {
|
|
debug("sending next, since searching");
|
|
- next = ISC_LIST_NEXT(query, link);
|
|
+ next = query->pending_free ? query->saved_next
|
|
+ : ISC_LIST_NEXT(query, link);
|
|
if (next != NULL) {
|
|
send_udp(next);
|
|
}
|
|
diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h
|
|
index 79a868d1ef..9683e39892 100644
|
|
--- a/bin/dig/include/dig/dig.h
|
|
+++ b/bin/dig/include/dig/dig.h
|
|
@@ -183,6 +183,7 @@ struct dig_query {
|
|
isc_socket_t *sock;
|
|
ISC_LINK(dig_query_t) link;
|
|
ISC_LINK(dig_query_t) clink;
|
|
+ dig_query_t *saved_next;
|
|
isc_sockaddr_t sockaddr;
|
|
isc_time_t time_sent;
|
|
isc_time_t time_recv;
|
|
--
|
|
2.23.0
|
|
|