From 244f84a84ba7e9551edb374911438e0c36d375cc Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Tue, 13 Oct 2020 13:00:36 +1100 Subject: [PATCH] Address TSAN error between dns_rbt_findnode() and subtractrdataset(). Having dns_rbt_findnode() in previous_closest_nsec() check of node->data is a optimisation that triggers a TSAN error with subtractrdataset(). find_closest_nsec() still needs to check if the NSEC record are active or not and look for a earlier NSEC records if it isn't. Set DNS_RBTFIND_EMPTYDATA so node->data isn't referenced without the node lock being held. WARNING: ThreadSanitizer: data race Read of size 8 at 0x000000000001 by thread T1 (mutexes: read M1, read M2): #0 dns_rbt_findnode lib/dns/rbt.c:1708 #1 previous_closest_nsec lib/dns/rbtdb.c:3760 #2 find_closest_nsec lib/dns/rbtdb.c:3942 #3 zone_find lib/dns/rbtdb.c:4091 #4 dns_db_findext lib/dns/db.c:536 #5 query_lookup lib/ns/query.c:5582 #6 ns__query_start lib/ns/query.c:5505 #7 query_setup lib/ns/query.c:5229 #8 ns_query_start lib/ns/query.c:11380 #9 ns__client_request lib/ns/client.c:2166 #10 processbuffer netmgr/tcpdns.c:230 #11 dnslisten_readcb netmgr/tcpdns.c:309 #12 read_cb netmgr/tcp.c:832 #13 #14 Previous write of size 8 at 0x000000000001 by thread T2 (mutexes: write M3): #0 subtractrdataset lib/dns/rbtdb.c:7133 #1 dns_db_subtractrdataset lib/dns/db.c:742 #2 diff_apply lib/dns/diff.c:368 #3 dns_diff_apply lib/dns/diff.c:459 #4 do_one_tuple lib/dns/update.c:247 #5 update_one_rr lib/dns/update.c:275 #6 delete_if_action lib/dns/update.c:689 #7 foreach_rr lib/dns/update.c:471 #8 delete_if lib/dns/update.c:716 #9 dns_update_signaturesinc lib/dns/update.c:1948 #10 receive_secure_serial lib/dns/zone.c:15637 #11 dispatch lib/isc/task.c:1152 #12 run lib/isc/task.c:1344 #13 Location is heap block of size 130 at 0x000000000028 allocated by thread T3: #0 malloc #1 default_memalloc lib/isc/mem.c:713 #2 mem_get lib/isc/mem.c:622 #3 mem_allocateunlocked lib/isc/mem.c:1268 #4 isc___mem_allocate lib/isc/mem.c:1288 #5 isc__mem_allocate lib/isc/mem.c:2453 #6 isc___mem_get lib/isc/mem.c:1037 #7 isc__mem_get lib/isc/mem.c:2432 #8 create_node lib/dns/rbt.c:2239 #9 dns_rbt_addnode lib/dns/rbt.c:1202 #10 dns_rbtdb_create lib/dns/rbtdb.c:8668 #11 dns_db_create lib/dns/db.c:118 #12 receive_secure_db lib/dns/zone.c:16154 #13 dispatch lib/isc/task.c:1152 #14 run lib/isc/task.c:1344 #15 Mutex M1 (0x000000000040) created at: #0 pthread_rwlock_init #1 isc_rwlock_init lib/isc/rwlock.c:39 #2 dns_rbtdb_create lib/dns/rbtdb.c:8527 #3 dns_db_create lib/dns/db.c:118 #4 receive_secure_db lib/dns/zone.c:16154 #5 dispatch lib/isc/task.c:1152 #6 run lib/isc/task.c:1344 #7 Mutex M2 (0x000000000044) created at: #0 pthread_rwlock_init #1 isc_rwlock_init lib/isc/rwlock.c:39 #2 dns_rbtdb_create lib/dns/rbtdb.c:8600 #3 dns_db_create lib/dns/db.c:118 #4 receive_secure_db lib/dns/zone.c:16154 #5 dispatch lib/isc/task.c:1152 #6 run lib/isc/task.c:1344 #7 Mutex M3 (0x000000000046) created at: #0 pthread_rwlock_init #1 isc_rwlock_init lib/isc/rwlock.c:39 #2 dns_rbtdb_create lib/dns/rbtdb.c:8600 #3 dns_db_create lib/dns/db.c:118 #4 receive_secure_db lib/dns/zone.c:16154 #5 dispatch lib/isc/task.c:1152 #6 run lib/isc/task.c:1344 #7 Thread T1 (running) created by main thread at: #0 pthread_create #1 isc_thread_create pthreads/thread.c:73 #2 isc_nm_start netmgr/netmgr.c:232 #3 create_managers bin/named/main.c:909 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 Thread T2 (running) created by main thread at: #0 pthread_create #1 isc_thread_create pthreads/thread.c:73 #2 isc_taskmgr_create lib/isc/task.c:1434 #3 create_managers bin/named/main.c:915 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 Thread T3 (running) created by main thread at: #0 pthread_create #1 isc_thread_create pthreads/thread.c:73 #2 isc_taskmgr_create lib/isc/task.c:1434 #3 create_managers bin/named/main.c:915 #4 setup bin/named/main.c:1223 #5 main bin/named/main.c:1523 SUMMARY: ThreadSanitizer: data race lib/dns/rbt.c:1708 in dns_rbt_findnode --- lib/dns/rbtdb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 5c07604956..6cad7abdd9 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -3709,7 +3709,7 @@ previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search, nsecnode = NULL; result = dns_rbt_findnode( search->rbtdb->nsec, target, NULL, &nsecnode, - nsecchain, DNS_RBTFIND_NOOPTIONS, NULL, NULL); + nsecchain, DNS_RBTFIND_EMPTYDATA, NULL, NULL); if (result == ISC_R_SUCCESS) { /* * Since this was the first loop, finding the @@ -3759,7 +3759,7 @@ previous_closest_nsec(dns_rdatatype_t type, rbtdb_search_t *search, *nodep = NULL; result = dns_rbt_findnode(search->rbtdb->tree, target, NULL, nodep, &search->chain, - DNS_RBTFIND_NOOPTIONS, NULL, NULL); + DNS_RBTFIND_EMPTYDATA, NULL, NULL); if (result == ISC_R_SUCCESS) { return (result); }