]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Flush client before putting it on inactive
authorMark Andrews <marka@isc.org>
Fri, 16 Oct 2020 01:06:15 +0000 (12:06 +1100)
committerMark Andrews <marka@isc.org>
Thu, 10 Dec 2020 06:31:20 +0000 (06:31 +0000)
    WARNING: ThreadSanitizer: data race
    Write of size 4 at 0x000000000001 by thread T1:
    #0 get_client bin/named/client.c:3928:16
    #1 ns_client_replace bin/named/client.c:3725:12
    #2 query_recurse bin/named/query.c:4366:13
    #3 query_find bin/named/query.c
    #4 ns_query_start bin/named/query.c:9716:8
    #5 client_request bin/named/client.c:3127:3
    #6 dispatch lib/isc/task.c:1157:7
    #7 run lib/isc/task.c:1331:2

    Previous write of size 4 at 0x000000000001 by thread T2:
    #0 exit_check bin/named/client.c:706:17
    #1 ns_client_detach bin/named/client.c:3702:8
    #2 query_resume bin/named/query.c:4186:3
    #3 dispatch lib/isc/task.c:1157:7
    #4 run lib/isc/task.c:1331:2

bin/named/client.c

index 339dd07f9afb5a00a37abc7d17d0b5f5129d916e..15fcfcd3c306755c80d90ed8e840d9401ab552b9 100644 (file)
@@ -711,6 +711,19 @@ exit_check(ns_client_t *client) {
                        if (!ns_g_clienttest && manager != NULL &&
                            !manager->exiting)
                        {
+                               /*
+                                * We are placing client on manager->inactive
+                                * locklessly and it may be picked up by a
+                                * different thread leading to TSAN errors.
+                                * The LOCK/UNLOCK will cause outstanding
+                                * writes to the client structure to be
+                                * flushed.
+                                *
+                                * queue_pop() prevents TSAN errors from
+                                * changes made by ISC_QUEUE_PUSH.
+                                */
+                               LOCK(&client->query.fetchlock);
+                               UNLOCK(&client->query.fetchlock);
                                ISC_QUEUE_PUSH(manager->inactive, client,
                                               ilink);
                        }