Always try locale initialization from OPENSSL_strcasecmp
Fixes #18172
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18282)
diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c
index c1793c9..89381f1 100644
--- a/crypto/evp/evp_lib.c
+++ b/crypto/evp/evp_lib.c
@@ -1196,8 +1196,6 @@
va_start(args, type);
- OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL);
-
if (OPENSSL_strcasecmp(type, "RSA") == 0) {
bits = va_arg(args, size_t);
params[0] = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS, &bits);
diff --git a/crypto/init.c b/crypto/init.c
index 8d51a13..cca93df 100644
--- a/crypto/init.c
+++ b/crypto/init.c
@@ -270,15 +270,6 @@
return 1;
}
-static CRYPTO_ONCE casecmp = CRYPTO_ONCE_STATIC_INIT;
-static int casecmp_inited = 0;
-DEFINE_RUN_ONCE_STATIC(ossl_init_casecmp)
-{
- int ret = ossl_init_casecmp_int();
-
- casecmp_inited = 1;
- return ret;
-}
#ifndef OPENSSL_NO_ENGINE
static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl)
@@ -451,10 +442,8 @@
OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_trace_cleanup()\n");
ossl_trace_cleanup();
- if (casecmp_inited) {
- OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_deinit_casecmp()\n");
- ossl_deinit_casecmp();
- }
+ OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_deinit_casecmp()\n");
+ ossl_deinit_casecmp();
base_inited = 0;
}
@@ -468,9 +457,6 @@
{
uint64_t tmp;
int aloaddone = 0;
- if (!RUN_ONCE(&casecmp, ossl_init_casecmp))
- return 0;
-
/* Applications depend on 0 being returned when cleanup was already done */
if (stopped) {
@@ -498,6 +484,9 @@
aloaddone = 1;
}
+ if (!ossl_init_casecmp())
+ return 0;
+
/*
* At some point we should look at this function with a view to moving
* most/all of this into OSSL_LIB_CTX.
diff --git a/crypto/o_str.c b/crypto/o_str.c
index d91ac8f..40473a4 100644
--- a/crypto/o_str.c
+++ b/crypto/o_str.c
@@ -18,6 +18,7 @@
#endif
#include <openssl/crypto.h>
#include "internal/cryptlib.h"
+#include "internal/thread_once.h"
#define DEFAULT_SEPARATOR ':'
#define CH_ZERO '\0'
@@ -347,13 +348,36 @@
}
#ifndef OPENSSL_NO_LOCALE
+# ifndef FIPS_MODULE
+static CRYPTO_ONCE casecmp = CRYPTO_ONCE_STATIC_INIT;
+DEFINE_RUN_ONCE_STATIC(init_casecmp)
+{
+ int ret = ossl_init_casecmp_int();
+
+ return ret;
+}
+
+int ossl_init_casecmp(void)
+{
+ if (!RUN_ONCE(&casecmp, init_casecmp))
+ return 0;
+ return 1;
+}
+# endif
+
static locale_t loc;
-static locale_t ossl_c_locale(void) {
+static locale_t ossl_c_locale(void)
+{
+# ifndef FIPS_MODULE
+ if (!ossl_init_casecmp())
+ return (locale_t)0;
+# endif
return loc;
}
-int ossl_init_casecmp_int(void) {
+int ossl_init_casecmp_int(void)
+{
# ifdef OPENSSL_SYS_WINDOWS
loc = _create_locale(LC_COLLATE, "C");
# else
@@ -362,9 +386,12 @@
return (loc == (locale_t)0) ? 0 : 1;
}
-void ossl_deinit_casecmp(void) {
- freelocale(loc);
- loc = (locale_t)0;
+void ossl_deinit_casecmp(void)
+{
+ if (loc != (locale_t)0) {
+ freelocale(loc);
+ loc = (locale_t)0;
+ }
}
int OPENSSL_strcasecmp(const char *s1, const char *s2)
@@ -387,11 +414,18 @@
return strncasecmp_l(s1, s2, n, l);
}
#else
-int ossl_init_casecmp_int(void) {
+int ossl_init_casecmp(void)
+{
return 1;
}
-void ossl_deinit_casecmp(void) {
+int ossl_init_casecmp_int(void)
+{
+ return 1;
+}
+
+void ossl_deinit_casecmp(void)
+{
}
int OPENSSL_strcasecmp(const char *s1, const char *s2)
diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h
index 408924f..ebb945f 100644
--- a/include/internal/cryptlib.h
+++ b/include/internal/cryptlib.h
@@ -158,5 +158,6 @@
unsigned char *ossl_hexstr2buf_sep(const char *str, long *buflen,
const char sep);
int ossl_init_casecmp_int(void);
+int ossl_init_casecmp(void);
void ossl_deinit_casecmp(void);
#endif