]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add the ability for ex_data to have a priority
authorMatt Caswell <matt@openssl.org>
Mon, 26 Apr 2021 10:35:17 +0000 (11:35 +0100)
committerMatt Caswell <matt@openssl.org>
Tue, 11 May 2021 13:56:55 +0000 (14:56 +0100)
Where an object has multiple ex_data associated with it, then we free that
ex_data in order of priority (high priority first).

Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14991)

21 files changed:
crypto/bio/bss_core.c
crypto/context.c
crypto/core_namemap.c
crypto/encode_decode/decoder_meth.c
crypto/encode_decode/encoder_meth.c
crypto/evp/evp_fetch.c
crypto/ex_data.c
crypto/initthread.c
crypto/property/defn_cache.c
crypto/property/property.c
crypto/property/property_string.c
crypto/provider_conf.c
crypto/provider_core.c
crypto/rand/rand_lib.c
crypto/self_test_core.c
crypto/store/store_meth.c
include/internal/cryptlib.h
providers/fips/fipsprov.c
providers/implementations/rands/crngt.c
providers/implementations/rands/drbg.c
test/context_internal_test.c

index 2baabe614ea0fa6ea3061ccb13d3a25102519181..89b1ef73958995726c04c15f1467ab7434983585 100644 (file)
@@ -30,6 +30,7 @@ static void *bio_core_globals_new(OSSL_LIB_CTX *ctx)
 }
 
 static const OSSL_LIB_CTX_METHOD bio_core_globals_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     bio_core_globals_new,
     bio_core_globals_free,
 };
index 4ea949970afb36552d0a652616e8c79a93627d4b..b21fdf077d9fdfe182f5fd3c86a10c3bd7cf8cd8 100644 (file)
@@ -305,7 +305,8 @@ static int ossl_lib_ctx_init_index(OSSL_LIB_CTX *ctx, int static_index,
     idx = ossl_crypto_get_ex_new_index_ex(ctx, CRYPTO_EX_INDEX_OSSL_LIB_CTX, 0,
                                           (void *)meth,
                                           ossl_lib_ctx_generic_new,
-                                          NULL, ossl_lib_ctx_generic_free);
+                                          NULL, ossl_lib_ctx_generic_free,
+                                          meth->priority);
     if (idx < 0)
         return 0;
 
index 1009fb1e94124a10ecc52da29774217a0666f0d1..5bb0f09ec7bf2686a617f677924104197db2503d 100644 (file)
@@ -87,6 +87,7 @@ static void stored_namemap_free(void *vnamemap)
 }
 
 static const OSSL_LIB_CTX_METHOD stored_namemap_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     stored_namemap_new,
     stored_namemap_free,
 };
index 7f8a365b66778d7da11743b11fbb78c4cb250cdd..7a271f7408a2633f12d83800b48177353614e25f 100644 (file)
@@ -76,6 +76,7 @@ static void *decoder_store_new(OSSL_LIB_CTX *ctx)
 
 
 static const OSSL_LIB_CTX_METHOD decoder_store_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     decoder_store_new,
     decoder_store_free,
 };
index de0a66578cddad03831213666ae676fd8564691c..bb319460b942822c15ec196ac1c4c739e8289c07 100644 (file)
@@ -76,6 +76,7 @@ static void *encoder_store_new(OSSL_LIB_CTX *ctx)
 
 
 static const OSSL_LIB_CTX_METHOD encoder_store_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     encoder_store_new,
     encoder_store_free,
 };
index 266f657ff249cb4fc36d12c1ea7222bfc209c830..b74379031b0443bb60ddf92e506d9b87429ff813 100644 (file)
@@ -35,6 +35,8 @@ static void *evp_method_store_new(OSSL_LIB_CTX *ctx)
 
 
 static const OSSL_LIB_CTX_METHOD evp_method_store_method = {
+    /* We want evp_method_store to be cleaned up before the provider store */
+    OSSL_LIB_CTX_METHOD_HIGH_PRIORITY,
     evp_method_store_new,
     evp_method_store_free,
 };
index 4a0efbdb18b9a56ecd128dc2403f4e7ce253756e..40223f06e4ecb695d234f4c533e3033a3f81167b 100644 (file)
@@ -7,6 +7,7 @@
  * https://www.openssl.org/source/license.html
  */
 
+#include <stdlib.h>
 #include "crypto/cryptlib.h"
 #include "internal/thread_once.h"
 
@@ -141,7 +142,8 @@ int ossl_crypto_get_ex_new_index_ex(OSSL_LIB_CTX *ctx, int class_index,
                                     long argl, void *argp,
                                     CRYPTO_EX_new *new_func,
                                     CRYPTO_EX_dup *dup_func,
-                                    CRYPTO_EX_free *free_func)
+                                    CRYPTO_EX_free *free_func,
+                                    int priority)
 {
     int toret = -1;
     EX_CALLBACK *a;
@@ -176,6 +178,7 @@ int ossl_crypto_get_ex_new_index_ex(OSSL_LIB_CTX *ctx, int class_index,
     a->new_func = new_func;
     a->dup_func = dup_func;
     a->free_func = free_func;
+    a->priority = priority;
 
     if (!sk_EX_CALLBACK_push(ip->meth, NULL)) {
         ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
@@ -195,7 +198,7 @@ int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
                             CRYPTO_EX_free *free_func)
 {
     return ossl_crypto_get_ex_new_index_ex(NULL, class_index, argl, argp,
-                                           new_func, dup_func, free_func);
+                                           new_func, dup_func, free_func, 0);
 }
 
 /*
@@ -331,6 +334,27 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
     return toret;
 }
 
+struct ex_callback_entry {
+    const EX_CALLBACK *excb;
+    int index;
+};
+
+static int ex_callback_compare(const void *a, const void *b)
+{
+    const struct ex_callback_entry *ap = (const struct ex_callback_entry *)a;
+    const struct ex_callback_entry *bp = (const struct ex_callback_entry *)b;
+
+    if (ap->excb == bp->excb)
+        return 0;
+
+    if (ap->excb == NULL)
+        return 1;
+    if (bp->excb == NULL)
+        return -1;
+    if (ap->excb->priority == bp->excb->priority)
+        return 0;
+    return ap->excb->priority > bp->excb->priority ? -1 : 1;
+}
 
 /*
  * Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for
@@ -341,9 +365,9 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
     int mx, i;
     EX_CALLBACKS *ip;
     void *ptr;
-    EX_CALLBACK *f;
-    EX_CALLBACK *stack[10];
-    EX_CALLBACK **storage = NULL;
+    const EX_CALLBACK *f;
+    struct ex_callback_entry stack[10];
+    struct ex_callback_entry *storage = NULL;
     OSSL_EX_DATA_GLOBAL *global = ossl_lib_ctx_get_ex_data_global(ad->ctx);
 
     if (global == NULL)
@@ -360,23 +384,23 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
         else
             storage = OPENSSL_malloc(sizeof(*storage) * mx);
         if (storage != NULL)
-            for (i = 0; i < mx; i++)
-                storage[i] = sk_EX_CALLBACK_value(ip->meth, i);
+            for (i = 0; i < mx; i++) {
+                storage[i].excb = sk_EX_CALLBACK_value(ip->meth, i);
+                storage[i].index = i;
+            }
     }
     CRYPTO_THREAD_unlock(global->ex_data_lock);
 
-    for (i = 0; i < mx; i++) {
-        if (storage != NULL)
-            f = storage[i];
-        else {
-            if (!CRYPTO_THREAD_write_lock(global->ex_data_lock))
-                continue;
-            f = sk_EX_CALLBACK_value(ip->meth, i);
-            CRYPTO_THREAD_unlock(global->ex_data_lock);
-        }
-        if (f != NULL && f->free_func != NULL) {
-            ptr = CRYPTO_get_ex_data(ad, i);
-            f->free_func(obj, ptr, ad, i, f->argl, f->argp);
+    if (storage != NULL) {
+        /* Sort according to priority. High priority first */
+        qsort(storage, mx, sizeof(*storage), ex_callback_compare);
+        for (i = 0; i < mx; i++) {
+            f = storage[i].excb;
+
+            if (f != NULL && f->free_func != NULL) {
+                ptr = CRYPTO_get_ex_data(ad, storage[i].index);
+                f->free_func(obj, ptr, ad, storage[i].index, f->argl, f->argp);
+            }
         }
     }
 
index 07406680718c7b7134f70e8d7b915ec6744ed605..fec32130475fc428175c2ffc89e984e4da507cff 100644 (file)
@@ -278,6 +278,7 @@ static void thread_event_ossl_ctx_free(void *tlocal)
 }
 
 static const OSSL_LIB_CTX_METHOD thread_event_ossl_ctx_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     thread_event_ossl_ctx_new,
     thread_event_ossl_ctx_free,
 };
index 6c6503bdcc9f8253a7fc4816ac271127fdae7d5a..8007599526c61e45063577ed8680e362970f00ca 100644 (file)
@@ -63,6 +63,7 @@ static void *property_defns_new(OSSL_LIB_CTX *ctx) {
 }
 
 static const OSSL_LIB_CTX_METHOD property_defns_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     property_defns_new,
     property_defns_free,
 };
index 2b841a2204d2fefbb6727eefdc9d46669a6bf6a0..da6bc84e27fab39cb6db40f3e8a73a510efae6fb 100644 (file)
@@ -94,6 +94,7 @@ static void *ossl_ctx_global_properties_new(OSSL_LIB_CTX *ctx)
 
 
 static const OSSL_LIB_CTX_METHOD ossl_ctx_global_properties_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     ossl_ctx_global_properties_new,
     ossl_ctx_global_properties_free,
 };
index 90bb322faafd0d6899ff6a8fc9a0f25747711759..9eb55cb4616a3c1e6feec3181ba047af7698e6cc 100644 (file)
@@ -105,6 +105,7 @@ err:
 }
 
 static const OSSL_LIB_CTX_METHOD property_string_data_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     property_string_data_new,
     property_string_data_free,
 };
index a04a7aa5535e86c9b724bd82800b875ea8871730..6223d27cbb556375ce1d1d3e95ff198764903c6c 100644 (file)
@@ -45,6 +45,8 @@ static void prov_conf_ossl_ctx_free(void *vpcgbl)
 }
 
 static const OSSL_LIB_CTX_METHOD provider_conf_ossl_ctx_method = {
+    /* Must be freed before the provider store is freed */
+    OSSL_LIB_CTX_METHOD_HIGH_PRIORITY,
     prov_conf_ossl_ctx_new,
     prov_conf_ossl_ctx_free,
 };
index 3d853eb66b1f079764296a16fd0a6ca1d9e7a6e5..db8763d50d45f8009d905b353c9f0b97c32f3536 100644 (file)
@@ -189,6 +189,7 @@ static void *provider_store_new(OSSL_LIB_CTX *ctx)
 }
 
 static const OSSL_LIB_CTX_METHOD provider_store_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     provider_store_new,
     provider_store_free,
 };
index f6c5bc15eec7a64d4b197b3e8c1fcc3a14393a11..bdf5f71f44c71da310abda2c4ae49190e9a6c88c 100644 (file)
@@ -486,6 +486,7 @@ static void rand_ossl_ctx_free(void *vdgbl)
 }
 
 static const OSSL_LIB_CTX_METHOD rand_drbg_ossl_ctx_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     rand_ossl_ctx_new,
     rand_ossl_ctx_free,
 };
index a4f6c9ab2af3251c8a0631b4dc58c490a152911b..341af7b194a7c913b3929546e1e931397c0bc7c8 100644 (file)
@@ -46,6 +46,7 @@ static void self_test_set_callback_free(void *stcb)
 }
 
 static const OSSL_LIB_CTX_METHOD self_test_set_callback_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     self_test_set_callback_new,
     self_test_set_callback_free,
 };
index a2ab341fe979a08cacf3eeb2e20e00261c29c0b1..7bf0a329ce1ae0857eb6fbb69026bdf85125cc54 100644 (file)
@@ -81,6 +81,7 @@ static void *loader_store_new(OSSL_LIB_CTX *ctx)
 
 
 static const OSSL_LIB_CTX_METHOD loader_store_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     loader_store_new,
     loader_store_free,
 };
index d583153b89c6492aa43b4b03be5063028ca46283..94d93abda2d1672c26012e1a474bb21d4699edf8 100644 (file)
@@ -120,6 +120,7 @@ size_t OPENSSL_instrument_bus2(unsigned int *, size_t, size_t);
 struct ex_callback_st {
     long argl;                  /* Arbitrary long */
     void *argp;                 /* Arbitrary void * */
+    int priority;               /* Priority ordering for freeing */
     CRYPTO_EX_new *new_func;
     CRYPTO_EX_free *free_func;
     CRYPTO_EX_dup *dup_func;
@@ -166,7 +167,10 @@ typedef struct ossl_ex_data_global_st {
 # define OSSL_LIB_CTX_BIO_CORE_INDEX                17
 # define OSSL_LIB_CTX_MAX_INDEXES                   18
 
+# define OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY       0
+# define OSSL_LIB_CTX_METHOD_HIGH_PRIORITY          1
 typedef struct ossl_lib_ctx_method {
+    int priority;
     void *(*new_func)(OSSL_LIB_CTX *ctx);
     void (*free_func)(void *);
 } OSSL_LIB_CTX_METHOD;
@@ -196,7 +200,8 @@ int ossl_crypto_get_ex_new_index_ex(OSSL_LIB_CTX *ctx, int class_index,
                                     long argl, void *argp,
                                     CRYPTO_EX_new *new_func,
                                     CRYPTO_EX_dup *dup_func,
-                                    CRYPTO_EX_free *free_func);
+                                    CRYPTO_EX_free *free_func,
+                                    int priority);
 int ossl_crypto_free_ex_index_ex(OSSL_LIB_CTX *ctx, int class_index, int idx);
 
 /* Function for simple binary search */
index 841c80bab7256c49142b0f03feb072f70d0b2eff..7998d55d9aedf352158b9db38b752ba2ad89d91d 100644 (file)
@@ -96,6 +96,7 @@ static void fips_prov_ossl_ctx_free(void *fgbl)
 }
 
 static const OSSL_LIB_CTX_METHOD fips_prov_ossl_ctx_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     fips_prov_ossl_ctx_new,
     fips_prov_ossl_ctx_free,
 };
index f1b31df1014aea91da31b45216e00b479fd9add1..87902c995cfabb7e3a584ad75c6c9b86fd3d71f4 100644 (file)
@@ -83,6 +83,7 @@ static void *rand_crng_ossl_ctx_new(OSSL_LIB_CTX *ctx)
 }
 
 static const OSSL_LIB_CTX_METHOD rand_crng_ossl_ctx_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     rand_crng_ossl_ctx_new,
     rand_crng_ossl_ctx_free,
 };
index 461d641273d17e437967db11c2d65757b58bd71a..81343fbd525dc0390434699ed6f01e75a1ee2075 100644 (file)
@@ -303,6 +303,7 @@ static void prov_drbg_nonce_ossl_ctx_free(void *vdngbl)
 }
 
 static const OSSL_LIB_CTX_METHOD drbg_nonce_ossl_ctx_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     prov_drbg_nonce_ossl_ctx_new,
     prov_drbg_nonce_ossl_ctx_free,
 };
index 46afd9f52184b2a8706276e7830d26fb4c899c90..4c02f601cc5283c106d3623e2e87c603a24c0064 100644 (file)
@@ -39,6 +39,7 @@ static void foo_free(void *ptr)
     OPENSSL_free(ptr);
 }
 static const OSSL_LIB_CTX_METHOD foo_method = {
+    OSSL_LIB_CTX_METHOD_DEFAULT_PRIORITY,
     foo_new,
     foo_free
 };