summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2018-07-29 14:37:17 +0200
committerAndy Polyakov <appro@openssl.org>2018-08-10 21:53:05 +0200
commit9553d9691ca67d6cd31573c7f6e567b182800511 (patch)
tree8332d5a2548d085c944d16f29015390b63c868ab /crypto
parent80158ae42fffe3354b160c5818f48b6a9b651538 (diff)
x509v3/v3_purp.c: re-implement lock-free check for extensions cache validity.
Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/6891) (back-ported from commit f21b5b64cbbc279ef31389e6ae312690575187da)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/include/internal/x509_int.h1
-rw-r--r--crypto/x509v3/v3_purp.c10
2 files changed, 11 insertions, 0 deletions
diff --git a/crypto/include/internal/x509_int.h b/crypto/include/internal/x509_int.h
index 2845026dd8..9a6322c0c7 100644
--- a/crypto/include/internal/x509_int.h
+++ b/crypto/include/internal/x509_int.h
@@ -166,6 +166,7 @@ struct x509_st {
unsigned char sha1_hash[SHA_DIGEST_LENGTH];
X509_CERT_AUX *aux;
CRYPTO_RWLOCK *lock;
+ volatile int ex_cached;
} /* X509 */ ;
/*
diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c
index 47ca7da5ec..7ac067229f 100644
--- a/crypto/x509v3/v3_purp.c
+++ b/crypto/x509v3/v3_purp.c
@@ -352,6 +352,10 @@ static void x509v3_cache_extensions(X509 *x)
X509_EXTENSION *ex;
int i;
+ /* fast lock-free check, see end of the function for details. */
+ if (x->ex_cached)
+ return;
+
CRYPTO_THREAD_write_lock(x->lock);
if (x->ex_flags & EXFLAG_SET) {
CRYPTO_THREAD_unlock(x->lock);
@@ -492,6 +496,12 @@ static void x509v3_cache_extensions(X509 *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.
+ */
+ x->ex_cached = 1;
}
/*-