From: Neil Horman Date: Fri, 8 May 2026 14:46:54 +0000 (-0400) Subject: make OSSL_DECODER no do ref counting X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7933e2ca6ead9a2fb16aa3fde783e66386570592;p=thirdparty%2Fopenssl.git make OSSL_DECODER no do ref counting Reviewed-by: Bob Beck Reviewed-by: Nikola Pajkovsky 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 b38f1adf5b6..315c99d8c60 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 0c9647e51f7..611dc787d7c 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); } /*