]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix refcounting for ENCODER/DECODER/STORE methods without caching
authorNeil Horman <nhorman@openssl.org>
Fri, 3 Jul 2026 12:40:06 +0000 (08:40 -0400)
committerNikola Pajkovsky <nikolap@openssl.org>
Tue, 14 Jul 2026 05:20:58 +0000 (07:20 +0200)
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 <beck@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
MergeDate: Tue Jul 14 05:21:36 2026
(Merged from https://github.com/openssl/openssl/pull/31844)

crypto/encode_decode/decoder_meth.c
crypto/encode_decode/encoder_meth.c
crypto/store/store_meth.c

index 995cb675baa7dfc70c906b3ad1ddd77018662af1..772c29c031952a499240b5707775db6878e10a0f 100644 (file)
@@ -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
+            }
         }
 
         /*
index f329d0a30753a2885e473187e26781689c8d5689..23dcccebb958a30d7ff8e226eca494c06ef56e43 100644 (file)
@@ -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
+            }
         }
 
         /*
index 96b092e5bbab8a99e87ad7fd18cc695a12602563..976e4aa734778805eb1d9c060f154db538e52db5 100644 (file)
@@ -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
+            }
         }
 
         /*