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 ++++++++++++++++++++++---- src/regress/lib/libcrypto/dsa/dsatest.c | 7 +++--- src/regress/lib/libcrypto/ec/ectest.c | 5 ++-- src/regress/lib/libcrypto/ecdsa/ecdsatest.c | 5 ++-- src/regress/lib/libcrypto/evp/evptest.c | 6 ++--- src/regress/lib/libcrypto/exdata/exdata_test.c | 5 ++-- src/regress/lib/libcrypto/pbkdf2/pbkdf2.c | 6 ++--- src/regress/lib/libssl/ssl/ssltest.c | 8 +++--- src/usr.bin/openssl/openssl.c | 9 +++---- 14 files changed, 93 insertions(+), 47 deletions(-) (limited to 'src') 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. diff --git a/src/regress/lib/libcrypto/dsa/dsatest.c b/src/regress/lib/libcrypto/dsa/dsatest.c index 3a761961f0..79c83e04bc 100644 --- a/src/regress/lib/libcrypto/dsa/dsatest.c +++ b/src/regress/lib/libcrypto/dsa/dsatest.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dsatest.c,v 1.11 2024/02/29 20:04:43 tb Exp $ */ +/* $OpenBSD: dsatest.c,v 1.12 2026/08/30 12:19:37 kenjiro Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -193,11 +193,10 @@ end: if (!ret) ERR_print_errors(bio_err); DSA_free(dsa); - CRYPTO_cleanup_all_ex_data(); - ERR_remove_thread_state(NULL); - ERR_free_strings(); BIO_free(bio_err); bio_err = NULL; + ERR_remove_thread_state(NULL); + OPENSSL_cleanup(); return !ret; } diff --git a/src/regress/lib/libcrypto/ec/ectest.c b/src/regress/lib/libcrypto/ec/ectest.c index 3e81954174..edfc9ada46 100644 --- a/src/regress/lib/libcrypto/ec/ectest.c +++ b/src/regress/lib/libcrypto/ec/ectest.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ectest.c,v 1.36 2025/07/23 07:40:07 tb Exp $ */ +/* $OpenBSD: ectest.c,v 1.37 2026/08/30 12:19:37 kenjiro Exp $ */ /* * Originally written by Bodo Moeller for the OpenSSL project. */ @@ -668,9 +668,8 @@ main(int argc, char *argv[]) prime_field_tests(); - CRYPTO_cleanup_all_ex_data(); - ERR_free_strings(); ERR_remove_thread_state(NULL); + OPENSSL_cleanup(); return 0; } diff --git a/src/regress/lib/libcrypto/ecdsa/ecdsatest.c b/src/regress/lib/libcrypto/ecdsa/ecdsatest.c index ef724c74b5..cfc1317bda 100644 --- a/src/regress/lib/libcrypto/ecdsa/ecdsatest.c +++ b/src/regress/lib/libcrypto/ecdsa/ecdsatest.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ecdsatest.c,v 1.18 2023/11/19 13:11:06 tb Exp $ */ +/* $OpenBSD: ecdsatest.c,v 1.19 2026/08/30 12:19:37 kenjiro Exp $ */ /* * Written by Nils Larsch for the OpenSSL project. */ @@ -337,9 +337,8 @@ main(void) ERR_print_errors_fp(stdout); } - CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); - ERR_free_strings(); + OPENSSL_cleanup(); return failed; } diff --git a/src/regress/lib/libcrypto/evp/evptest.c b/src/regress/lib/libcrypto/evp/evptest.c index 6c47e38a5f..b83ef33ce9 100644 --- a/src/regress/lib/libcrypto/evp/evptest.c +++ b/src/regress/lib/libcrypto/evp/evptest.c @@ -1,4 +1,4 @@ -/* $OpenBSD: evptest.c,v 1.15 2024/03/30 09:49:59 tb Exp $ */ +/* $OpenBSD: evptest.c,v 1.16 2026/08/30 12:19:37 kenjiro Exp $ */ /* Written by Ben Laurie, 2001 */ /* * Copyright (c) 2001 The OpenSSL Project. All rights reserved. @@ -431,10 +431,8 @@ main(int argc, char **argv) } fclose(f); - EVP_cleanup(); - CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); - ERR_free_strings(); + OPENSSL_cleanup(); return 0; } diff --git a/src/regress/lib/libcrypto/exdata/exdata_test.c b/src/regress/lib/libcrypto/exdata/exdata_test.c index a82cb4a66c..7c283470f1 100644 --- a/src/regress/lib/libcrypto/exdata/exdata_test.c +++ b/src/regress/lib/libcrypto/exdata/exdata_test.c @@ -1,4 +1,4 @@ -/* $OpenBSD: exdata_test.c,v 1.3 2024/10/02 14:12:21 jsing Exp $ */ +/* $OpenBSD: exdata_test.c,v 1.4 2026/08/30 12:19:37 kenjiro Exp $ */ /* * Copyright (c) 2023 Joel Sing * @@ -264,8 +264,7 @@ main(int argc, char **argv) failed |= ex_data_test(); failed |= ex_new_index_test(); - /* Force a clean up. */ - CRYPTO_cleanup_all_ex_data(); + OPENSSL_cleanup(); return failed; } diff --git a/src/regress/lib/libcrypto/pbkdf2/pbkdf2.c b/src/regress/lib/libcrypto/pbkdf2/pbkdf2.c index 33b683f0a0..4a11126c34 100644 --- a/src/regress/lib/libcrypto/pbkdf2/pbkdf2.c +++ b/src/regress/lib/libcrypto/pbkdf2/pbkdf2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pbkdf2.c,v 1.3 2023/11/19 13:11:06 tb Exp $ */ +/* $OpenBSD: pbkdf2.c,v 1.4 2026/08/30 12:19:37 kenjiro Exp $ */ /* Written by Christian Heimes, 2013 */ /* * Copyright (c) 2013 The OpenSSL Project. All rights reserved. @@ -196,9 +196,7 @@ main(int argc,char **argv) test_p5_pbkdf2(n, "sha512", test, sha512_results[n]); } - EVP_cleanup(); - CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); - ERR_free_strings(); + OPENSSL_cleanup(); return 0; } diff --git a/src/regress/lib/libssl/ssl/ssltest.c b/src/regress/lib/libssl/ssl/ssltest.c index 27adeeaf17..3bc5f99617 100644 --- a/src/regress/lib/libssl/ssl/ssltest.c +++ b/src/regress/lib/libssl/ssl/ssltest.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssltest.c,v 1.45 2024/03/01 03:45:16 tb Exp $ */ +/* $OpenBSD: ssltest.c,v 1.46 2026/08/30 12:19:37 kenjiro Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -759,11 +759,9 @@ end: SSL_CTX_free(c_ctx); BIO_free(bio_stdout); - CRYPTO_cleanup_all_ex_data(); - ERR_free_strings(); - ERR_remove_thread_state(NULL); - EVP_cleanup(); BIO_free(bio_err); + ERR_remove_thread_state(NULL); + OPENSSL_cleanup(); exit(ret); return ret; diff --git a/src/usr.bin/openssl/openssl.c b/src/usr.bin/openssl/openssl.c index 056912a9ed..b9d63fa43a 100644 --- a/src/usr.bin/openssl/openssl.c +++ b/src/usr.bin/openssl/openssl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: openssl.c,v 1.41 2026/01/02 00:14:24 kenjiro Exp $ */ +/* $OpenBSD: openssl.c,v 1.42 2026/08/30 12:19:37 kenjiro Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -360,10 +360,6 @@ openssl_shutdown(void) CONF_modules_unload(1); destroy_ui(); OBJ_cleanup(); - EVP_cleanup(); - CRYPTO_cleanup_all_ex_data(); - ERR_remove_thread_state(NULL); - ERR_free_strings(); } int @@ -461,6 +457,9 @@ main(int argc, char **argv) BIO_free(bio_err); bio_err = NULL; } + ERR_remove_thread_state(NULL); + OPENSSL_cleanup(); + return (ret); } -- cgit v1.2.3-55-g6feb