Commit 7933e2ca6e for openssl.org
commit 7933e2ca6ead9a2fb16aa3fde783e66386570592
Author: Neil Horman <nhorman@openssl.org>
Date: Fri May 8 10:46:54 2026 -0400
make OSSL_DECODER no do ref counting
Reviewed-by: Bob Beck <beck@openssl.org>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
MergeDate: Thu Jun 25 21:26:11 2026
(Merged from https://github.com/openssl/openssl/pull/31143)
diff --git a/crypto/encode_decode/decoder_meth.c b/crypto/encode_decode/decoder_meth.c
index b38f1adf5b..315c99d8c6 100644
--- a/crypto/encode_decode/decoder_meth.c
+++ b/crypto/encode_decode/decoder_meth.c
@@ -59,7 +59,7 @@ static OSSL_DECODER *ossl_decoder_new(void)
if ((decoder = OPENSSL_zalloc(sizeof(*decoder))) == NULL)
return NULL;
if (!CRYPTO_NEW_REF(&decoder->base.refcnt, 1)) {
- OSSL_DECODER_free(decoder);
+ ossl_decoder_free(decoder);
return NULL;
}
@@ -68,9 +68,17 @@ static OSSL_DECODER *ossl_decoder_new(void)
int OSSL_DECODER_up_ref(OSSL_DECODER *decoder)
{
-#ifdef OSSL_DECODER_fetch
+#ifdef OPENSSL_NO_CACHED_FETCH
return ossl_decoder_up_ref(decoder);
#else
+ /*
+ * DECODERS do something weird. They manually build methods rather than
+ * attempt to fetch them from the method store or construct them through
+ * the ossl_generic_fetch mechanism. As such they don't make use of the refcounting
+ * that we rely on in the method store, and so we always need to refcount them here
+ * We can identify them based on the fact that they never have a registered nid (i.e.
+ * its always zero)
+ */
if (decoder->base.id == 0)
return ossl_decoder_up_ref(decoder);
return 1;
@@ -79,7 +87,7 @@ int OSSL_DECODER_up_ref(OSSL_DECODER *decoder)
void OSSL_DECODER_free(OSSL_DECODER *decoder)
{
-#ifdef OSSL_DECODER_fetch
+#ifdef OPENSSL_NO_CACHED_FETCH
ossl_decoder_free(decoder);
#else
if (decoder != NULL && decoder->base.id == 0)
@@ -230,14 +238,14 @@ void *ossl_decoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef,
return NULL;
decoder->base.id = id;
if ((decoder->base.name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
- OSSL_DECODER_free(decoder);
+ ossl_decoder_free(decoder);
return NULL;
}
decoder->base.algodef = algodef;
if ((decoder->base.parsed_propdef
= ossl_parse_property(libctx, algodef->property_definition))
== NULL) {
- OSSL_DECODER_free(decoder);
+ ossl_decoder_free(decoder);
return NULL;
}
@@ -289,13 +297,13 @@ void *ossl_decoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef,
if (!((decoder->newctx == NULL && decoder->freectx == NULL)
|| (decoder->newctx != NULL && decoder->freectx != NULL))
|| decoder->decode == NULL) {
- OSSL_DECODER_free(decoder);
+ ossl_decoder_free(decoder);
ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INVALID_PROVIDER_FUNCTIONS);
return NULL;
}
if (prov != NULL && !ossl_provider_up_ref(prov)) {
- OSSL_DECODER_free(decoder);
+ ossl_decoder_free(decoder);
return NULL;
}
@@ -341,17 +349,7 @@ static void *construct_decoder(const OSSL_ALGORITHM *algodef,
/* Intermediary function to avoid ugly casts, used below */
static void destruct_decoder(void *method, void *data)
{
- OSSL_DECODER_free(method);
-}
-
-static int up_ref_decoder(void *method)
-{
- return OSSL_DECODER_up_ref(method);
-}
-
-static void free_decoder(void *method)
-{
- OSSL_DECODER_free(method);
+ ossl_decoder_free(method);
}
/* Fetching support. Can fetch by numeric identity or by name */
@@ -409,7 +407,7 @@ inner_ossl_decoder_fetch(struct decoder_data_st *methdata,
id = ossl_namemap_name2num(namemap, name);
if (id != 0)
ossl_method_store_cache_set(store, prov, id, propq, method,
- up_ref_decoder, free_decoder);
+ ossl_decoder_up_ref, ossl_decoder_free);
}
/*
diff --git a/crypto/encode_decode/encoder_meth.c b/crypto/encode_decode/encoder_meth.c
index 0c9647e51f..611dc787d7 100644
--- a/crypto/encode_decode/encoder_meth.c
+++ b/crypto/encode_decode/encoder_meth.c
@@ -27,12 +27,29 @@
static void ossl_encoder_free(void *data)
{
- OSSL_ENCODER_free(data);
+ OSSL_ENCODER *encoder = (OSSL_ENCODER *)data;
+ int ref = 0;
+
+ if (encoder == NULL)
+ return;
+
+ CRYPTO_DOWN_REF(&encoder->base.refcnt, &ref);
+ if (ref > 0)
+ return;
+ OPENSSL_free(encoder->base.name);
+ ossl_property_free(encoder->base.parsed_propdef);
+ ossl_provider_free(encoder->base.prov);
+ CRYPTO_FREE_REF(&encoder->base.refcnt);
+ OPENSSL_free(encoder);
}
static int ossl_encoder_up_ref(void *data)
{
- return OSSL_ENCODER_up_ref(data);
+ OSSL_ENCODER *encoder = (OSSL_ENCODER *)data;
+ int ref = 0;
+
+ CRYPTO_UP_REF(&encoder->base.refcnt, &ref);
+ return 1;
}
/* Simple method structure constructor and destructor */
@@ -56,6 +73,7 @@ int OSSL_ENCODER_up_ref(OSSL_ENCODER *encoder)
return ossl_encoder_up_ref(encoder);
#else
return 1;
+#endif
}
void OSSL_ENCODER_free(OSSL_ENCODER *encoder)
@@ -208,14 +226,14 @@ static void *encoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef,
return NULL;
encoder->base.id = id;
if ((encoder->base.name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
- OSSL_ENCODER_free(encoder);
+ ossl_encoder_free(encoder);
return NULL;
}
encoder->base.algodef = algodef;
if ((encoder->base.parsed_propdef
= ossl_parse_property(libctx, algodef->property_definition))
== NULL) {
- OSSL_ENCODER_free(encoder);
+ ossl_encoder_free(encoder);
return NULL;
}
@@ -273,13 +291,13 @@ static void *encoder_from_algorithm(int id, const OSSL_ALGORITHM *algodef,
|| (encoder->import_object != NULL && encoder->free_object != NULL)
|| (encoder->import_object == NULL && encoder->free_object == NULL))
|| encoder->encode == NULL) {
- OSSL_ENCODER_free(encoder);
+ ossl_encoder_free(encoder);
ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_INVALID_PROVIDER_FUNCTIONS);
return NULL;
}
if (prov != NULL && !ossl_provider_up_ref(prov)) {
- OSSL_ENCODER_free(encoder);
+ ossl_encoder_free(encoder);
return NULL;
}
@@ -325,17 +343,7 @@ static void *construct_encoder(const OSSL_ALGORITHM *algodef,
/* Intermediary function to avoid ugly casts, used below */
static void destruct_encoder(void *method, void *data)
{
- OSSL_ENCODER_free(method);
-}
-
-static int up_ref_encoder(void *method)
-{
- return OSSL_ENCODER_up_ref(method);
-}
-
-static void free_encoder(void *method)
-{
- OSSL_ENCODER_free(method);
+ ossl_encoder_free(method);
}
/* Fetching support. Can fetch by numeric identity or by name */
@@ -392,7 +400,7 @@ inner_ossl_encoder_fetch(struct encoder_data_st *methdata,
if (id == 0)
id = ossl_namemap_name2num(namemap, name);
ossl_method_store_cache_set(store, prov, id, propq, method,
- up_ref_encoder, free_encoder);
+ ossl_encoder_up_ref, ossl_encoder_free);
}
/*