summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2022-04-29 08:08:06 +0200
committerRichard Levitte <levitte@openssl.org>2022-05-05 15:06:11 +0200
commit4da7663b02bf05542830e85db6f74cf90daf1f49 (patch)
tree4f9cff33c44c8e57caefbd23c66a78649a001788
parent03454ba2a234197c961920f1bac37cc9f4cf3f54 (diff)
For child libctx / provider, don't count self-references in parent
In child library contexts, which contain child "clones" of the providers the application has in store, one of these children will always be the provider that creates the child library context; let's call them self-refering child providers. For these self-refering child providers, we don't increment the parent provider reference count, nor do we free the parent provider, as those become self defeating and hinder the teardown and unloading process when the application cleans up. For non self-refering child providers, we must retain this propagation of reference count to the parent, so that aren't torn down too early, i.e. when there's still a "foreign" reference (fetched algorithm). Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/18151)
-rw-r--r--crypto/provider_child.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/crypto/provider_child.c b/crypto/provider_child.c
index eb81c30a41..b1eadd5b19 100644
--- a/crypto/provider_child.c
+++ b/crypto/provider_child.c
@@ -269,26 +269,46 @@ void ossl_provider_deinit_child(OSSL_LIB_CTX *ctx)
gbl->c_provider_deregister_child_cb(gbl->handle);
}
+/*
+ * ossl_provider_up_ref_parent() and ossl_provider_free_parent() do
+ * nothing in "self-referencing" child providers, i.e. when the parent
+ * of the child provider is the same as the provider where this child
+ * provider was created.
+ * This allows the teardown function in the parent provider to be called
+ * at the correct moment.
+ * For child providers in other providers, the reference count is done to
+ * ensure that cross referencing is recorded. These should be cleared up
+ * through that providers teardown, as part of freeing its child libctx.
+ */
+
int ossl_provider_up_ref_parent(OSSL_PROVIDER *prov, int activate)
{
struct child_prov_globals *gbl;
+ const OSSL_CORE_HANDLE *parent_handle;
gbl = ossl_lib_ctx_get_data(ossl_provider_libctx(prov),
OSSL_LIB_CTX_CHILD_PROVIDER_INDEX);
if (gbl == NULL)
return 0;
- return gbl->c_prov_up_ref(ossl_provider_get_parent(prov), activate);
+ parent_handle = ossl_provider_get_parent(prov);
+ if (parent_handle == gbl->handle)
+ return 1;
+ return gbl->c_prov_up_ref(parent_handle, activate);
}
int ossl_provider_free_parent(OSSL_PROVIDER *prov, int deactivate)
{
struct child_prov_globals *gbl;
+ const OSSL_CORE_HANDLE *parent_handle;
gbl = ossl_lib_ctx_get_data(ossl_provider_libctx(prov),
OSSL_LIB_CTX_CHILD_PROVIDER_INDEX);
if (gbl == NULL)
return 0;
+ parent_handle = ossl_provider_get_parent(prov);
+ if (parent_handle == gbl->handle)
+ return 1;
return gbl->c_prov_free(ossl_provider_get_parent(prov), deactivate);
}