summaryrefslogtreecommitdiff
path: root/crypto/comp
diff options
context:
space:
mode:
authorTodd Short <tshort@akamai.com>2021-04-12 15:51:59 -0400
committerTomas Mraz <tomas@openssl.org>2021-04-22 17:41:55 +0200
commit309c6fbaceb907e5b596a158f0891f42e6694bc2 (patch)
tree0a5939ab3a04539d0805203caced2961e49fcde3 /crypto/comp
parent1fac27050176f7ed00da5649266024265678f70c (diff)
downloadopenssl-new-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.c91
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);