The new init functions can now fail so shouldn't be void
authorMatt Caswell <matt@openssl.org>
Wed, 10 Feb 2016 13:59:15 +0000 (13:59 +0000)
committerMatt Caswell <matt@openssl.org>
Wed, 10 Feb 2016 17:40:59 +0000 (17:40 +0000)
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 <rsalz@openssl.org>
13 files changed:
apps/openssl.c
crypto/async/async.c
crypto/comp/c_zlib.c
crypto/err/err.c
crypto/evp/names.c
crypto/init.c
doc/crypto/OPENSSL_init_crypto.pod
doc/ssl/OPENSSL_init_ssl.pod
include/openssl/crypto.h
include/openssl/err.h
include/openssl/ssl.h
ssl/ssl_init.c
ssl/ssl_lib.c

index 4a6185b1e2916d935ae875b9476bdc7aa9898b91..e9c24d057296f3ee8bf6c2227bfb3fe3ecbf3ab2 100644 (file)
@@ -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();
 
index db511442bab91447de6d5ad247a879fa0de241ed..af9da35f99c3ec662edc13dbd542f016245d539c 100644 (file)
@@ -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;
     }
 
index 619765ceff7355a33a5b6b5a330e0cc87dd7e18f..baad9c66eed9d3101971e0afebacbfa83033a81a 100644 (file)
@@ -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
index d92e41e3e9d58b37ea9954391cce5ea44d0eae02..72656339c564205aca582db5bc124e5a1689854a 100644 (file)
@@ -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;
index f6e50044715c5ab6e2eae3b22722e78b47b0b626..2a5606b04014fdf56c03755babd85076a1a6e76f 100644 (file)
@@ -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;
index 3238b8002560c59e69731f2b0a21694856547a41..f01bd4d93f6e11740263a270ca54a489a1303edd 100644 (file)
@@ -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))
index 11bc1c7f7b9610d92049e665002223bd9e768f6f..67c84913cd1a97f03f43582b755a845c00a38815 100644 (file)
@@ -11,7 +11,7 @@ initialisation and deinitialisation functions
  #include <openssl/crypto.h>
 
  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
 
index d9246a53c1dd6fae26adfe221b8ea29cbdb73c23..113e93f94e125db751d622b72abc5b8f98d6601b 100644 (file)
@@ -8,7 +8,7 @@ OPENSSL_init_ssl - OpenSSL (libssl and libcrypto) initialisation
 
  #include <openssl/ssl.h>
 
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<OPENSSL_init_crypto(3)>, 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<OPENSSL_init_crypto(3)>
index 16b7fbdfaacf6bbfd108f2da9e0b914b274cf23f..d6cedecd60afee38f1c67fec1b384cd04937ee87 100644 (file)
@@ -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);
 
index 147d4da726ec98971b46a8f6c4c57530089ee60f..39f216c21c3b817f5af952dbc78cda07a0eb4890 100644 (file)
@@ -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
index d65ee9f708891de51fefe8f316b96a71b6136766..888f9a9c956b0f35987310bfca027f4186b38a31 100644 (file)
@@ -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);
index 67e431941a5bcbf1a994876519a686f94a418434..134aa00d546aae266777f81bb8de18d0c5499518 100644 (file)
@@ -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;
 }
 
index e4b5d9f05ef3cccd82ddf3350ecfbaf151f47845..d0802207ce1e1bc519c7b6217ffba51782a8c285 100644 (file)
@@ -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);