bind/2985-Add-some-DBC-checks-in-dighost-fix-race-between-clea.patch

229 lines
6.6 KiB
Diff
Raw Normal View History

2019-12-28 09:41:34 +08:00
--- a/bin/dig/dighost.c 2019-04-18 00:14:08.120000000 -0400
+++ b/bin/dig/dighost_1.c 2019-04-18 02:34:32.947000000 -0400
@@ -1822,9 +1822,9 @@ clear_query(dig_query_t *query) {
debug("clear_query(%p)", query);
- if (query->timer != NULL)
+ if (query->timer != NULL){
isc_timer_detach(&query->timer);
-
+ }
if (query->waiting_senddone) {
debug("send_done not yet called");
query->pending_free = ISC_TRUE;
@@ -1833,13 +1833,15 @@ clear_query(dig_query_t *query) {
lookup = query->lookup;
- if (lookup->current_query == query)
+ if (lookup->current_query == query){
lookup->current_query = NULL;
-
- if (ISC_LINK_LINKED(query, link))
+ }
+ if (ISC_LINK_LINKED(query, link)){
ISC_LIST_UNLINK(lookup->q, query, link);
- if (ISC_LINK_LINKED(query, clink))
+ }
+ if (ISC_LINK_LINKED(query, clink)){
ISC_LIST_UNLINK(lookup->connecting, query, clink);
+ }
if (ISC_LINK_LINKED(&query->recvbuf, link))
ISC_LIST_DEQUEUE(query->recvlist, &query->recvbuf,
link);
@@ -1856,6 +1858,7 @@ clear_query(dig_query_t *query) {
isc_mempool_put(commctx, query->recvspace);
isc_buffer_invalidate(&query->recvbuf);
isc_buffer_invalidate(&query->lengthbuf);
+ query->magic = 0;
isc_mem_free(mctx, query);
}
@@ -2807,13 +2810,14 @@ setup_lookup(dig_lookup_t *lookup) {
for (serv = ISC_LIST_HEAD(lookup->my_server_list);
serv != NULL;
- serv = ISC_LIST_NEXT(serv, link)) {
+ serv = ISC_LIST_NEXT(serv, link))
+ {
query = isc_mem_allocate(mctx, sizeof(dig_query_t));
- if (query == NULL)
+ if (query == NULL){
fatal("memory allocation failure in %s:%d",
__FILE__, __LINE__);
- debug("create query %p linked to lookup %p",
- query, lookup);
+ }
+ debug("create query %p linked to lookup %p", query, lookup);
query->lookup = lookup;
query->timer = NULL;
query->waiting_connect = ISC_FALSE;
@@ -2838,9 +2842,9 @@ setup_lookup(dig_lookup_t *lookup) {
ISC_LIST_INIT(query->lengthlist);
query->sock = NULL;
query->recvspace = isc_mempool_get(commctx);
- if (query->recvspace == NULL)
+ if (query->recvspace == NULL){
fatal("memory allocation failure");
-
+ }
isc_buffer_init(&query->recvbuf, query->recvspace, COMMSIZE);
isc_buffer_init(&query->lengthbuf, query->lengthspace, 2);
isc_buffer_init(&query->slbuf, query->slspace, 2);
@@ -2848,6 +2852,7 @@ setup_lookup(dig_lookup_t *lookup) {
ISC_LINK_INIT(query, clink);
ISC_LINK_INIT(query, link);
+ query->magic = DIG_QUERY_MAGIC;
ISC_LIST_ENQUEUE(lookup->q, query, link);
}
@@ -2856,9 +2861,10 @@ setup_lookup(dig_lookup_t *lookup) {
extrabytes = 0;
dighost_printmessage(ISC_LIST_HEAD(lookup->q), lookup->sendmsg,
ISC_TRUE);
- if (lookup->stats)
+ if (lookup->stats){
printf(";; QUERY SIZE: %u\n\n",
isc_buffer_usedlength(&lookup->renderbuf));
+ }
}
return (ISC_TRUE);
}
@@ -2893,20 +2899,26 @@ send_done(isc_task_t *_task, isc_event_t
}
query = event->ev_arg;
+ REQUIRE(DIG_VALID_QUERY(query));
query->waiting_senddone = ISC_FALSE;
l = query->lookup;
- if (l->ns_search_only && !l->trace_root && !l->tcp_mode) {
+ if (!query->pending_free && l->ns_search_only &&
+ !l->trace_root && !l->tcp_mode)
+ {
debug("sending next, since searching");
next = ISC_LIST_NEXT(query, link);
- if (next != NULL)
+ if (next != NULL){
send_udp(next);
+ }
}
isc_event_free(&event);
- if (query->pending_free)
+ if (query->pending_free){
+ query->magic = 0;
clear_query(query);
+ }
check_next_lookup(l);
UNLOCK_LOOKUP;
@@ -2924,6 +2936,7 @@ cancel_lookup(dig_lookup_t *lookup) {
debug("cancel_lookup()");
query = ISC_LIST_HEAD(lookup->q);
while (query != NULL) {
+ REQUIRE(DIG_VALID_QUERY(query));
next = ISC_LIST_NEXT(query, link);
if (query->sock != NULL) {
isc_socket_cancel(query->sock, global_task,
@@ -2943,6 +2956,7 @@ bringup_timer(dig_query_t *query, unsign
dig_lookup_t *l;
unsigned int local_timeout;
isc_result_t result;
+ REQUIRE(DIG_VALID_QUERY(query));
debug("bringup_timer()");
/*
@@ -3007,7 +3021,7 @@ send_tcp_connect(dig_query_t *query) {
isc_result_t result;
dig_query_t *next;
dig_lookup_t *l;
-
+ REQUIRE(DIG_VALID_QUERY(query));
debug("send_tcp_connect(%p)", query);
l = query->lookup;
@@ -3145,7 +3159,7 @@ send_udp(dig_query_t *query) {
isc_result_t result;
isc_buffer_t *sendbuf;
dig_query_t *next;
-
+ REQUIRE(DIG_VALID_QUERY(query));
debug("send_udp(%p)", query);
l = query->lookup;
@@ -3248,6 +3262,7 @@ connect_timeout(isc_task_t *task, isc_ev
LOCK_LOOKUP;
query = event->ev_arg;
+ REQUIRE(DIG_VALID_QUERY(query));
l = query->lookup;
isc_event_free(&event);
@@ -3335,7 +3350,7 @@ tcp_length_done(isc_task_t *task, isc_ev
LOCK_LOOKUP;
sevent = (isc_socketevent_t *)event;
query = event->ev_arg;
-
+ REQUIRE(DIG_VALID_QUERY(query));
recvcount--;
INSIST(recvcount >= 0);
@@ -3412,7 +3427,7 @@ launch_next_query(dig_query_t *query, is
isc_result_t result;
dig_lookup_t *l;
isc_buffer_t *buffer;
-
+ REQUIRE(DIG_VALID_QUERY(query));
INSIST(!free_now);
debug("launch_next_query()");
@@ -3491,7 +3506,7 @@ connect_done(isc_task_t *task, isc_event
LOCK_LOOKUP;
sevent = (isc_socketevent_t *)event;
query = sevent->ev_arg;
-
+ REQUIRE(DIG_VALID_QUERY(query));
INSIST(query->waiting_connect);
query->waiting_connect = ISC_FALSE;
@@ -4460,6 +4475,7 @@ do_lookup(dig_lookup_t *lookup) {
lookup->pending = ISC_TRUE;
query = ISC_LIST_HEAD(lookup->q);
if (query != NULL) {
+ REQUIRE(DIG_VALID_QUERY(query));
if (lookup->tcp_mode)
send_tcp_connect(query);
else
--- a/bin/dig/include/dig/dig.h 2018-09-04 00:04:41.000000000 -0400
+++ b/bin/dig/include/dig/dig_1.h 2019-04-18 02:36:44.313000000 -0400
@@ -24,6 +24,7 @@
#include <isc/formatcheck.h>
#include <isc/lang.h>
#include <isc/list.h>
+#include <isc/magic.h>
#include <isc/mem.h>
#include <isc/print.h>
#include <isc/sockaddr.h>
@@ -90,6 +91,9 @@ typedef struct dig_message dig_message_t
#endif
typedef ISC_LIST(dig_server_t) dig_serverlist_t;
typedef struct dig_searchlist dig_searchlist_t;
+#define DIG_QUERY_MAGIC ISC_MAGIC('D','i','g','q')
+
+#define DIG_VALID_QUERY(x) ISC_MAGIC_VALID((x), DIG_QUERY_MAGIC)
/*% The dig_lookup structure */
struct dig_lookup {
@@ -199,6 +203,7 @@ isc_boolean_t sigchase;
/*% The dig_query structure */
struct dig_query {
+ unsigned int magic;
dig_lookup_t *lookup;
isc_boolean_t waiting_connect,
pending_free,