From 0fc32b0718ec210e03b6d8623d4819ed04615a1b Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 10 Feb 2016 13:59:15 +0000 Subject: [PATCH] The new init functions can now fail so shouldn't be void The new init functions can fail if the library has already been stopped. We should be able to indicate failure with a 0 return value. Reviewed-by: Rich Salz --- apps/openssl.c | 5 +++-- crypto/async/async.c | 10 +++++++--- crypto/comp/c_zlib.c | 6 +++++- crypto/err/err.c | 3 ++- crypto/evp/names.c | 9 +++++++-- crypto/init.c | 8 +++++--- doc/crypto/OPENSSL_init_crypto.pod | 6 +++--- doc/ssl/OPENSSL_init_ssl.pod | 6 +++++- include/openssl/crypto.h | 2 +- include/openssl/err.h | 1 + include/openssl/ssl.h | 2 +- ssl/ssl_init.c | 13 ++++++++----- ssl/ssl_lib.c | 3 ++- 13 files changed, 50 insertions(+), 24 deletions(-) diff --git a/apps/openssl.c b/apps/openssl.c index 4a6185b1e2..e9c24d0572 100644 --- a/apps/openssl.c +++ b/apps/openssl.c @@ -172,8 +172,9 @@ static int apps_startup() #endif /* Set non-default library initialisation settings */ - OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN - | OPENSSL_INIT_LOAD_CONFIG, NULL); + if (!OPENSSL_init_crypto(OPENSSL_INIT_ENGINE_ALL_BUILTIN + | OPENSSL_INIT_LOAD_CONFIG, NULL)) + return 0; setup_ui_method(); diff --git a/crypto/async/async.c b/crypto/async/async.c index db511442ba..af9da35f99 100644 --- a/crypto/async/async.c +++ b/crypto/async/async.c @@ -97,7 +97,8 @@ err: static async_ctx *async_get_ctx(void) { - OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL); + if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) + return NULL; return async_arch_get_ctx(); } @@ -361,9 +362,12 @@ int ASYNC_init_thread(size_t max_size, size_t init_size) return 0; } - OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL); + if (!OPENSSL_init_crypto(OPENSSL_INIT_ASYNC, NULL)) { + ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_NOT_INITED); + return 0; + } if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_ASYNC)) { - ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_MALLOC_FAILURE); + ASYNCerr(ASYNC_F_ASYNC_INIT_THREAD, ERR_R_NOT_INITED); return 0; } diff --git a/crypto/comp/c_zlib.c b/crypto/comp/c_zlib.c index 619765ceff..baad9c66ee 100644 --- a/crypto/comp/c_zlib.c +++ b/crypto/comp/c_zlib.c @@ -289,9 +289,13 @@ COMP_METHOD *COMP_zlib(void) && p_inflateInit_ && p_deflateEnd && p_deflate && p_deflateInit_ && p_zError) zlib_loaded++; + + if (!OPENSSL_init_crypto(OPENSSL_INIT_ZLIB, NULL)) { + COMP_zlib_cleanup(); + return meth; + } if (zlib_loaded) meth = &zlib_stateful_method; - OPENSSL_init_crypto(OPENSSL_INIT_ZLIB, NULL); } } #endif diff --git a/crypto/err/err.c b/crypto/err/err.c index d92e41e3e9..72656339c5 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -894,8 +894,9 @@ ERR_STATE *ERR_get_state(void) * the first one that we just replaced. */ ERR_STATE_free(tmpp); + + /* Ignore failures from these */ OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); - /* Ignore failures from this */ ossl_init_thread_start(OPENSSL_INIT_THREAD_ERR_STATE); } return ret; diff --git a/crypto/evp/names.c b/crypto/evp/names.c index f6e5004471..2a5606b040 100644 --- a/crypto/evp/names.c +++ b/crypto/evp/names.c @@ -110,7 +110,8 @@ const EVP_CIPHER *EVP_get_cipherbyname(const char *name) { const EVP_CIPHER *cp; - OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL); + if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL)) + return NULL; cp = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH); return (cp); @@ -120,7 +121,8 @@ const EVP_MD *EVP_get_digestbyname(const char *name) { const EVP_MD *cp; - OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL); + if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL)) + return NULL; cp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); return (cp); @@ -166,6 +168,7 @@ void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph, { struct doall_cipher dc; + /* Ignore errors */ OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL); dc.fn = fn; @@ -179,6 +182,7 @@ void EVP_CIPHER_do_all_sorted(void (*fn) (const EVP_CIPHER *ciph, { struct doall_cipher dc; + /* Ignore errors */ OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL); dc.fn = fn; @@ -207,6 +211,7 @@ void EVP_MD_do_all(void (*fn) (const EVP_MD *md, { struct doall_md dc; + /* Ignore errors */ OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL); dc.fn = fn; diff --git a/crypto/init.c b/crypto/init.c index 3238b80025..f01bd4d93f 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -626,10 +626,10 @@ static const OPENSSL_INIT_SETTINGS *ossl_init_get_setting( * called prior to any threads making calls to any OpenSSL functions, * i.e. passing a non-null settings value is assumed to be single-threaded. */ -void OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) +int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { - /* XXX TODO WARNING To be updated to return a value not assert. */ - assert(!stopped); + if (stopped) + return 0; ossl_init_once_run(&base, ossl_init_base); @@ -716,6 +716,8 @@ void OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) if (opts & OPENSSL_INIT_ZLIB) { ossl_init_once_run(&zlib, ossl_init_zlib); } + + return 1; } int OPENSSL_atexit(void (*handler)(void)) diff --git a/doc/crypto/OPENSSL_init_crypto.pod b/doc/crypto/OPENSSL_init_crypto.pod index 11bc1c7f7b..67c84913cd 100644 --- a/doc/crypto/OPENSSL_init_crypto.pod +++ b/doc/crypto/OPENSSL_init_crypto.pod @@ -11,7 +11,7 @@ initialisation and deinitialisation functions #include void OPENSSL_cleanup(void); - void OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); + int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); int OPENSSL_atexit(void (*handler)(void)); void OPENSSL_thread_stop(void); @@ -206,8 +206,8 @@ using static linking should also call OPENSSL_thread_stop(). =head1 RETURN VALUES -The function OPENSSL_atexit() returns 1 on success or 0 on -error. +The functions OPENSSL_init_crypto and OPENSSL_atexit() returns 1 on success or +0 on error. =head1 SEE ALSO diff --git a/doc/ssl/OPENSSL_init_ssl.pod b/doc/ssl/OPENSSL_init_ssl.pod index d9246a53c1..113e93f94e 100644 --- a/doc/ssl/OPENSSL_init_ssl.pod +++ b/doc/ssl/OPENSSL_init_ssl.pod @@ -8,7 +8,7 @@ OPENSSL_init_ssl - OpenSSL (libssl and libcrypto) initialisation #include - void OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); + int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); =head1 DESCRIPTION @@ -63,6 +63,10 @@ these settings will also be passed internally to a call to L, so this parameter can also be used to provide libcrypto settings values. +=head1 RETURN VALUES + +The function OPENSSL_init_ssl() returns 1 on success or 0 on error. + =head1 SEE ALSO L diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index 16b7fbdfaa..d6cedecd60 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -598,7 +598,7 @@ typedef struct ossl_init_stop_st OPENSSL_INIT_STOP; /* Library initialisation functions */ void OPENSSL_cleanup(void); -void OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); +int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); int OPENSSL_atexit(void (*handler)(void)); void OPENSSL_thread_stop(void); diff --git a/include/openssl/err.h b/include/openssl/err.h index 147d4da726..39f216c21c 100644 --- a/include/openssl/err.h +++ b/include/openssl/err.h @@ -309,6 +309,7 @@ typedef struct err_state_st { # define ERR_R_PASSED_NULL_PARAMETER (3|ERR_R_FATAL) # define ERR_R_INTERNAL_ERROR (4|ERR_R_FATAL) # define ERR_R_DISABLED (5|ERR_R_FATAL) +# define ERR_R_NOT_INITED (6|ERR_R_FATAL) /* * 99 is the maximum possible ERR_R_... code, higher values are reserved for diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index d65ee9f708..888f9a9c95 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1940,7 +1940,7 @@ __owur void *SSL_CTX_get0_security_ex_data(const SSL_CTX *ctx); #define OPENSSL_INIT_SSL_DEFAULT \ (OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS) -void OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); +int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings); # ifndef OPENSSL_NO_UNIT_TEST __owur const struct openssl_ssl_test_functions *SSL_test_functions(void); diff --git a/ssl/ssl_init.c b/ssl/ssl_init.c index 67e431941a..134aa00d54 100644 --- a/ssl/ssl_init.c +++ b/ssl/ssl_init.c @@ -299,13 +299,14 @@ static void ssl_library_stop(void) * called prior to any threads making calls to any OpenSSL functions, * i.e. passing a non-null settings value is assumed to be single-threaded. */ -void OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) +int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { - /* XXX TODO WARNING To be updated to return a value not assert. */ - assert(!stopped); + if (stopped) + return 0; - OPENSSL_init_crypto(opts | OPENSSL_INIT_ADD_ALL_CIPHERS - | OPENSSL_INIT_ADD_ALL_DIGESTS, settings); + if (!OPENSSL_init_crypto(opts | OPENSSL_INIT_ADD_ALL_CIPHERS + | OPENSSL_INIT_ADD_ALL_DIGESTS, settings)) + return 0; ossl_init_once_run(&ssl_base, ossl_init_ssl_base); @@ -314,5 +315,7 @@ void OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) if (opts & OPENSSL_INIT_LOAD_SSL_STRINGS) ossl_init_once_run(&ssl_strings, ossl_init_load_ssl_strings); + + return 1; } diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index e4b5d9f05e..d0802207ce 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -2270,7 +2270,8 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) return (NULL); } - OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); + if (!OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL)) + return NULL; if (FIPS_mode() && (meth->version < TLS1_VERSION)) { SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE); -- 2.25.1