x509v3/v3_purp.c: refine lock-free check in x509v3_cache_extensions.
authorAndy Polyakov <appro@openssl.org>
Fri, 17 Aug 2018 10:30:36 +0000 (12:30 +0200)
committerAndy Polyakov <appro@openssl.org>
Sun, 26 Aug 2018 15:47:49 +0000 (17:47 +0200)
Reviewed-by: Kurt Roeckx <kurt@roeckx.be>
(Merged from https://github.com/openssl/openssl/pull/6996)

crypto/x509v3/v3_purp.c

index 5a535e2..70b0397 100644 (file)
@@ -354,9 +354,11 @@ static void x509v3_cache_extensions(X509 *x)
     X509_EXTENSION *ex;
     int i;
 
+#ifdef tsan_ld_acq
     /* fast lock-free check, see end of the function for details. */
-    if (tsan_load((TSAN_QUALIFIER int *)&x->ex_cached))
+    if (tsan_ld_acq((TSAN_QUALIFIER int *)&x->ex_cached))
         return;
+#endif
 
     CRYPTO_THREAD_write_lock(x->lock);
     if (x->ex_flags & EXFLAG_SET) {
@@ -498,13 +500,15 @@ static void x509v3_cache_extensions(X509 *x)
     }
     x509_init_sig_info(x);
     x->ex_flags |= EXFLAG_SET;
-    CRYPTO_THREAD_unlock(x->lock);
+#ifdef tsan_st_rel
+    tsan_st_rel((TSAN_QUALIFIER int *)&x->ex_cached, 1);
     /*
-     * It has to be placed after memory barrier, which is implied by unlock.
-     * Worst thing that can happen is that another thread proceeds to lock
-     * and checks x->ex_flags & EXFLAGS_SET. See beginning of the function.
+     * Above store triggers fast lock-free check in the beginning of the
+     * function. But one has to ensure that the structure is "stable", i.e.
+     * all stores are visible on all processors. Hence the release fence.
      */
-    tsan_store((TSAN_QUALIFIER int *)&x->ex_cached, 1);
+#endif
+    CRYPTO_THREAD_unlock(x->lock);
 }
 
 /*-