Browse Source

Add the ability for ex_data to have a priority

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)
master
Matt Caswell 1 year ago
parent
commit
a16d21744d
21 changed files with 71 additions and 21 deletions
  1. +1
    -0
      crypto/bio/bss_core.c
  2. +2
    -1
      crypto/context.c
  3. +1
    -0
      crypto/core_namemap.c
  4. +1
    -0
      crypto/encode_decode/decoder_meth.c
  5. +1
    -0
      crypto/encode_decode/encoder_meth.c
  6. +2
    -0
      crypto/evp/evp_fetch.c
  7. +43
    -19
      crypto/ex_data.c
  8. +1
    -0
      crypto/initthread.c
  9. +1
    -0
      crypto/property/defn_cache.c
  10. +1
    -0
      crypto/property/property.c
  11. +1
    -0
      crypto/property/property_string.c
  12. +2
    -0
      crypto/provider_conf.c
  13. +1
    -0
      crypto/provider_core.c
  14. +1
    -0
      crypto/rand/rand_lib.c
  15. +1
    -0
      crypto/self_test_core.c
  16. +1
    -0
      crypto/store/store_meth.c
  17. +6
    -1
      include/internal/cryptlib.h
  18. +1
    -0
      providers/fips/fipsprov.c
  19. +1
    -0
      providers/implementations/rands/crngt.c
  20. +1
    -0
      providers/implementations/rands/drbg.c
  21. +1
    -0
      test/context_internal_test.c

+ 1
- 0
crypto/bio/bss_core.c View 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,
};


+ 2
- 1
crypto/context.c View 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;


+ 1
- 0
crypto/core_namemap.c View 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,
};


+ 1
- 0
crypto/encode_decode/decoder_meth.c View 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,
};


+ 1
- 0
crypto/encode_decode/encoder_meth.c View 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,
};


+ 2
- 0
crypto/evp/evp_fetch.c View 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,
};


+ 43
- 19
crypto/ex_data.c View 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);
}
}
}


+ 1
- 0
crypto/initthread.c View 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,
};


+ 1
- 0
crypto/property/defn_cache.c View 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,
};


+ 1
- 0
crypto/property/property.c View 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,
};


+ 1
- 0
crypto/property/property_string.c View 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,
};


+ 2
- 0
crypto/provider_conf.c View 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,
};


+ 1
- 0
crypto/provider_core.c View 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,
};


+ 1
- 0
crypto/rand/rand_lib.c View 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,
};


+ 1
- 0
crypto/self_test_core.c View 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,
};


+ 1
- 0
crypto/store/store_meth.c View 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,
};


+ 6
- 1
include/internal/cryptlib.h View 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 */


+ 1
- 0
providers/fips/fipsprov.c View 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,
};


+ 1
- 0
providers/implementations/rands/crngt.c View 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,
};


+ 1
- 0
providers/implementations/rands/drbg.c View 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,
};


+ 1
- 0
test/context_internal_test.c View 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
};


Loading…
Cancel
Save