diff options
Diffstat (limited to 'crypto/ex_data.c')
-rw-r--r-- | crypto/ex_data.c | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/crypto/ex_data.c b/crypto/ex_data.c index 13b928899456..0412f38e9baa 100644 --- a/crypto/ex_data.c +++ b/crypto/ex_data.c @@ -26,8 +26,10 @@ int ossl_do_ex_data_init(OSSL_LIB_CTX *ctx) * Return the EX_CALLBACKS from the |ex_data| array that corresponds to * a given class. On success, *holds the lock.* * The |global| parameter is assumed to be non null (checked by the caller). + * If |read| is 1 then a read lock is obtained. Otherwise it is a write lock. */ -static EX_CALLBACKS *get_and_lock(OSSL_EX_DATA_GLOBAL *global, int class_index) +static EX_CALLBACKS *get_and_lock(OSSL_EX_DATA_GLOBAL *global, int class_index, + int read) { EX_CALLBACKS *ip; @@ -44,8 +46,14 @@ static EX_CALLBACKS *get_and_lock(OSSL_EX_DATA_GLOBAL *global, int class_index) return NULL; } - if (!CRYPTO_THREAD_write_lock(global->ex_data_lock)) - return NULL; + if (read) { + if (!CRYPTO_THREAD_read_lock(global->ex_data_lock)) + return NULL; + } else { + if (!CRYPTO_THREAD_write_lock(global->ex_data_lock)) + return NULL; + } + ip = &global->ex_data[class_index]; return ip; } @@ -112,7 +120,7 @@ int ossl_crypto_free_ex_index_ex(OSSL_LIB_CTX *ctx, int class_index, int idx) if (global == NULL) return 0; - ip = get_and_lock(global, class_index); + ip = get_and_lock(global, class_index, 0); if (ip == NULL) return 0; @@ -153,7 +161,7 @@ int ossl_crypto_get_ex_new_index_ex(OSSL_LIB_CTX *ctx, int class_index, if (global == NULL) return -1; - ip = get_and_lock(global, class_index); + ip = get_and_lock(global, class_index, 0); if (ip == NULL) return -1; @@ -165,16 +173,14 @@ int ossl_crypto_get_ex_new_index_ex(OSSL_LIB_CTX *ctx, int class_index, || !sk_EX_CALLBACK_push(ip->meth, NULL)) { sk_EX_CALLBACK_free(ip->meth); ip->meth = NULL; - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); goto err; } } a = (EX_CALLBACK *)OPENSSL_malloc(sizeof(*a)); - if (a == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (a == NULL) goto err; - } a->argl = argl; a->argp = argp; a->new_func = new_func; @@ -183,7 +189,7 @@ int ossl_crypto_get_ex_new_index_ex(OSSL_LIB_CTX *ctx, int class_index, a->priority = priority; if (!sk_EX_CALLBACK_push(ip->meth, NULL)) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); OPENSSL_free(a); goto err; } @@ -223,7 +229,7 @@ int ossl_crypto_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj, if (global == NULL) return 0; - ip = get_and_lock(global, class_index); + ip = get_and_lock(global, class_index, 1); if (ip == NULL) return 0; @@ -241,10 +247,8 @@ int ossl_crypto_new_ex_data_ex(OSSL_LIB_CTX *ctx, int class_index, void *obj, } CRYPTO_THREAD_unlock(global->ex_data_lock); - if (mx > 0 && storage == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (mx > 0 && storage == NULL) return 0; - } for (i = 0; i < mx; i++) { if (storage[i] != NULL && storage[i]->new_func != NULL) { ptr = CRYPTO_get_ex_data(ad, i); @@ -286,7 +290,7 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, if (global == NULL) return 0; - ip = get_and_lock(global, class_index); + ip = get_and_lock(global, class_index, 1); if (ip == NULL) return 0; @@ -307,10 +311,8 @@ int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, if (mx == 0) return 1; - if (storage == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + if (storage == NULL) return 0; - } /* * Make sure the ex_data stack is at least |mx| elements long to avoid * issues in the for loop that follows; so go get the |mx|'th element @@ -375,7 +377,7 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) if (global == NULL) goto err; - ip = get_and_lock(global, class_index); + ip = get_and_lock(global, class_index, 1); if (ip == NULL) goto err; @@ -442,7 +444,7 @@ int ossl_crypto_alloc_ex_data_intern(int class_index, void *obj, if (global == NULL) return 0; - ip = get_and_lock(global, class_index); + ip = get_and_lock(global, class_index, 1); if (ip == NULL) return 0; f = sk_EX_CALLBACK_value(ip->meth, idx); @@ -470,14 +472,14 @@ int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val) if (ad->sk == NULL) { if ((ad->sk = sk_void_new_null()) == NULL) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); return 0; } } for (i = sk_void_num(ad->sk); i <= idx; ++i) { if (!sk_void_push(ad->sk, NULL)) { - ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_CRYPTO_LIB); return 0; } } |