From cad22202a32a94059e351d9819e6c9ed5c66605a Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Tue, 9 Nov 2021 13:48:31 +0000 Subject: [PATCH] Stop receiving child callbacks in a child libctx when appropriate We should stop receiving child callbacks if we're about to free up the child libctx. Otherwise we can get callbacks when the libctx is half freed up. Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/16980) --- crypto/context.c | 4 ++++ crypto/provider_child.c | 12 +++++++++++- doc/internal/man3/ossl_provider_new.pod | 8 ++++++-- include/internal/provider.h | 1 + 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/crypto/context.c b/crypto/context.c index 1e0dfa8e015..bba8e4208b1 100644 --- a/crypto/context.c +++ b/crypto/context.c @@ -240,6 +240,10 @@ void OSSL_LIB_CTX_free(OSSL_LIB_CTX *ctx) if (ossl_lib_ctx_is_default(ctx)) return; +#ifndef FIPS_MODULE + if (ctx->ischild) + ossl_provider_deinit_child(ctx); +#endif context_deinit(ctx); OPENSSL_free(ctx); } diff --git a/crypto/provider_child.c b/crypto/provider_child.c index 1b925303010..977ea4db3bf 100644 --- a/crypto/provider_child.c +++ b/crypto/provider_child.c @@ -42,7 +42,6 @@ static void child_prov_ossl_ctx_free(void *vgbl) { struct child_prov_globals *gbl = vgbl; - gbl->c_provider_deregister_child_cb(gbl->handle); CRYPTO_THREAD_lock_free(gbl->lock); OPENSSL_free(gbl); } @@ -269,6 +268,17 @@ int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx, return 1; } +void ossl_provider_deinit_child(OSSL_LIB_CTX *ctx) +{ + struct child_prov_globals *gbl + = ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_CHILD_PROVIDER_INDEX, + &child_prov_ossl_ctx_method); + if (gbl == NULL) + return; + + gbl->c_provider_deregister_child_cb(gbl->handle); +} + int ossl_provider_up_ref_parent(OSSL_PROVIDER *prov, int activate) { struct child_prov_globals *gbl; diff --git a/doc/internal/man3/ossl_provider_new.pod b/doc/internal/man3/ossl_provider_new.pod index 7f6934a59e3..1dba1860f75 100644 --- a/doc/internal/man3/ossl_provider_new.pod +++ b/doc/internal/man3/ossl_provider_new.pod @@ -8,7 +8,7 @@ ossl_provider_set_module_path, ossl_provider_add_parameter, ossl_provider_set_child, ossl_provider_get_parent, ossl_provider_up_ref_parent, ossl_provider_free_parent, ossl_provider_default_props_update, ossl_provider_get0_dispatch, -ossl_provider_init_as_child, +ossl_provider_init_as_child, ossl_provider_deinit_child, ossl_provider_activate, ossl_provider_deactivate, ossl_provider_add_to_store, ossl_provider_ctx, ossl_provider_doall_activated, @@ -98,7 +98,7 @@ ossl_provider_get_capabilities int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx, const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH *in); - + void ossl_provider_deinit_child(OSSL_LIB_CTX *ctx); =head1 DESCRIPTION @@ -302,6 +302,10 @@ the necessary upcalls for managing child providers. The I and I parameters are the B and B pointers that were passed to the provider's B function. +ossl_provider_deinit_child() deregisters callbacks from the parent library +context about provider creation or removal events for the child library context +I. Must only be called if I is a child library context. + =head1 NOTES Locating a provider module happens as follows: diff --git a/include/internal/provider.h b/include/internal/provider.h index ae8d7434374..b8ba7f68926 100644 --- a/include/internal/provider.h +++ b/include/internal/provider.h @@ -107,6 +107,7 @@ void ossl_provider_add_conf_module(void); int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx, const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH *in); +void ossl_provider_deinit_child(OSSL_LIB_CTX *ctx); # ifdef __cplusplus } -- 2.47.2