]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
state_key_initialized had a data race.
authorMark Andrews <marka@isc.org>
Thu, 27 Aug 2020 04:33:56 +0000 (14:33 +1000)
committerMark Andrews <marka@isc.org>
Mon, 7 Sep 2020 23:25:43 +0000 (09:25 +1000)
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)

lib/dns/geoip2.c

index 9ed484c880ac4c08242707d6e7b52856573f008e..35bb7fbdb98d00ee60587b49ba099649174d29ab 100644 (file)
@@ -75,9 +75,30 @@ typedef struct geoip_state {
        MMDB_entry_s entry;
 } geoip_state_t;
 
+#if defined(ISC_PLATFORM_HAVESTDATOMIC)
+#if defined(__cplusplus)
+#include <isc/stdatomic.h>
+#else
+#include <stdatomic.h>
+#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;
                        }