Commit f454c8fd5d for openssl.org

commit f454c8fd5d97b80f431dba16b8deacad6b69cbfd
Author: Neil Horman <nhorman@openssl.org>
Date:   Fri Jul 3 08:40:06 2026 -0400

    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 <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)

diff --git a/crypto/encode_decode/decoder_meth.c b/crypto/encode_decode/decoder_meth.c
index 995cb675ba..772c29c031 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 f329d0a307..23dcccebb9 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 96b092e5bb..976e4aa734 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
+            }
         }

         /*