diff options
author | Todd Short <tshort@akamai.com> | 2021-04-12 15:51:59 -0400 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-04-22 17:41:55 +0200 |
commit | 309c6fbaceb907e5b596a158f0891f42e6694bc2 (patch) | |
tree | 0a5939ab3a04539d0805203caced2961e49fcde3 /crypto/comp | |
parent | 1fac27050176f7ed00da5649266024265678f70c (diff) | |
download | openssl-309c6fbaceb907e5b596a158f0891f42e6694bc2.tar.gz |
Add RUN_ONCE support to zlib init
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14940)
Diffstat (limited to 'crypto/comp')
-rw-r--r-- | crypto/comp/c_zlib.c | 91 |
1 files changed, 45 insertions, 46 deletions
diff --git a/crypto/comp/c_zlib.c b/crypto/comp/c_zlib.c index 4d81b5f53e..a27bbeacb1 100644 --- a/crypto/comp/c_zlib.c +++ b/crypto/comp/c_zlib.c @@ -15,6 +15,7 @@ #include <openssl/err.h> #include "crypto/cryptlib.h" #include "internal/bio.h" +#include "internal/thread_once.h" #include "comp_local.h" COMP_METHOD *COMP_zlib(void); @@ -102,7 +103,6 @@ static deflate_ft p_deflate = NULL; static deflateInit__ft p_deflateInit_ = NULL; static zError__ft p_zError = NULL; -static int zlib_loaded = 0; /* only attempt to init func pts once */ static DSO *zlib_dso = NULL; # define compress p_compress @@ -204,61 +204,58 @@ static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, return olen - state->istream.avail_out; } -#endif - -COMP_METHOD *COMP_zlib(void) +static CRYPTO_ONCE zlib_once = CRYPTO_ONCE_STATIC_INIT; +DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init) { - COMP_METHOD *meth = &zlib_method_nozlib; - -#ifdef ZLIB_SHARED +# ifdef ZLIB_SHARED /* LIBZ may be externally defined, and we should respect that value */ -# ifndef LIBZ -# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) -# define LIBZ "ZLIB1" -# elif defined(OPENSSL_SYS_VMS) -# define LIBZ "LIBZ" -# else -# define LIBZ "z" +# ifndef LIBZ +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +# define LIBZ "ZLIB1" +# elif defined(OPENSSL_SYS_VMS) +# define LIBZ "LIBZ" +# else +# define LIBZ "z" +# endif # endif -# endif - if (!zlib_loaded) { - zlib_dso = DSO_load(NULL, LIBZ, NULL, 0); - if (zlib_dso != NULL) { - p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress"); - p_inflateEnd - = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd"); - p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate"); - p_inflateInit_ - = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_"); - p_deflateEnd - = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd"); - p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate"); - p_deflateInit_ - = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_"); - p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError"); - - if (p_compress && p_inflateEnd && p_inflate - && p_inflateInit_ && p_deflateEnd - && p_deflate && p_deflateInit_ && p_zError) - zlib_loaded++; - - if (!OPENSSL_init_crypto(OPENSSL_INIT_ZLIB, NULL)) { - ossl_comp_zlib_cleanup(); - return meth; - } - if (zlib_loaded) - meth = &zlib_stateful_method; + zlib_dso = DSO_load(NULL, LIBZ, NULL, 0); + if (zlib_dso != NULL) { + p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress"); + p_inflateEnd = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd"); + p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate"); + p_inflateInit_ = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_"); + p_deflateEnd = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd"); + p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate"); + p_deflateInit_ = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_"); + p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError"); + + if (p_compress == NULL || p_inflateEnd == NULL + || p_inflate == NULL || p_inflateInit_ == NULL + || p_deflateEnd == NULL || p_deflate == NULL + || p_deflateInit_ == NULL || p_zError == NULL) { + ossl_comp_zlib_cleanup(); + return 0; } } +# endif + return 1; +} #endif -#if defined(ZLIB) - meth = &zlib_stateful_method; + +COMP_METHOD *COMP_zlib(void) +{ + COMP_METHOD *meth = &zlib_method_nozlib; + +#ifdef ZLIB + if (RUN_ONCE(&zlib_once, ossl_comp_zlib_init)) + meth = &zlib_stateful_method; #endif return meth; } +/* Also called from OPENSSL_cleanup() */ void ossl_comp_zlib_cleanup(void) { #ifdef ZLIB_SHARED @@ -318,9 +315,9 @@ const BIO_METHOD *BIO_f_zlib(void) static int bio_zlib_new(BIO *bi) { BIO_ZLIB_CTX *ctx; + # ifdef ZLIB_SHARED - (void)COMP_zlib(); - if (!zlib_loaded) { + if (!RUN_ONCE(&zlib_once, ossl_comp_zlib_init)) { ERR_raise(ERR_LIB_COMP, COMP_R_ZLIB_NOT_SUPPORTED); return 0; } @@ -346,6 +343,7 @@ static int bio_zlib_new(BIO *bi) static int bio_zlib_free(BIO *bi) { BIO_ZLIB_CTX *ctx; + if (!bi) return 0; ctx = BIO_get_data(bi); @@ -632,6 +630,7 @@ static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) static long bio_zlib_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) { BIO *next = BIO_next(b); + if (next == NULL) return 0; return BIO_callback_ctrl(next, cmd, fp); |