]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Address data race over 'done' in zt_test
authorMark Andrews <marka@isc.org>
Wed, 19 Aug 2020 23:31:12 +0000 (09:31 +1000)
committerMark Andrews <marka@isc.org>
Wed, 2 Sep 2020 09:35:43 +0000 (09:35 +0000)
==================
WARNING: ThreadSanitizer: data race (pid=697)
  Read of size 1 at 0x7ffcf51dd2b7 by main thread:
    #0 asyncload_zone /builds/isc-projects/bind9/lib/dns/tests/zt_test.c:206:2 (zt_test+0x4b835f)
    #1 <null> <null> (libcmocka.so.0+0x50d8)
    #2 __libc_start_main /build/glibc-vjB4T1/glibc-2.28/csu/../csu/libc-start.c:308:16 (libc.so.6+0x2409a)

  Previous write of size 1 at 0x7ffcf51dd2b7 by thread T15:
    #0 load_done /builds/isc-projects/bind9/lib/dns/tests/zt_test.c:89:8 (zt_test+0x4b8d99)
    #1 zone_asyncload /builds/isc-projects/bind9/lib/dns/zone.c:2243:3 (libdns.so.1110+0x1da0f6)
    #2 dispatch /builds/isc-projects/bind9/lib/isc/task.c:1157:7 (libisc.so.1107+0x50845)
    #3 run /builds/isc-projects/bind9/lib/isc/task.c:1331:2 (libisc.so.1107+0x4d799)

lib/dns/tests/zt_test.c

index f183c0f0ea762f5d4b8c6e207af6bca6af285fe9..f06366f396941eb371f7748ed13aea63fce33bfc 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <isc/app.h>
 #include <isc/buffer.h>
+#include <isc/mutex.h>
 #include <isc/print.h>
 #include <isc/task.h>
 #include <isc/timer.h>
@@ -41,6 +42,8 @@
 
 #include "dnstest.h"
 
+static isc_mutex_t done_lock;
+
 struct args {
        void *arg1;
        void *arg2;
@@ -86,7 +89,9 @@ load_done(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) {
        UNUSED(zone);
        UNUSED(task);
 
+       LOCK(&done_lock);
        *done = true;
+       UNLOCK(&done_lock);
        isc_app_shutdown();
        return (ISC_R_SUCCESS);
 }
@@ -95,7 +100,9 @@ static isc_result_t
 all_done(void *arg) {
        bool *done = (bool *) arg;
 
+       LOCK(&done_lock);
        *done = true;
+       UNLOCK(&done_lock);
        isc_app_shutdown();
        return (ISC_R_SUCCESS);
 }
@@ -171,6 +178,9 @@ asyncload_zone(void **state) {
 
        UNUSED(state);
 
+       result = isc_mutex_init(&done_lock);
+       assert_int_equal(result, ISC_R_SUCCESS);
+
        result = dns_test_makezone("foo", &zone, NULL, true);
        assert_int_equal(result, ISC_R_SUCCESS);
 
@@ -183,7 +193,9 @@ asyncload_zone(void **state) {
        assert_non_null(view->zonetable);
 
        assert_false(dns__zone_loadpending(zone));
+       LOCK(&done_lock);
        assert_false(done);
+       UNLOCK(&done_lock);
        zonefile = fopen("./zone.data", "wb");
        assert_non_null(zonefile);
        origfile = fopen("./testdata/zt/zone1.db", "r+b");
@@ -203,7 +215,9 @@ asyncload_zone(void **state) {
        isc_app_run();
        while (dns__zone_loadpending(zone) && i++ < 5000)
                dns_test_nap(1000);
+       LOCK(&done_lock);
        assert_true(done);
+       UNLOCK(&done_lock);
        /* The zone should now be loaded; test it */
        result = dns_zone_getdb(zone, &db);
        assert_int_equal(result, ISC_R_SUCCESS);
@@ -225,7 +239,9 @@ asyncload_zone(void **state) {
 
        while (dns__zone_loadpending(zone) && i++ < 5000)
                dns_test_nap(1000);
+       LOCK(&done_lock);
        assert_true(done);
+       UNLOCK(&done_lock);
        /* The zone should now be loaded; test it */
        result = dns_zone_getdb(zone, &db);
        assert_int_equal(result, ISC_R_SUCCESS);
@@ -241,7 +257,9 @@ asyncload_zone(void **state) {
 
        while (dns__zone_loadpending(zone) && i++ < 5000)
                dns_test_nap(1000);
+       LOCK(&done_lock);
        assert_true(done);
+       UNLOCK(&done_lock);
        /* The zone should now be loaded; test it */
        result = dns_zone_getdb(zone, &db);
        assert_int_equal(result, ISC_R_SUCCESS);
@@ -255,6 +273,9 @@ asyncload_zone(void **state) {
 
        dns_zone_detach(&zone);
        dns_view_detach(&view);
+
+       result = isc_mutex_destroy(&done_lock);
+       assert_int_equal(result, ISC_R_SUCCESS);
 }
 
 /* asynchronous zone table load */
@@ -271,6 +292,9 @@ asyncload_zt(void **state) {
 
        UNUSED(state);
 
+       result = isc_mutex_init(&done_lock);
+       assert_int_equal(result, ISC_R_SUCCESS);
+
        result = dns_test_makezone("foo", &zone1, NULL, true);
        assert_int_equal(result, ISC_R_SUCCESS);
        dns_zone_setfile(zone1, "testdata/zt/zone1.db");
@@ -299,16 +323,23 @@ asyncload_zt(void **state) {
 
        assert_false(dns__zone_loadpending(zone1));
        assert_false(dns__zone_loadpending(zone2));
+       LOCK(&done_lock);
        assert_false(done);
+       UNLOCK(&done_lock);
 
        args.arg1 = zt;
        args.arg2 = &done;
        isc_app_onrun(mctx, maintask, start_zt_asyncload, &args);
 
        isc_app_run();
-       while (!done && i++ < 5000)
+       LOCK(&done_lock);
+       while (!done && i++ < 5000) {
+               UNLOCK(&done_lock);
                dns_test_nap(1000);
+               LOCK(&done_lock);
+       }
        assert_true(done);
+       UNLOCK(&done_lock);
 
        /* Both zones should now be loaded; test them */
        result = dns_zone_getdb(zone1, &db);
@@ -332,6 +363,9 @@ asyncload_zt(void **state) {
        dns_zone_detach(&zone2);
        dns_zone_detach(&zone3);
        dns_view_detach(&view);
+
+       result = isc_mutex_destroy(&done_lock);
+       assert_int_equal(result, ISC_R_SUCCESS);
 }
 
 int