From 9553d9691ca67d6cd31573c7f6e567b182800511 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Sun, 29 Jul 2018 14:37:17 +0200 Subject: [PATCH] x509v3/v3_purp.c: re-implement lock-free check for extensions cache validity. Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/6891) (back-ported from commit f21b5b64cbbc279ef31389e6ae312690575187da) --- crypto/include/internal/x509_int.h | 1 + crypto/x509v3/v3_purp.c | 10 ++++++++++ 2 files changed, 11 insertions(+) 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; } /*- -- 2.25.1