From ed6b2c7938ec6f07b15745d4183afc276e74c6dd Mon Sep 17 00:00:00 2001 From: Rich Salz Date: Tue, 29 Aug 2017 15:24:17 -0400 Subject: [PATCH] Add CRYPTO_thread_glock_new Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/4294) --- crypto/bio/b_addr.c | 2 +- crypto/bio/bio_meth.c | 2 +- crypto/engine/eng_lib.c | 2 +- crypto/err/err.c | 2 +- crypto/ex_data.c | 2 +- crypto/init.c | 74 ++++++++++++++++++++++++++++++++++- crypto/mem_dbg.c | 4 +- crypto/mem_sec.c | 2 +- crypto/objects/o_names.c | 2 +- crypto/rand/drbg_lib.c | 8 ++-- crypto/rand/rand_lib.c | 6 +-- crypto/store/store_register.c | 2 +- include/openssl/crypto.h | 1 + util/libcrypto.num | 1 + 14 files changed, 91 insertions(+), 19 deletions(-) diff --git a/crypto/bio/b_addr.c b/crypto/bio/b_addr.c index ba26c9144a..47e4fc20fb 100644 --- a/crypto/bio/b_addr.c +++ b/crypto/bio/b_addr.c @@ -603,7 +603,7 @@ static int addrinfo_wrap(int family, int socktype, DEFINE_RUN_ONCE_STATIC(do_bio_lookup_init) { OPENSSL_init_crypto(0, NULL); - bio_lookup_lock = CRYPTO_THREAD_lock_new(); + bio_lookup_lock = CRYPTO_THREAD_glock_new("bio_lookup"); return bio_lookup_lock != NULL; } diff --git a/crypto/bio/bio_meth.c b/crypto/bio/bio_meth.c index be6420c028..99e81c7cad 100644 --- a/crypto/bio/bio_meth.c +++ b/crypto/bio/bio_meth.c @@ -15,7 +15,7 @@ static CRYPTO_ONCE bio_type_init = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(do_bio_type_init) { - bio_type_lock = CRYPTO_THREAD_lock_new(); + bio_type_lock = CRYPTO_THREAD_glock_new("bio_type"); return bio_type_lock != NULL; } diff --git a/crypto/engine/eng_lib.c b/crypto/engine/eng_lib.c index c060a5d6ac..8e2ff9da16 100644 --- a/crypto/engine/eng_lib.c +++ b/crypto/engine/eng_lib.c @@ -21,7 +21,7 @@ CRYPTO_ONCE engine_lock_init = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE(do_engine_lock_init) { OPENSSL_init_crypto(0, NULL); - global_engine_lock = CRYPTO_THREAD_lock_new(); + global_engine_lock = CRYPTO_THREAD_glock_new("global_engine"); return global_engine_lock != NULL; } diff --git a/crypto/err/err.c b/crypto/err/err.c index ab08435af1..5e3474ffff 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -267,7 +267,7 @@ static void ERR_STATE_free(ERR_STATE *s) DEFINE_RUN_ONCE_STATIC(do_err_strings_init) { OPENSSL_init_crypto(0, NULL); - err_string_lock = CRYPTO_THREAD_lock_new(); + err_string_lock = CRYPTO_THREAD_glock_new("err_string"); int_error_hash = lh_ERR_STRING_DATA_new(err_string_data_hash, err_string_data_cmp); return err_string_lock != NULL && int_error_hash != NULL; diff --git a/crypto/ex_data.c b/crypto/ex_data.c index 22c4d3d9b9..30b16f9457 100644 --- a/crypto/ex_data.c +++ b/crypto/ex_data.c @@ -39,7 +39,7 @@ static CRYPTO_ONCE ex_data_init = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(do_ex_data_init) { OPENSSL_init_crypto(0, NULL); - ex_data_lock = CRYPTO_THREAD_lock_new(); + ex_data_lock = CRYPTO_THREAD_glock_new("ex_data"); return ex_data_lock != NULL; } diff --git a/crypto/init.c b/crypto/init.c index 074e683cc0..458520a3e2 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -27,6 +27,15 @@ #include "internal/dso.h" #include "internal/store.h" + +typedef struct global_lock_st { + CRYPTO_RWLOCK *lock; + const char *name; + struct global_lock_st *next; +} GLOBAL_LOCK; + +static GLOBAL_LOCK *global_locks; + static int stopped = 0; static void ossl_init_thread_stop(struct thread_local_inits_st *locals); @@ -65,6 +74,7 @@ struct ossl_init_stop_st { static OPENSSL_INIT_STOP *stop_handlers = NULL; static CRYPTO_RWLOCK *init_lock = NULL; +static CRYPTO_RWLOCK *glock_lock = NULL; static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT; static int base_inited = 0; @@ -84,7 +94,8 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_base) #ifndef OPENSSL_SYS_UEFI atexit(OPENSSL_cleanup); #endif - if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL) + if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL + || (glock_lock = CRYPTO_THREAD_lock_new()) == NULL) return 0; OPENSSL_cpuid_setup(); @@ -405,6 +416,14 @@ void OPENSSL_cleanup(void) return; stopped = 1; + /* Free list of global locks. */ + while (global_locks != NULL) { + GLOBAL_LOCK *next = global_locks->next; + + free(global_locks); + global_locks = next; + } + /* * Thread stop may not get automatically called by the thread library for * the very last thread in some situations, so call it directly. @@ -421,6 +440,9 @@ void OPENSSL_cleanup(void) stop_handlers = NULL; CRYPTO_THREAD_lock_free(init_lock); + init_lock = NULL; + CRYPTO_THREAD_lock_free(glock_lock); + glock_lock = NULL; /* * We assume we are single-threaded for this function, i.e. no race @@ -684,7 +706,47 @@ int OPENSSL_atexit(void (*handler)(void)) return 1; } -#ifdef OPENSSL_SYS_UNIX +#ifndef OPENSSL_SYS_UNIX +CRYPTO_RWLOCK *CRYPTO_THREAD_glock_new(const char *name) +{ + return CRYPTO_THREAD_lock_new(); +} +#else + + +/* + * Create a new global lock, return NULL on error. + */ +CRYPTO_RWLOCK *CRYPTO_THREAD_glock_new(const char *name) +{ + GLOBAL_LOCK *newlock; + + if (name == NULL + || glock_lock == NULL + || (newlock = malloc(sizeof(*newlock))) == NULL) + return CRYPTO_THREAD_lock_new(); + CRYPTO_THREAD_write_lock(glock_lock); + newlock->name = name; + newlock->lock = CRYPTO_THREAD_lock_new(); + newlock->next = global_locks; + global_locks = newlock->next; + CRYPTO_THREAD_unlock(glock_lock); + return newlock->lock; +} + +/* + * Unlock all global locks. + */ +static void unlock_all(void) +{ + GLOBAL_LOCK *lp; + + CRYPTO_THREAD_write_lock(init_lock); + for (lp = global_locks; lp != NULL; lp = lp->next) + CRYPTO_THREAD_unlock(lp->lock); + CRYPTO_THREAD_unlock(init_lock); +} + /* * The following three functions are for OpenSSL developers. This is * where we set/reset state across fork (called via pthread_atfork when @@ -698,14 +760,22 @@ int OPENSSL_atexit(void (*handler)(void)) void OPENSSL_fork_prepare(void) { + GLOBAL_LOCK *lp; + + CRYPTO_THREAD_write_lock(init_lock); + for (lp = global_locks; lp != NULL; lp = lp->next) + CRYPTO_THREAD_write_lock(lp->lock); + CRYPTO_THREAD_unlock(init_lock); } void OPENSSL_fork_parent(void) { + unlock_all(); } void OPENSSL_fork_child(void) { + unlock_all(); rand_fork(); } #endif diff --git a/crypto/mem_dbg.c b/crypto/mem_dbg.c index 70b5e62ab5..9228dcef13 100644 --- a/crypto/mem_dbg.c +++ b/crypto/mem_dbg.c @@ -90,8 +90,8 @@ static CRYPTO_THREAD_ID disabling_threadid; DEFINE_RUN_ONCE_STATIC(do_memdbg_init) { - malloc_lock = CRYPTO_THREAD_lock_new(); - long_malloc_lock = CRYPTO_THREAD_lock_new(); + malloc_lock = CRYPTO_THREAD_glock_new("malloc"); + long_malloc_lock = CRYPTO_THREAD_glock_new("long_malloc"); if (malloc_lock == NULL || long_malloc_lock == NULL || !CRYPTO_THREAD_init_local(&appinfokey, NULL)) { CRYPTO_THREAD_lock_free(malloc_lock); diff --git a/crypto/mem_sec.c b/crypto/mem_sec.c index f8470249c3..ff6e657c62 100644 --- a/crypto/mem_sec.c +++ b/crypto/mem_sec.c @@ -66,7 +66,7 @@ int CRYPTO_secure_malloc_init(size_t size, int minsize) int ret = 0; if (!secure_mem_initialized) { - sec_malloc_lock = CRYPTO_THREAD_lock_new(); + sec_malloc_lock = CRYPTO_THREAD_glock_new("sec_malloc"); if (sec_malloc_lock == NULL) return 0; if ((ret = sh_init(size, minsize)) != 0) { diff --git a/crypto/objects/o_names.c b/crypto/objects/o_names.c index 73676445c1..d0e8e05fe8 100644 --- a/crypto/objects/o_names.c +++ b/crypto/objects/o_names.c @@ -69,7 +69,7 @@ DEFINE_RUN_ONCE_STATIC(o_names_init) { CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE); names_lh = lh_OBJ_NAME_new(obj_name_hash, obj_name_cmp); - obj_lock = CRYPTO_THREAD_lock_new(); + obj_lock = CRYPTO_THREAD_glock_new("obj"); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE); return names_lh != NULL && obj_lock != NULL; } diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c index 83ddc27ee5..b7f7e4c341 100644 --- a/crypto/rand/drbg_lib.c +++ b/crypto/rand/drbg_lib.c @@ -337,11 +337,11 @@ void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx) * Creates a global DRBG with default settings. * Returns 1 on success, 0 on failure */ -static int setup_drbg(RAND_DRBG *drbg) +static int setup_drbg(RAND_DRBG *drbg, const char *name) { int ret = 1; - drbg->lock = CRYPTO_THREAD_lock_new(); + drbg->lock = CRYPTO_THREAD_glock_new(name); ret &= drbg->lock != NULL; drbg->size = RANDOMNESS_NEEDED; drbg->secure = CRYPTO_secure_malloc_initialized(); @@ -362,8 +362,8 @@ DEFINE_RUN_ONCE_STATIC(do_rand_init_drbg) { int ret = 1; - ret &= setup_drbg(&rand_drbg); - ret &= setup_drbg(&priv_drbg); + ret &= setup_drbg(&rand_drbg, "rand_drbg"); + ret &= setup_drbg(&priv_drbg, "priv_drbg"); return ret; } diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index a27281c6e1..2f2ab6a86d 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -182,13 +182,13 @@ DEFINE_RUN_ONCE_STATIC(do_rand_init) int ret = 1; #ifndef OPENSSL_NO_ENGINE - rand_engine_lock = CRYPTO_THREAD_lock_new(); + rand_engine_lock = CRYPTO_THREAD_glock_new("rand_engine"); ret &= rand_engine_lock != NULL; #endif - rand_meth_lock = CRYPTO_THREAD_lock_new(); + rand_meth_lock = CRYPTO_THREAD_glock_new("rand_meth"); ret &= rand_meth_lock != NULL; - rand_bytes.lock = CRYPTO_THREAD_lock_new(); + rand_bytes.lock = CRYPTO_THREAD_glock_new("rand_bytes"); ret &= rand_bytes.lock != NULL; rand_bytes.curr = 0; rand_bytes.size = MAX_RANDOMNESS_HELD; diff --git a/crypto/store/store_register.c b/crypto/store/store_register.c index 85c38b84dd..987ca42f8c 100644 --- a/crypto/store/store_register.c +++ b/crypto/store/store_register.c @@ -20,7 +20,7 @@ static CRYPTO_ONCE registry_init = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(do_registry_init) { - registry_lock = CRYPTO_THREAD_lock_new(); + registry_lock = CRYPTO_THREAD_glock_new("registry"); return registry_lock != NULL; } diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index cebde9734b..c4a36afb7e 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -68,6 +68,7 @@ typedef struct { typedef void CRYPTO_RWLOCK; CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void); +CRYPTO_RWLOCK *CRYPTO_THREAD_glock_new(const char *name); int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock); int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock); int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock); diff --git a/util/libcrypto.num b/util/libcrypto.num index d955f9166b..8a276b96cd 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4389,3 +4389,4 @@ EVP_aria_256_ccm 4332 1_1_1 EXIST::FUNCTION:ARIA EVP_aria_128_gcm 4333 1_1_1 EXIST::FUNCTION:ARIA EVP_aria_128_ccm 4334 1_1_1 EXIST::FUNCTION:ARIA EVP_aria_192_gcm 4335 1_1_1 EXIST::FUNCTION:ARIA +CRYPTO_THREAD_glock_new 4336 1_1_1 EXIST::FUNCTION: -- 2.25.1