From 5931045c664b500427fb54c31fab4de3e92bb159 Mon Sep 17 00:00:00 2001 From: kenjiro <> Date: Sun, 30 Aug 2026 12:19:37 +0000 Subject: Make CRYPTO_cleanup_all_ex_data() a compatibility no-op The ex_data callback registry is process-wide, but this API could free it while other threads were still using libcrypto, resulting in a use-after-free. Retain the public symbol as a compatibility no-op and mark it deprecated. Move the actual cleanup to an internal function called by OPENSSL_cleanup(). Replace the in-tree callers with OPENSSL_cleanup() at final shutdown to preserve cleanup behavior and coverage. Document both APIs and the requirement that OPENSSL_cleanup() only be called after all threads and components have stopped using libcrypto. ok tb --- src/lib/libcrypto/crypto.h | 5 ++--- src/lib/libcrypto/crypto_ex_data.c | 15 +++++++++++-- src/lib/libcrypto/crypto_init.c | 4 ++-- src/lib/libcrypto/crypto_internal.h | 3 ++- src/lib/libcrypto/man/CRYPTO_set_ex_data.3 | 27 +++++++++++++++++++--- src/lib/libcrypto/man/OPENSSL_init_crypto.3 | 35 ++++++++++++++++++++++++----- 6 files changed, 73 insertions(+), 16 deletions(-) (limited to 'src/lib') diff --git a/src/lib/libcrypto/crypto.h b/src/lib/libcrypto/crypto.h index 9fcf868403..2a121dda85 100644 --- a/src/lib/libcrypto/crypto.h +++ b/src/lib/libcrypto/crypto.h @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto.h,v 1.80 2025/09/28 07:52:53 tb Exp $ */ +/* $OpenBSD: crypto.h,v 1.81 2026/08/30 12:19:37 kenjiro Exp $ */ /* ==================================================================== * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. * @@ -305,8 +305,7 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); * (relative to the class type involved) */ int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val); void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx); -/* This function cleans up all "ex_data" state. It mustn't be called under - * potential race-conditions. */ +/* Deprecated no-op retained for compatibility. */ void CRYPTO_cleanup_all_ex_data(void); void CRYPTO_lock(int mode, int type, const char *file, int line); diff --git a/src/lib/libcrypto/crypto_ex_data.c b/src/lib/libcrypto/crypto_ex_data.c index 233905f888..2066098653 100644 --- a/src/lib/libcrypto/crypto_ex_data.c +++ b/src/lib/libcrypto/crypto_ex_data.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto_ex_data.c,v 1.6 2025/06/15 15:58:56 tb Exp $ */ +/* $OpenBSD: crypto_ex_data.c,v 1.7 2026/08/30 12:19:37 kenjiro Exp $ */ /* * Copyright (c) 2023 Joel Sing * @@ -19,6 +19,8 @@ #include +#include "crypto_internal.h" + #define CRYPTO_EX_DATA_MAX_INDEX 32 struct crypto_ex_data { @@ -150,6 +152,16 @@ LCRYPTO_ALIAS(CRYPTO_get_ex_new_index); void CRYPTO_cleanup_all_ex_data(void) +{ +} +LCRYPTO_ALIAS(CRYPTO_cleanup_all_ex_data); + +/* + * Free process-wide ex_data state during OPENSSL_cleanup(). The caller must + * ensure that no other thread is using libcrypto. + */ +void +crypto_ex_data_cleanup(void) { struct crypto_ex_data_class *class; int i, j; @@ -173,7 +185,6 @@ CRYPTO_cleanup_all_ex_data(void) free(classes); classes = NULL; } -LCRYPTO_ALIAS(CRYPTO_cleanup_all_ex_data); static void crypto_ex_data_clear(CRYPTO_EX_DATA *exdata) diff --git a/src/lib/libcrypto/crypto_init.c b/src/lib/libcrypto/crypto_init.c index ae4914e358..5b7ce3d4fa 100644 --- a/src/lib/libcrypto/crypto_init.c +++ b/src/lib/libcrypto/crypto_init.c @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto_init.c,v 1.26 2025/06/11 07:41:12 tb Exp $ */ +/* $OpenBSD: crypto_init.c,v 1.27 2026/08/30 12:19:37 kenjiro Exp $ */ /* * Copyright (c) 2018 Bob Beck * @@ -107,7 +107,7 @@ OPENSSL_cleanup(void) /* This currently calls init... */ ERR_free_strings(); - CRYPTO_cleanup_all_ex_data(); + crypto_ex_data_cleanup(); EVP_cleanup(); X509_VERIFY_PARAM_table_cleanup(); diff --git a/src/lib/libcrypto/crypto_internal.h b/src/lib/libcrypto/crypto_internal.h index 058245e95e..2dce750724 100644 --- a/src/lib/libcrypto/crypto_internal.h +++ b/src/lib/libcrypto/crypto_internal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: crypto_internal.h,v 1.16 2025/07/22 09:18:02 jsing Exp $ */ +/* $OpenBSD: crypto_internal.h,v 1.17 2026/08/30 12:19:37 kenjiro Exp $ */ /* * Copyright (c) 2023 Joel Sing * @@ -299,5 +299,6 @@ crypto_ror_u64(uint64_t v, size_t shift) #endif void crypto_cpu_caps_init(void); +void crypto_ex_data_cleanup(void); #endif diff --git a/src/lib/libcrypto/man/CRYPTO_set_ex_data.3 b/src/lib/libcrypto/man/CRYPTO_set_ex_data.3 index ae2b04b528..00b5785533 100644 --- a/src/lib/libcrypto/man/CRYPTO_set_ex_data.3 +++ b/src/lib/libcrypto/man/CRYPTO_set_ex_data.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: CRYPTO_set_ex_data.3,v 1.17 2026/08/23 04:46:31 jsg Exp $ +.\" $OpenBSD: CRYPTO_set_ex_data.3,v 1.18 2026/08/30 12:19:37 kenjiro Exp $ .\" .\" Copyright (c) 2023 Ingo Schwarze .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: August 23 2026 $ +.Dd $Mdocdate: August 30 2026 $ .Dt CRYPTO_SET_EX_DATA 3 .Os .Sh NAME @@ -25,7 +25,8 @@ .Nm CRYPTO_new_ex_data , .Nm CRYPTO_set_ex_data , .Nm CRYPTO_get_ex_data , -.Nm CRYPTO_free_ex_data +.Nm CRYPTO_free_ex_data , +.Nm CRYPTO_cleanup_all_ex_data .Nd low-level functions for application specific data .Sh SYNOPSIS .Lb libcrypto @@ -89,6 +90,8 @@ .Fa "void *parent" .Fa "CRYPTO_EX_DATA *ad" .Fc +.Ft void +.Fn CRYPTO_cleanup_all_ex_data void .Sh DESCRIPTION The library implements the functions documented in the .Xr RSA_get_ex_new_index 3 @@ -342,6 +345,20 @@ Despite its name, does not free .Fa ad itself. +.Pp +.Fn CRYPTO_cleanup_all_ex_data +is deprecated and has no effect. +It is retained for source and binary compatibility only. +Application programs should not call it after individual operations, +from individual library components, or during process shutdown. +No replacement call is needed. +.Pp +In particular, +.Xr OPENSSL_cleanup 3 +is not a replacement for +.Fn CRYPTO_cleanup_all_ex_data . +It tears down process-wide library state and is only intended for final +shutdown after all threads using libcrypto have stopped. .Sh RETURN VALUES .Fn CRYPTO_get_ex_new_index returns a new index equal to or greater than 1 @@ -425,6 +442,10 @@ and .Fn CRYPTO_EX_dup first appeared in OpenSSL 0.9.5 and have been available since .Ox 2.7 . +.Pp +.Fn CRYPTO_cleanup_all_ex_data +first appeared in OpenSSL 0.9.7 and has been available since +.Ox 3.2 . .Sh CAVEATS If a program installs callback functions, the last call to .Fn CRYPTO_get_ex_new_index diff --git a/src/lib/libcrypto/man/OPENSSL_init_crypto.3 b/src/lib/libcrypto/man/OPENSSL_init_crypto.3 index 5c29d55aa9..24756bc396 100644 --- a/src/lib/libcrypto/man/OPENSSL_init_crypto.3 +++ b/src/lib/libcrypto/man/OPENSSL_init_crypto.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: OPENSSL_init_crypto.3,v 1.7 2025/06/09 12:43:53 schwarze Exp $ +.\" $OpenBSD: OPENSSL_init_crypto.3,v 1.8 2026/08/30 12:19:37 kenjiro Exp $ .\" Copyright (c) 2018, 2020 Ingo Schwarze .\" .\" Permission to use, copy, modify, and distribute this software for any @@ -13,13 +13,14 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: June 9 2025 $ +.Dd $Mdocdate: August 30 2026 $ .Dt OPENSSL_INIT_CRYPTO 3 .Os .Sh NAME .Nm OPENSSL_init_crypto , -.Nm OPENSSL_init -.Nd initialise the crypto library +.Nm OPENSSL_init , +.Nm OPENSSL_cleanup +.Nd initialise and shut down the crypto library .Sh SYNOPSIS .Lb libcrypto .In openssl/crypto.h @@ -30,8 +31,13 @@ .Fc .Ft void .Fn OPENSSL_init void +.Ft void +.Fn OPENSSL_cleanup void .Sh DESCRIPTION -These functions are deprecated. +.Fn OPENSSL_init_crypto +and +.Fn OPENSSL_init +are deprecated. It is never useful for an application program to call either of them explicitly. .Pp @@ -84,6 +90,21 @@ the first one have any effect. .Pp .Fn OPENSSL_init has no effect at all. +.Pp +.Fn OPENSSL_cleanup +frees process-wide resources allocated by libcrypto. +It is intended exclusively for the final shutdown of libcrypto in a process. +Before calling it, the application has to ensure that all other threads +that may use libcrypto have stopped and that no library component will use +libcrypto again. +After it returns, libcrypto cannot be reinitialized and no libcrypto or +libssl function may be called. +.Pp +.Fn OPENSSL_cleanup +is not a replacement for deprecated cleanup functions such as +.Xr CRYPTO_cleanup_all_ex_data 3 +and must not be called after individual cryptographic operations or when an +individual library component is finished with libcrypto. .Sh RETURN VALUES .Fn OPENSSL_init_crypto is intended to return 1 on success or 0 on error. @@ -101,6 +122,10 @@ It stopped having any effect in OpenSSL 1.1.1 and in .Fn OPENSSL_init_crypto first appeared in OpenSSL 1.1.0 and has been available since .Ox 6.3 . +.Pp +.Fn OPENSSL_cleanup +first appeared in OpenSSL 1.1.0 and has been available since +.Ox 7.2 . .Sh BUGS .Fn OPENSSL_init_crypto silently ignores almost all kinds of errors. -- cgit v1.2.3-55-g6feb