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 4a6185b..e9c24d0 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 db51144..af9da35 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 619765c..baad9c6 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 d92e41e..7265633 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 f6e5004..2a5606b 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 3238b80..f01bd4d 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 11bc1c7..67c8491 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 d9246a5..113e93f 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 16b7fbd..d6cedec 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 147d4da..39f216c 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 d65ee9f..888f9a9 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 67e4319..134aa00 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 e4b5d9f..d080220 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);