summaryrefslogtreecommitdiffstats
path: root/crypto/x509v3
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2018-08-17 12:30:36 +0200
committerAndy Polyakov <appro@openssl.org>2018-08-26 17:47:49 +0200
commit7d38ca3f8bca58bf7b69e78c1f1ab69e5f429dff (patch)
tree4b95e6c1dd4f10bc9a7c649e2856579d7e5db5ab /crypto/x509v3
parentinternal/tsan_assist.h: add tsan_ld_acq and tsan_st_rel. (diff)
downloadopenssl-7d38ca3f8bca58bf7b69e78c1f1ab69e5f429dff.tar.xz
openssl-7d38ca3f8bca58bf7b69e78c1f1ab69e5f429dff.zip
x509v3/v3_purp.c: refine lock-free check in x509v3_cache_extensions.
Reviewed-by: Kurt Roeckx <kurt@roeckx.be> (Merged from https://github.com/openssl/openssl/pull/6996)
Diffstat (limited to 'crypto/x509v3')
-rw-r--r--crypto/x509v3/v3_purp.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c
index 5a535e2ade..70b0397d97 100644
--- a/crypto/x509v3/v3_purp.c
+++ b/crypto/x509v3/v3_purp.c
@@ -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);
}
/*-