summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
0da7358)
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/6786)
unsigned char sha1_hash[SHA_DIGEST_LENGTH];
X509_CERT_AUX *aux;
CRYPTO_RWLOCK *lock;
unsigned char sha1_hash[SHA_DIGEST_LENGTH];
X509_CERT_AUX *aux;
CRYPTO_RWLOCK *lock;
+ volatile int ex_cached;
#include <openssl/x509v3.h>
#include <openssl/x509_vfy.h>
#include "internal/x509_int.h"
#include <openssl/x509v3.h>
#include <openssl/x509_vfy.h>
#include "internal/x509_int.h"
+#include "internal/tsan_assist.h"
static void x509v3_cache_extensions(X509 *x);
static void x509v3_cache_extensions(X509 *x);
X509_EXTENSION *ex;
int i;
X509_EXTENSION *ex;
int i;
+ /* fast lock-free check, see end of the function for details. */
+ if (tsan_load((TSAN_QUALIFIER int *)&x->ex_cached))
+ return;
+
CRYPTO_THREAD_write_lock(x->lock);
if (x->ex_flags & EXFLAG_SET) {
CRYPTO_THREAD_unlock(x->lock);
CRYPTO_THREAD_write_lock(x->lock);
if (x->ex_flags & EXFLAG_SET) {
CRYPTO_THREAD_unlock(x->lock);
x509_init_sig_info(x);
x->ex_flags |= EXFLAG_SET;
CRYPTO_THREAD_unlock(x->lock);
x509_init_sig_info(x);
x->ex_flags |= EXFLAG_SET;
CRYPTO_THREAD_unlock(x->lock);
+ /*
+ * 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.
+ */
+ tsan_store((TSAN_QUALIFIER int *)&x->ex_cached, 1);