From: Neil Horman Date: Fri, 3 Jul 2026 12:40:06 +0000 (-0400) Subject: Fix refcounting for ENCODER/DECODER/STORE methods without caching X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=f454c8fd5d97b80f431dba16b8deacad6b69cbfd;p=thirdparty%2Fopenssl.git Fix refcounting for ENCODER/DECODER/STORE methods without caching https://github.com/openssl/openssl/pull/31782 Fixed method refcounting for EVP objects when the provider they are fetched from requests no-caching, but I neglected to add simmilar refcounting fixes for DECODERS/ENCODERS and STORE objects, who follow a different fetch path (these use inner_[decoder|encoder|loader]_fetch rather than inner_evp_generic_fetch. They got missed because the p_ossltest provider that we use to test these paths don't provide these objects, so the path never got exercised. Reviewed-by: Bob Beck Reviewed-by: Paul Dale MergeDate: Tue Jul 14 05:21:36 2026 (Merged from https://github.com/openssl/openssl/pull/31844) --- diff --git a/crypto/encode_decode/decoder_meth.c b/crypto/encode_decode/decoder_meth.c index 995cb675baa..772c29c0319 100644 --- a/crypto/encode_decode/decoder_meth.c +++ b/crypto/encode_decode/decoder_meth.c @@ -406,9 +406,19 @@ inner_ossl_decoder_fetch(struct decoder_data_st *methdata, */ if (id == 0 && name != NULL) id = ossl_namemap_name2num(namemap, name); - if (id != 0) + if (id != 0 && methdata->tmp_store == NULL) { ossl_method_store_cache_set(store, prov, id, propq, method, ossl_decoder_up_ref, ossl_decoder_free); + } else { + /* + * Like with EVP methods, if the provider requests no caching we need + * to take an extra refcount here so that the tmp_stored decoder + * lives beyond the freeing of that tmp_store + */ +#ifndef OPENSSL_NO_CACHED_FETCH + OSSL_DECODER_up_ref((OSSL_DECODER *)method); +#endif + } } /* diff --git a/crypto/encode_decode/encoder_meth.c b/crypto/encode_decode/encoder_meth.c index f329d0a3075..23dcccebb95 100644 --- a/crypto/encode_decode/encoder_meth.c +++ b/crypto/encode_decode/encoder_meth.c @@ -405,8 +405,19 @@ 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, - ossl_encoder_up_ref, ossl_encoder_free); + if (id != 0 && methdata->tmp_store == NULL) { + ossl_method_store_cache_set(store, prov, id, propq, method, + ossl_encoder_up_ref, ossl_encoder_free); + } else { + /* + * Like with EVP methods, if the provider requests no caching we need + * to take an extra refcount here so that the tmp_stored encoder + * lives beyond the freeing of that tmp_store + */ +#ifndef OPENSSL_NO_CACHED_FETCH + OSSL_ENCODER_up_ref((OSSL_ENCODER *)method); +#endif + } } /* diff --git a/crypto/store/store_meth.c b/crypto/store/store_meth.c index 96b092e5bba..976e4aa7347 100644 --- a/crypto/store/store_meth.c +++ b/crypto/store/store_meth.c @@ -353,8 +353,19 @@ inner_loader_fetch(struct loader_data_st *methdata, */ if (id == 0) id = ossl_namemap_name2num(namemap, scheme); - ossl_method_store_cache_set(store, prov, id, propq, method, - up_ref_loader, free_loader); + if (id != 0 && methdata->tmp_store == NULL) { + ossl_method_store_cache_set(store, prov, id, propq, method, + up_ref_loader, free_loader); + } else { + /* + * Like with EVP methods, if the provider requests no caching we need + * to take an extra refcount here so that the tmp_stored loader + * lives beyond the freeing of that tmp_store + */ +#ifndef OPENSSL_NO_CACHED_FETCH + OSSL_STORE_LOADER_up_ref((OSSL_STORE_LOADER *)method); +#endif + } } /*