From d45f53c2cd3589aa3011fcb529bba38564010022 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 20 Aug 2020 09:31:12 +1000 Subject: [PATCH] Address data race over 'done' in zt_test ================== 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 (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 | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/lib/dns/tests/zt_test.c b/lib/dns/tests/zt_test.c index f183c0f0ea..f06366f396 100644 --- a/lib/dns/tests/zt_test.c +++ b/lib/dns/tests/zt_test.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -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