68 lines
2.2 KiB
Diff
68 lines
2.2 KiB
Diff
From 72cbe648c47c9b8de34908531b08d191539dc902 Mon Sep 17 00:00:00 2001
|
|
From: Mark Andrews <marka@isc.org>
|
|
Date: Thu, 27 Aug 2020 20:40:08 +1000
|
|
Subject: [PATCH] Test if linked while holding the queue lock
|
|
|
|
WARNING: ThreadSanitizer: data race
|
|
Read of size 8 at 0x000000000001 by thread T1:
|
|
#0 client_shutdown bin/named/client.c:849:6
|
|
#1 dispatch lib/isc/task.c:1157:7
|
|
#2 run lib/isc/task.c:1331:2
|
|
|
|
Previous write of size 8 at 0x000000000001 by thread T2 (mutexes: write M1, write M2):
|
|
#0 client_shutdown bin/named/client.c:850:3
|
|
#1 dispatch lib/isc/task.c:1157:7
|
|
#2 run lib/isc/task.c:1331:2
|
|
Conflict: NA
|
|
Reference: https://gitlab.isc.org/isc-projects/bind9/-/commit/72cbe648c47c9b8de34908531b08d191539dc902
|
|
---
|
|
bin/named/client.c | 3 +--
|
|
lib/isc/include/isc/queue.h | 19 +++++++++++++++++++
|
|
2 files changed, 20 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/bin/named/client.c b/bin/named/client.c
|
|
index 8b3227ad62..978e4d91b8 100644
|
|
--- a/bin/named/client.c
|
|
+++ b/bin/named/client.c
|
|
@@ -850,8 +850,7 @@ client_shutdown(isc_task_t *task, isc_event_t *event) {
|
|
client->shutdown_arg = NULL;
|
|
}
|
|
|
|
- if (ISC_QLINK_LINKED(client, ilink))
|
|
- ISC_QUEUE_UNLINK(client->manager->inactive, client, ilink);
|
|
+ ISC_QUEUE_UNLINKIFLINKED(client->manager->inactive, client, ilink);
|
|
|
|
client->newstate = NS_CLIENTSTATE_FREED;
|
|
client->needshutdown = false;
|
|
diff --git a/lib/isc/include/isc/queue.h b/lib/isc/include/isc/queue.h
|
|
index d682ba4940..416cefcb5d 100644
|
|
--- a/lib/isc/include/isc/queue.h
|
|
+++ b/lib/isc/include/isc/queue.h
|
|
@@ -154,4 +154,23 @@
|
|
(elt)->link.next = (elt)->link.prev = (void *)(-1); \
|
|
} while(0)
|
|
|
|
+#define ISC_QUEUE_UNLINKIFLINKED(queue, elt, link) \
|
|
+ do { \
|
|
+ LOCK(&(queue).headlock); \
|
|
+ LOCK(&(queue).taillock); \
|
|
+ if (ISC_QLINK_LINKED(elt, link)) { \
|
|
+ if ((elt)->link.prev == NULL) \
|
|
+ (queue).head = (elt)->link.next; \
|
|
+ else \
|
|
+ (elt)->link.prev->link.next = (elt)->link.next; \
|
|
+ if ((elt)->link.next == NULL) \
|
|
+ (queue).tail = (elt)->link.prev; \
|
|
+ else \
|
|
+ (elt)->link.next->link.prev = (elt)->link.prev; \
|
|
+ } \
|
|
+ UNLOCK(&(queue).taillock); \
|
|
+ UNLOCK(&(queue).headlock); \
|
|
+ (elt)->link.next = (elt)->link.prev = (void *)(-1); \
|
|
+ } while(0)
|
|
+
|
|
#endif /* ISC_QUEUE_H */
|
|
--
|
|
2.23.0
|
|
|