From: Mark Andrews Date: Thu, 27 Aug 2020 04:33:56 +0000 (+1000) Subject: state_key_initialized had a data race. X-Git-Tag: v9.11.24~30^2~15 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=3d6dda54e7b9de57a481a8213d77556720a625d2;p=thirdparty%2Fbind9.git state_key_initialized had a data race. WARNING: ThreadSanitizer: data race (pid=25060) Read of size 1 at 0x7fb4b1448098 by thread T12 (mutexes: write M802339438951732248): #0 state_key_init /builds/isc-projects/bind9/lib/dns/geoip2.c:113:7 (libdns.so.1110+0x24204a) #1 get_entry_for /builds/isc-projects/bind9/lib/dns/geoip2.c:214:11 (libdns.so.1110+0x241dc7) #2 dns_geoip_match /builds/isc-projects/bind9/lib/dns/geoip2.c:383:10 (libdns.so.1110+0x2418a5) #3 dns_aclelement_match2 /builds/isc-projects/bind9/lib/dns/acl.c:493:11 (libdns.so.1110+0x3f46b) #4 dns_acl_match2 /builds/isc-projects/bind9/lib/dns/acl.c:298:7 (libdns.so.1110+0x3f236) #5 allowed /builds/isc-projects/bind9/bin/named/client.c:1866:11 (named+0x4da797) #6 ns_client_isself /builds/isc-projects/bind9/bin/named/client.c:1931:7 (named+0x4da688) #7 notify_isself /builds/isc-projects/bind9/lib/dns/zone.c:11025:11 (libdns.so.1110+0x20f74a) #8 notify_send /builds/isc-projects/bind9/lib/dns/zone.c:11344:7 (libdns.so.1110+0x20f397) #9 notify_find_address /builds/isc-projects/bind9/lib/dns/zone.c:11148:2 (libdns.so.1110+0x20d9db) #10 zone_notify /builds/isc-projects/bind9/lib/dns/zone.c:11586:3 (libdns.so.1110+0x204d98) #11 zone_maintenance /builds/isc-projects/bind9/lib/dns/zone.c:10261:4 (libdns.so.1110+0x203d4d) #12 zone_timer /builds/isc-projects/bind9/lib/dns/zone.c:13106:2 (libdns.so.1110+0x1e847a) #13 dispatch /builds/isc-projects/bind9/lib/isc/task.c:1157:7 (libisc.so.1107+0x50845) #14 run /builds/isc-projects/bind9/lib/isc/task.c:1331:2 (libisc.so.1107+0x4d799) Previous write of size 1 at 0x7fb4b1448098 by thread T11 (mutexes: write M818946462577691672, write M52428): #0 state_key_init /builds/isc-projects/bind9/lib/dns/geoip2.c:129:27 (libdns.so.1110+0x242118) #1 get_entry_for /builds/isc-projects/bind9/lib/dns/geoip2.c:214:11 (libdns.so.1110+0x241dc7) #2 dns_geoip_match /builds/isc-projects/bind9/lib/dns/geoip2.c:383:10 (libdns.so.1110+0x2418a5) #3 dns_aclelement_match2 /builds/isc-projects/bind9/lib/dns/acl.c:493:11 (libdns.so.1110+0x3f46b) #4 dns_acl_match2 /builds/isc-projects/bind9/lib/dns/acl.c:298:7 (libdns.so.1110+0x3f236) #5 allowed /builds/isc-projects/bind9/bin/named/client.c:1866:11 (named+0x4da797) #6 ns_client_isself /builds/isc-projects/bind9/bin/named/client.c:1931:7 (named+0x4da688) #7 notify_isself /builds/isc-projects/bind9/lib/dns/zone.c:11025:11 (libdns.so.1110+0x20f74a) #8 notify_send /builds/isc-projects/bind9/lib/dns/zone.c:11344:7 (libdns.so.1110+0x20f397) #9 notify_find_address /builds/isc-projects/bind9/lib/dns/zone.c:11148:2 (libdns.so.1110+0x20d9db) #10 zone_notify /builds/isc-projects/bind9/lib/dns/zone.c:11586:3 (libdns.so.1110+0x204d98) #11 zone_maintenance /builds/isc-projects/bind9/lib/dns/zone.c:10261:4 (libdns.so.1110+0x203d4d) #12 zone_timer /builds/isc-projects/bind9/lib/dns/zone.c:13106:2 (libdns.so.1110+0x1e847a) #13 dispatch /builds/isc-projects/bind9/lib/isc/task.c:1157:7 (libisc.so.1107+0x50845) #14 run /builds/isc-projects/bind9/lib/isc/task.c:1331:2 (libisc.so.1107+0x4d799) Location is global 'state_key_initialized' of size 1 at 0x7fb4b1448098 (libdns.so.1110+0x0000002c6098) --- diff --git a/lib/dns/geoip2.c b/lib/dns/geoip2.c index 9ed484c880a..35bb7fbdb98 100644 --- a/lib/dns/geoip2.c +++ b/lib/dns/geoip2.c @@ -75,9 +75,30 @@ typedef struct geoip_state { MMDB_entry_s entry; } geoip_state_t; +#if defined(ISC_PLATFORM_HAVESTDATOMIC) +#if defined(__cplusplus) +#include +#else +#include +#endif +#endif + #ifdef ISC_PLATFORM_USETHREADS static isc_mutex_t key_mutex; -static bool state_key_initialized = false; +#if defined(ISC_PLATFORM_HAVESTDATOMIC) +static _Atomic(int32_t) state_key_initialized = 0; +#define GEOIP2_LOAD(x) atomic_load(&(x)) +#define GEOIP2_STORE(x, v) atomic_store(&(x), v) +#else +static int32_t state_key_initialized = 0; +#if defined(ISC_PLATFORM_HAVEXADD) +#define GEOIP2_LOAD(x) isc_atomic_xadd(&(x), 0) +#define GEOIP2_STORE(x, v) isc_atomic_store(&(x), v) +#else +#define GEOIP2_LOAD(x) (x) +#define GEOIP2_STORE(x, v) (x) = (v) +#endif +#endif static isc_thread_key_t state_key; static isc_once_t mutex_once = ISC_ONCE_INIT; #else @@ -110,9 +131,9 @@ state_key_init(void) { return (result); } - if (!state_key_initialized) { + if (!GEOIP2_LOAD(state_key_initialized)) { LOCK(&key_mutex); - if (!state_key_initialized) { + if (!GEOIP2_LOAD(state_key_initialized)) { int ret; if (state_mctx == NULL) { @@ -126,7 +147,7 @@ state_key_init(void) { ret = isc_thread_key_create(&state_key, free_state); if (ret == 0) { - state_key_initialized = true; + GEOIP2_STORE(state_key_initialized, 1); } else { result = ISC_R_FAILURE; }