bind/backport-0037-Test-if-linked-while-holding-the-queue-lock.patch
jiangheng ad37c37958 backport some patches from community
(cherry picked from commit a9fd9ece9b9436b6103d084920c6897ef1adbae6)
2022-09-03 21:36:21 +08:00

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