From 72cbe648c47c9b8de34908531b08d191539dc902 Mon Sep 17 00:00:00 2001 From: Mark Andrews 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