Some functions that lock things are void, so we just return early.
Also make ossl_namemap_empty return 0 on error. Updated the docs, and added
some code to ossl_namemap_stored() to handle the failure, and updated the
tests to allow for failure.
Fixes: #14230
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14238)
goto err;
}
- CRYPTO_THREAD_write_lock(bio_lookup_lock);
+ if (!CRYPTO_THREAD_write_lock(bio_lookup_lock)) {
+ ret = 0;
+ goto err;
+ }
he_fallback_address = INADDR_ANY;
if (host == NULL) {
he = &he_fallback;
{
BN_MONT_CTX *ret;
- CRYPTO_THREAD_read_lock(lock);
+ if (!CRYPTO_THREAD_read_lock(lock))
+ return NULL;
ret = *pmont;
CRYPTO_THREAD_unlock(lock);
if (ret)
}
/* The locked compare-and-set, after the local work is done. */
- CRYPTO_THREAD_write_lock(lock);
+ if (!CRYPTO_THREAD_write_lock(lock)) {
+ BN_MONT_CTX_free(ret);
+ return NULL;
+ }
+
if (*pmont) {
BN_MONT_CTX_free(ret);
ret = *pmont;
void *ptr = meth->new_func(ctx);
if (ptr != NULL) {
- CRYPTO_THREAD_write_lock(ctx->lock);
+ if (!CRYPTO_THREAD_write_lock(ctx->lock))
+ /*
+ * Can't return something, so best to hope that something will
+ * fail later. :(
+ */
+ return;
CRYPTO_set_ex_data(ad, index, ptr);
CRYPTO_THREAD_unlock(ctx->lock);
}
if (ctx == NULL)
return NULL;
- CRYPTO_THREAD_read_lock(ctx->lock);
+ if (!CRYPTO_THREAD_read_lock(ctx->lock))
+ return NULL;
dynidx = ctx->dyn_indexes[index];
CRYPTO_THREAD_unlock(ctx->lock);
if (dynidx != -1) {
- CRYPTO_THREAD_read_lock(ctx->index_locks[index]);
- CRYPTO_THREAD_read_lock(ctx->lock);
+ if (!CRYPTO_THREAD_read_lock(ctx->index_locks[index]))
+ return NULL;
+ if (!CRYPTO_THREAD_read_lock(ctx->lock)) {
+ CRYPTO_THREAD_unlock(ctx->index_locks[index]);
+ return NULL;
+ }
data = CRYPTO_get_ex_data(&ctx->data, dynidx);
CRYPTO_THREAD_unlock(ctx->lock);
CRYPTO_THREAD_unlock(ctx->index_locks[index]);
return data;
}
- CRYPTO_THREAD_write_lock(ctx->index_locks[index]);
- CRYPTO_THREAD_write_lock(ctx->lock);
+ if (!CRYPTO_THREAD_write_lock(ctx->index_locks[index]))
+ return NULL;
+ if (!CRYPTO_THREAD_write_lock(ctx->lock)) {
+ CRYPTO_THREAD_unlock(ctx->index_locks[index]);
+ return NULL;
+ }
dynidx = ctx->dyn_indexes[index];
if (dynidx != -1) {
*/
if (ossl_crypto_alloc_ex_data_intern(CRYPTO_EX_INDEX_OSSL_LIB_CTX, NULL,
&ctx->data, ctx->dyn_indexes[index])) {
- CRYPTO_THREAD_read_lock(ctx->lock);
+ if (!CRYPTO_THREAD_read_lock(ctx->lock))
+ goto end;
data = CRYPTO_get_ex_data(&ctx->data, ctx->dyn_indexes[index]);
CRYPTO_THREAD_unlock(ctx->lock);
}
+end:
CRYPTO_THREAD_unlock(ctx->index_locks[index]);
-
return data;
}
if (ctx == NULL)
return 0;
- CRYPTO_THREAD_read_lock(ctx->oncelock);
+ if (!CRYPTO_THREAD_read_lock(ctx->oncelock))
+ return 0;
done = ctx->run_once_done[idx];
if (done)
ret = ctx->run_once_ret[idx];
if (done)
return ret;
- CRYPTO_THREAD_write_lock(ctx->oncelock);
+ if (!CRYPTO_THREAD_write_lock(ctx->oncelock))
+ return 0;
if (ctx->run_once_done[idx]) {
ret = ctx->run_once_ret[idx];
CRYPTO_THREAD_unlock(ctx->oncelock);
if (namemap == NULL)
return 1;
- CRYPTO_THREAD_read_lock(namemap->lock);
+ if (!CRYPTO_THREAD_read_lock(namemap->lock))
+ return -1;
rv = namemap->max_number == 0;
CRYPTO_THREAD_unlock(namemap->lock);
return rv;
* the user function, so that we're not holding the read lock when in user
* code. This could lead to deadlocks.
*/
- CRYPTO_THREAD_read_lock(namemap->lock);
- num_names = lh_NAMENUM_ENTRY_num_items(namemap->namenum);
+ if (!CRYPTO_THREAD_read_lock(namemap->lock))
+ return 0;
+ num_names = lh_NAMENUM_ENTRY_num_items(namemap->namenum);
if (num_names == 0) {
CRYPTO_THREAD_unlock(namemap->lock);
return 0;
if (namemap == NULL)
return 0;
- CRYPTO_THREAD_read_lock(namemap->lock);
+ if (!CRYPTO_THREAD_read_lock(namemap->lock))
+ return 0;
number = namemap_name2num_n(namemap, name, name_len);
CRYPTO_THREAD_unlock(namemap->lock);
if (name == NULL || name_len == 0 || namemap == NULL)
return 0;
- CRYPTO_THREAD_write_lock(namemap->lock);
+ if (!CRYPTO_THREAD_write_lock(namemap->lock))
+ return 0;
tmp_number = namemap_add_name_n(namemap, number, name, name_len);
CRYPTO_THREAD_unlock(namemap->lock);
return tmp_number;
return 0;
}
- CRYPTO_THREAD_write_lock(namemap->lock);
+ if (!CRYPTO_THREAD_write_lock(namemap->lock))
+ return 0;
/*
* Check that no name is an empty string, and that all names have at
* most one numeric identity together.
OSSL_NAMEMAP *ossl_namemap_stored(OSSL_LIB_CTX *libctx)
{
+#ifndef FIPS_MODULE
+ int nms;
+#endif
OSSL_NAMEMAP *namemap =
ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_NAMEMAP_INDEX,
&stored_namemap_method);
+ if (namemap == NULL)
+ return NULL;
+
#ifndef FIPS_MODULE
- if (namemap != NULL && ossl_namemap_empty(namemap)) {
+ nms = ossl_namemap_empty(namemap);
+ if (nms < 0) {
+ /*
+ * Could not get lock to make the count, so maybe internal objects
+ * weren't added. This seems safest.
+ */
+ return NULL;
+ }
+ if (nms == 1) {
/* Before pilfering, we make sure the legacy database is populated */
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
| OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return 0;
ref_exists = ((e->struct_ref > 0) ? 1 : 0);
CRYPTO_THREAD_unlock(global_engine_lock);
ctrl_exists = ((e->ctrl == NULL) ? 0 : 1);
static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx)
{
dynamic_data_ctx *c = OPENSSL_zalloc(sizeof(*c));
- int ret = 1;
+ int ret = 0;
if (c == NULL) {
ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE);
c->dirs = sk_OPENSSL_STRING_new_null();
if (c->dirs == NULL) {
ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE);
- OPENSSL_free(c);
- return 0;
+ goto end;
}
c->DYNAMIC_F1 = "v_check";
c->DYNAMIC_F2 = "bind_engine";
c->dir_load = 1;
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ goto end;
if ((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e,
dynamic_ex_data_idx))
== NULL) {
}
}
CRYPTO_THREAD_unlock(global_engine_lock);
+ ret = 1;
/*
* If we lost the race to set the context, c is non-NULL and *ctx is the
* context of the thread that won.
*/
- if (c)
+end:
+ if (c != NULL)
sk_OPENSSL_STRING_free(c->dirs);
OPENSSL_free(c);
return ret;
ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NO_INDEX);
return NULL;
}
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return NULL;
/* Avoid a race by checking again inside this lock */
if (dynamic_ex_data_idx < 0) {
/* Good, someone didn't beat us to it */
CRYPTO_THREAD_unlock(global_engine_lock);
to_return = e->finish(e);
if (unlock_for_handlers)
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return 0;
if (!to_return)
return 0;
}
ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE);
return 0;
}
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return 0;
ret = engine_unlocked_init(e);
CRYPTO_THREAD_unlock(global_engine_lock);
return ret;
if (e == NULL)
return 1;
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return 0;
to_return = engine_unlocked_finish(e, 1);
CRYPTO_THREAD_unlock(global_engine_lock);
if (!to_return) {
return NULL;
}
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return NULL;
ret = engine_list_head;
if (ret) {
ret->struct_ref++;
return NULL;
}
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return NULL;
ret = engine_list_tail;
if (ret) {
ret->struct_ref++;
ENGINE *ret = NULL;
if (e == NULL) {
ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
+ return NULL;
}
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return NULL;
ret = e->next;
if (ret) {
/* Return a valid structural reference to the next ENGINE */
ENGINE *ret = NULL;
if (e == NULL) {
ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
+ return NULL;
}
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return NULL;
ret = e->prev;
if (ret) {
/* Return a valid structural reference to the next ENGINE */
ERR_raise(ERR_LIB_ENGINE, ENGINE_R_ID_OR_NAME_MISSING);
return 0;
}
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return 0;
if (!engine_list_add(e)) {
ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR);
to_return = 0;
ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return 0;
if (!engine_list_remove(e)) {
ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR);
to_return = 0;
return NULL;
}
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return NULL;
iterator = engine_list_head;
while (iterator && (strcmp(id, iterator->id) != 0))
iterator = iterator->next;
if (e == NULL) {
ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
+ return NULL;
}
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return NULL;
if (e->funct_ref == 0) {
CRYPTO_THREAD_unlock(global_engine_lock);
ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NOT_INITIALISED);
- return 0;
+ return NULL;
}
CRYPTO_THREAD_unlock(global_engine_lock);
if (!e->load_privkey) {
ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NO_LOAD_FUNCTION);
- return 0;
+ return NULL;
}
pkey = e->load_privkey(e, key_id, ui_method, callback_data);
if (pkey == NULL) {
ERR_raise(ERR_LIB_ENGINE, ENGINE_R_FAILED_LOADING_PRIVATE_KEY);
- return 0;
+ return NULL;
}
return pkey;
}
if (e == NULL) {
ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
+ return NULL;
}
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return NULL;
if (e->funct_ref == 0) {
CRYPTO_THREAD_unlock(global_engine_lock);
ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NOT_INITIALISED);
- return 0;
+ return NULL;
}
CRYPTO_THREAD_unlock(global_engine_lock);
if (!e->load_pubkey) {
ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NO_LOAD_FUNCTION);
- return 0;
+ return NULL;
}
pkey = e->load_pubkey(e, key_id, ui_method, callback_data);
if (pkey == NULL) {
ERR_raise(ERR_LIB_ENGINE, ENGINE_R_FAILED_LOADING_PUBLIC_KEY);
- return 0;
+ return NULL;
}
return pkey;
}
ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return 0;
if (e->funct_ref == 0) {
CRYPTO_THREAD_unlock(global_engine_lock);
ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NOT_INITIALISED);
{
int ret = 0, added = 0;
ENGINE_PILE tmplate, *fnd;
- CRYPTO_THREAD_write_lock(global_engine_lock);
+
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return 0;
if (!(*table))
added = 1;
if (!int_table_check(table, 1))
void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e)
{
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ /* Can't return a value. :( */
+ return;
if (int_table_check(table, 0))
lh_ENGINE_PILE_doall_ENGINE(&(*table)->piles, int_unregister_cb, e);
CRYPTO_THREAD_unlock(global_engine_lock);
void engine_table_cleanup(ENGINE_TABLE **table)
{
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return;
if (*table) {
lh_ENGINE_PILE_doall(&(*table)->piles, int_cleanup_cb_doall);
lh_ENGINE_PILE_free(&(*table)->piles);
return NULL;
}
ERR_set_mark();
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ goto end;
/*
* Check again inside the lock otherwise we could race against cleanup
* operations. But don't worry about a debug printout
return NULL;
}
- CRYPTO_THREAD_write_lock(global_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(global_engine_lock))
+ return NULL;
engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr);
/* If found obtain a structural reference to engine */
if (fstr.e) {
{
ERR_STRING_DATA *p = NULL;
- CRYPTO_THREAD_read_lock(err_string_lock);
+ if (!CRYPTO_THREAD_read_lock(err_string_lock))
+ return NULL;
p = lh_ERR_STRING_DATA_retrieve(int_error_hash, d);
CRYPTO_THREAD_unlock(err_string_lock);
*/
static int err_load_strings(const ERR_STRING_DATA *str)
{
- CRYPTO_THREAD_write_lock(err_string_lock);
+ if (!CRYPTO_THREAD_write_lock(err_string_lock))
+ return 0;
for (; str->error; str++)
(void)lh_ERR_STRING_DATA_insert(int_error_hash,
(ERR_STRING_DATA *)str);
if (!RUN_ONCE(&err_string_init, do_err_strings_init))
return 0;
- CRYPTO_THREAD_write_lock(err_string_lock);
+ if (!CRYPTO_THREAD_write_lock(err_string_lock))
+ return 0;
/*
* We don't need to ERR_PACK the lib, since that was done (to
* the table) when it was loaded.
if (!RUN_ONCE(&err_string_init, do_err_strings_init))
return 0;
- CRYPTO_THREAD_write_lock(err_string_lock);
+ if (!CRYPTO_THREAD_write_lock(err_string_lock))
+ return 0;
ret = int_err_library_number++;
CRYPTO_THREAD_unlock(err_string_lock);
return ret;
if (pk->keymgmt == keymgmt)
return pk->keydata;
- CRYPTO_THREAD_read_lock(pk->lock);
+ if (!CRYPTO_THREAD_read_lock(pk->lock))
+ return NULL;
/*
* If the provider native "origin" hasn't changed since last time, we
* try to find our keymgmt in the operation cache. If it has changed
return NULL;
}
- CRYPTO_THREAD_write_lock(pk->lock);
+ if (!CRYPTO_THREAD_write_lock(pk->lock)) {
+ evp_keymgmt_freedata(keymgmt, import_data.keydata);
+ return NULL;
+ }
/* Check to make sure some other thread didn't get there first */
op = evp_keymgmt_util_find_operation_cache(pk, keymgmt);
if (op != NULL && op->keydata != NULL) {
return NULL;
}
- CRYPTO_THREAD_write_lock(global->ex_data_lock);
+ if (!CRYPTO_THREAD_write_lock(global->ex_data_lock))
+ return NULL;
ip = &global->ex_data[class_index];
return ip;
}
if (storage != NULL)
f = storage[i];
else {
- CRYPTO_THREAD_write_lock(global->ex_data_lock);
+ 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 (settings == NULL) {
ret = RUN_ONCE(&config, ossl_init_config);
} else {
- CRYPTO_THREAD_write_lock(init_lock);
+ if (!CRYPTO_THREAD_write_lock(init_lock))
+ return 0;
conf_settings = settings;
ret = RUN_ONCE_ALT(&config, ossl_init_config_settings,
ossl_init_config);
if (gtr == NULL)
return 0;
- CRYPTO_THREAD_write_lock(gtr->lock);
+ if (!CRYPTO_THREAD_write_lock(gtr->lock))
+ return 0;
ret = (sk_THREAD_EVENT_HANDLER_PTR_push(gtr->skhands, hands) != 0);
CRYPTO_THREAD_unlock(gtr->lock);
gtr = get_global_tevent_register();
if (gtr == NULL)
return;
- CRYPTO_THREAD_write_lock(gtr->lock);
+ if (!CRYPTO_THREAD_write_lock(gtr->lock))
+ return;
for (i = 0; i < sk_THREAD_EVENT_HANDLER_PTR_num(gtr->skhands); i++) {
THREAD_EVENT_HANDLER **hands
= sk_THREAD_EVENT_HANDLER_PTR_value(gtr->skhands, i);
gtr = get_global_tevent_register();
if (gtr == NULL)
return 0;
- if (!all)
- CRYPTO_THREAD_write_lock(gtr->lock);
- else
+ if (!all) {
+ if (!CRYPTO_THREAD_write_lock(gtr->lock))
+ return 0;
+ } else {
glob_tevent_reg = NULL;
+ }
for (i = 0; i < sk_THREAD_EVENT_HANDLER_PTR_num(gtr->skhands); i++) {
THREAD_EVENT_HANDLER **hands
= sk_THREAD_EVENT_HANDLER_PTR_value(gtr->skhands, i);
if (!secure_mem_initialized) {
return CRYPTO_malloc(num, file, line);
}
- CRYPTO_THREAD_write_lock(sec_malloc_lock);
+ if (!CRYPTO_THREAD_write_lock(sec_malloc_lock))
+ return NULL;
ret = sh_malloc(num);
actual_size = ret ? sh_actual_size(ret) : 0;
secure_mem_used += actual_size;
CRYPTO_free(ptr, file, line);
return;
}
- CRYPTO_THREAD_write_lock(sec_malloc_lock);
+ if (!CRYPTO_THREAD_write_lock(sec_malloc_lock))
+ return;
actual_size = sh_actual_size(ptr);
CLEAR(ptr, actual_size);
secure_mem_used -= actual_size;
CRYPTO_free(ptr, file, line);
return;
}
- CRYPTO_THREAD_write_lock(sec_malloc_lock);
+ if (!CRYPTO_THREAD_write_lock(sec_malloc_lock))
+ return;
actual_size = sh_actual_size(ptr);
CLEAR(ptr, actual_size);
secure_mem_used -= actual_size;
if (!secure_mem_initialized)
return 0;
- CRYPTO_THREAD_write_lock(sec_malloc_lock);
+ if (!CRYPTO_THREAD_write_lock(sec_malloc_lock))
+ return 0;
ret = sh_allocated(ptr);
CRYPTO_THREAD_unlock(sec_malloc_lock);
return ret;
#ifndef OPENSSL_NO_SECURE_MEMORY
size_t actual_size;
- CRYPTO_THREAD_write_lock(sec_malloc_lock);
+ if (!CRYPTO_THREAD_write_lock(sec_malloc_lock))
+ return 0;
actual_size = sh_actual_size(ptr);
CRYPTO_THREAD_unlock(sec_malloc_lock);
return actual_size;
if (!OBJ_NAME_init())
return 0;
- CRYPTO_THREAD_write_lock(obj_lock);
+ if (!CRYPTO_THREAD_write_lock(obj_lock))
+ return 0;
if (name_funcs_stack == NULL)
name_funcs_stack = sk_NAME_FUNCS_new_null();
return NULL;
if (!OBJ_NAME_init())
return NULL;
- CRYPTO_THREAD_read_lock(obj_lock);
+ if (!CRYPTO_THREAD_read_lock(obj_lock))
+ return NULL;
alias = type & OBJ_NAME_ALIAS;
type &= ~OBJ_NAME_ALIAS;
type &= ~OBJ_NAME_ALIAS;
onp = OPENSSL_malloc(sizeof(*onp));
- if (onp == NULL) {
- /* ERROR */
- goto unlock;
- }
+ if (onp == NULL)
+ return 0;
onp->name = name;
onp->alias = alias;
onp->type = type;
onp->data = data;
- CRYPTO_THREAD_write_lock(obj_lock);
+ if (!CRYPTO_THREAD_write_lock(obj_lock)) {
+ OPENSSL_free(onp);
+ return 0;
+ }
ret = lh_OBJ_NAME_insert(names_lh, onp);
if (ret != NULL) {
if (!OBJ_NAME_init())
return 0;
- CRYPTO_THREAD_write_lock(obj_lock);
+ if (!CRYPTO_THREAD_write_lock(obj_lock))
+ return 0;
type &= ~OBJ_NAME_ALIAS;
on.name = name;
struct provider_store_st *store;
if ((store = get_provider_store(libctx)) != NULL) {
- CRYPTO_THREAD_write_lock(store->lock);
+ if (!CRYPTO_THREAD_write_lock(store->lock))
+ return 0;
store->use_fallbacks = 0;
CRYPTO_THREAD_unlock(store->lock);
return 1;
#endif
tmpl.name = (char *)name;
- CRYPTO_THREAD_write_lock(store->lock);
+ if (!CRYPTO_THREAD_write_lock(store->lock))
+ return NULL;
if ((i = sk_OSSL_PROVIDER_find(store->providers, &tmpl)) == -1
|| (prov = sk_OSSL_PROVIDER_value(store->providers, i)) == NULL
|| !ossl_provider_up_ref(prov))
if ((prov = provider_new(name, init_function)) == NULL)
return NULL;
- CRYPTO_THREAD_write_lock(store->lock);
+ if (!CRYPTO_THREAD_write_lock(store->lock))
+ return NULL;
if (!ossl_provider_up_ref(prov)) { /* +1 One reference for the store */
ossl_provider_free(prov); /* -1 Reference that was to be returned */
prov = NULL;
* modifies a number of things in the provider structure that this
* function needs to perform under lock anyway.
*/
- CRYPTO_THREAD_write_lock(prov->flag_lock);
+ if (!CRYPTO_THREAD_write_lock(prov->flag_lock))
+ goto end;
if (prov->flag_initialized) {
ok = 1;
goto end;
return 0;
if (ref < 1) {
- CRYPTO_THREAD_write_lock(prov->flag_lock);
+ if (!CRYPTO_THREAD_write_lock(prov->flag_lock))
+ return 0;
prov->flag_activated = 0;
CRYPTO_THREAD_unlock(prov->flag_lock);
}
return 0;
if (provider_init(prov)) {
- CRYPTO_THREAD_write_lock(prov->flag_lock);
+ if (!CRYPTO_THREAD_write_lock(prov->flag_lock))
+ return 0;
prov->flag_activated = 1;
CRYPTO_THREAD_unlock(prov->flag_lock);
return 0;
if (provider_activate(prov)) {
if (!retain_fallbacks) {
- CRYPTO_THREAD_write_lock(prov->store->lock);
+ if (!CRYPTO_THREAD_write_lock(prov->store->lock)) {
+ provider_deactivate(prov);
+ return 0;
+ }
prov->store->use_fallbacks = 0;
CRYPTO_THREAD_unlock(prov->store->lock);
}
int activated_fallback_count = 0;
int i;
- CRYPTO_THREAD_read_lock(store->lock);
+ if (!CRYPTO_THREAD_read_lock(store->lock))
+ return;
use_fallbacks = store->use_fallbacks;
CRYPTO_THREAD_unlock(store->lock);
if (!use_fallbacks)
return;
- CRYPTO_THREAD_write_lock(store->lock);
+ if (!CRYPTO_THREAD_write_lock(store->lock))
+ return;
/* Check again, just in case another thread changed it */
use_fallbacks = store->use_fallbacks;
if (!use_fallbacks) {
* Under lock, grab a copy of the provider list and up_ref each
* provider so that they don't disappear underneath us.
*/
- CRYPTO_THREAD_read_lock(store->lock);
+ if (!CRYPTO_THREAD_read_lock(store->lock))
+ return 0;
provs = sk_OSSL_PROVIDER_dup(store->providers);
if (provs == NULL) {
CRYPTO_THREAD_unlock(store->lock);
size_t byte = bitnum / 8;
unsigned char bit = (1 << (bitnum % 8)) & 0xFF;
- CRYPTO_THREAD_write_lock(provider->opbits_lock);
+ if (!CRYPTO_THREAD_write_lock(provider->opbits_lock))
+ return 0;
if (provider->operation_bits_sz <= byte) {
unsigned char *tmp = OPENSSL_realloc(provider->operation_bits,
byte + 1);
}
*result = 0;
- CRYPTO_THREAD_read_lock(provider->opbits_lock);
+ if (!CRYPTO_THREAD_read_lock(provider->opbits_lock))
+ return 0;
if (provider->operation_bits_sz > byte)
*result = ((provider->operation_bits[byte] & bit) != 0);
CRYPTO_THREAD_unlock(provider->opbits_lock);
if (!RUN_ONCE(&rand_init, do_rand_init))
return 0;
- CRYPTO_THREAD_write_lock(rand_meth_lock);
+ if (!CRYPTO_THREAD_write_lock(rand_meth_lock))
+ return 0;
# ifndef OPENSSL_NO_ENGINE
ENGINE_finish(funct_ref);
funct_ref = NULL;
if (!RUN_ONCE(&rand_init, do_rand_init))
return NULL;
- CRYPTO_THREAD_write_lock(rand_meth_lock);
+ if (!CRYPTO_THREAD_write_lock(rand_meth_lock))
+ return NULL;
if (default_RAND_meth == NULL) {
# ifndef OPENSSL_NO_ENGINE
ENGINE *e;
return 0;
}
}
- CRYPTO_THREAD_write_lock(rand_engine_lock);
+ if (!CRYPTO_THREAD_write_lock(rand_engine_lock)) {
+ ENGINE_finish(engine);
+ return 0;
+ }
+
/* This function releases any prior ENGINE so call it first */
RAND_set_rand_method(tmp_meth);
funct_ref = engine;
{
BN_BLINDING *ret;
- CRYPTO_THREAD_write_lock(rsa->lock);
+ if (!CRYPTO_THREAD_write_lock(rsa->lock))
+ return NULL;
if (rsa->blinding == NULL) {
rsa->blinding = RSA_setup_blinding(rsa, ctx);
ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
return 0;
}
- CRYPTO_THREAD_write_lock(registry_lock);
+ if (!CRYPTO_THREAD_write_lock(registry_lock))
+ return 0;
if (ossl_store_register_init()
&& (lh_OSSL_STORE_LOADER_insert(loader_register, loader) != NULL
ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
return NULL;
}
- CRYPTO_THREAD_write_lock(registry_lock);
+ if (!CRYPTO_THREAD_write_lock(registry_lock))
+ return NULL;
if (!ossl_store_register_init())
ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_INTERNAL_ERROR);
ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
return NULL;
}
- CRYPTO_THREAD_write_lock(registry_lock);
+ if (!CRYPTO_THREAD_write_lock(registry_lock))
+ return NULL;
if (!ossl_store_register_init())
ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_INTERNAL_ERROR);
return lock;
}
-int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
+__owur int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
{
if (!ossl_assert(*(unsigned int *)lock == 1))
return 0;
return 1;
}
-int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
+__owur int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
{
if (!ossl_assert(*(unsigned int *)lock == 1))
return 0;
return lock;
}
-int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
+__owur int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
{
# ifdef USE_RWLOCK
if (pthread_rwlock_rdlock(lock) != 0)
return 1;
}
-int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
+__owur int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
{
# ifdef USE_RWLOCK
if (pthread_rwlock_wrlock(lock) != 0)
return lock;
}
-int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
+__owur int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
{
# ifdef USE_RWLOCK
CRYPTO_win_rwlock *rwlock = lock;
return 1;
}
-int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
+__owur int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
{
# ifdef USE_RWLOCK
CRYPTO_win_rwlock *rwlock = lock;
prefix = trace_channels[category].prefix;
if (channel != NULL) {
- CRYPTO_THREAD_write_lock(trace_lock);
+ if (!CRYPTO_THREAD_write_lock(trace_lock))
+ return NULL;
current_channel = channel;
switch (trace_channels[category].type) {
case SIMPLE_CHANNEL:
/* Internal functions to open, handle and close a channel to the console. */
static int open_console(UI *ui)
{
- CRYPTO_THREAD_write_lock(ui->lock);
+ if (!CRYPTO_THREAD_write_lock(ui->lock))
+ return 0;
is_a_tty = 1;
# if defined(OPENSSL_SYS_VXWORKS)
}
if (type == X509_LU_CRL && ent->hashes) {
htmp.hash = h;
- CRYPTO_THREAD_read_lock(ctx->lock);
+ if (!CRYPTO_THREAD_read_lock(ctx->lock))
+ goto finish;
idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp);
if (idx >= 0) {
hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
/* If a CRL, update the last file suffix added for this */
if (type == X509_LU_CRL) {
- CRYPTO_THREAD_write_lock(ctx->lock);
+ if (!CRYPTO_THREAD_write_lock(ctx->lock))
+ goto finish;
/*
* Look for entry again in case another thread added an entry
* first.
{
if (x->policy_cache == NULL) {
- CRYPTO_THREAD_write_lock(x->lock);
+ if (!CRYPTO_THREAD_write_lock(x->lock))
+ return NULL;
policy_cache_new(x);
CRYPTO_THREAD_unlock(x->lock);
}
return (x->ex_flags & EXFLAG_INVALID) == 0;
#endif
- CRYPTO_THREAD_write_lock(x->lock);
+ if (!CRYPTO_THREAD_write_lock(x->lock))
+ return 0;
if (x->ex_flags & EXFLAG_SET) { /* Cert has already been processed */
CRYPTO_THREAD_unlock(x->lock);
return (x->ex_flags & EXFLAG_INVALID) == 0;
* under a lock to avoid race condition.
*/
if (!sk_X509_REVOKED_is_sorted(crl->crl.revoked)) {
- CRYPTO_THREAD_write_lock(crl->lock);
+ if (!CRYPTO_THREAD_write_lock(crl->lock))
+ return 0;
sk_X509_REVOKED_sort(crl->crl.revoked);
CRYPTO_THREAD_unlock(crl->lock);
}
B<OSSL_NAMEMAP>, or NULL on error.
ossl_namemap_empty() returns 1 if the B<OSSL_NAMEMAP> is NULL or
-empty, or 0 if it's not empty.
+empty, 0 if it's not empty, or -1 on internal error (such as inability
+to lock).
ossl_namemap_add_name() and ossl_namemap_add_name_n() return the number
associated with the added string, or zero on error.
typedef void CRYPTO_RWLOCK;
CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void);
-int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock);
-int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock);
+__owur int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock);
+__owur int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock);
int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock);
void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock);
#include <openssl/evp.h>
#include <openssl/params.h>
#include <openssl/crypto.h>
+#include <internal/cryptlib.h>
#include <openssl/fipskey.h>
#include <openssl/err.h>
#include <openssl/proverr.h>
static void set_fips_state(int state)
{
- CRYPTO_THREAD_write_lock(fips_state_lock);
- FIPS_state = state;
- CRYPTO_THREAD_unlock(fips_state_lock);
+ if (ossl_assert(CRYPTO_THREAD_write_lock(fips_state_lock) != 0)) {
+ FIPS_state = state;
+ CRYPTO_THREAD_unlock(fips_state_lock);
+ }
}
/* This API is triggered either on loading of the FIPS module or on demand */
if (!RUN_ONCE(&fips_self_test_init, do_fips_self_test_init))
return 0;
- CRYPTO_THREAD_read_lock(fips_state_lock);
+ if (!CRYPTO_THREAD_read_lock(fips_state_lock))
+ return 0;
loclstate = FIPS_state;
CRYPTO_THREAD_unlock(fips_state_lock);
return 0;
}
- CRYPTO_THREAD_write_lock(self_test_lock);
- CRYPTO_THREAD_read_lock(fips_state_lock);
+ if (!CRYPTO_THREAD_write_lock(self_test_lock))
+ return 0;
+ if (!CRYPTO_THREAD_read_lock(fips_state_lock)) {
+ CRYPTO_THREAD_unlock(self_test_lock);
+ return 0;
+ }
if (FIPS_state == FIPS_STATE_RUNNING) {
CRYPTO_THREAD_unlock(fips_state_lock);
if (!on_demand_test) {
int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb)
{
- CRYPTO_THREAD_write_lock(ctx->lock);
+ if (!CRYPTO_THREAD_write_lock(ctx->lock))
+ return 0;
ctx->generate_session_id = cb;
CRYPTO_THREAD_unlock(ctx->lock);
return 1;
int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb)
{
- CRYPTO_THREAD_write_lock(ssl->lock);
+ if (!CRYPTO_THREAD_write_lock(ssl->lock))
+ return 0;
ssl->generate_session_id = cb;
CRYPTO_THREAD_unlock(ssl->lock);
return 1;
r.session_id_length = id_len;
memcpy(r.session_id, id, id_len);
- CRYPTO_THREAD_read_lock(ssl->session_ctx->lock);
+ if (!CRYPTO_THREAD_read_lock(ssl->session_ctx->lock))
+ return 0;
p = lh_SSL_SESSION_retrieve(ssl->session_ctx->sessions, &r);
CRYPTO_THREAD_unlock(ssl->session_ctx->lock);
return (p != NULL);
* somebody doesn't free ssl->session between when we check it's non-null
* and when we up the reference count.
*/
- CRYPTO_THREAD_read_lock(ssl->lock);
+ if (!CRYPTO_THREAD_read_lock(ssl->lock))
+ return NULL;
sess = ssl->session;
if (sess)
SSL_SESSION_up_ref(sess);
}
/* Choose which callback will set the session ID */
- CRYPTO_THREAD_read_lock(s->lock);
- CRYPTO_THREAD_read_lock(s->session_ctx->lock);
+ if (!CRYPTO_THREAD_read_lock(s->lock))
+ return 0;
+ if (!CRYPTO_THREAD_read_lock(s->session_ctx->lock)) {
+ CRYPTO_THREAD_unlock(s->lock);
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+ SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
+ return 0;
+ }
if (s->generate_session_id)
cb = s->generate_session_id;
else if (s->session_ctx->generate_session_id)
memcpy(data.session_id, sess_id, sess_id_len);
data.session_id_length = sess_id_len;
- CRYPTO_THREAD_read_lock(s->session_ctx->lock);
+ if (!CRYPTO_THREAD_read_lock(s->session_ctx->lock))
+ return NULL;
ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data);
if (ret != NULL) {
/* don't allow other threads to steal it: */
* if session c is in already in cache, we take back the increment later
*/
- CRYPTO_THREAD_write_lock(ctx->lock);
+ if (!CRYPTO_THREAD_write_lock(ctx->lock)) {
+ SSL_SESSION_free(c);
+ return 0;
+ }
s = lh_SSL_SESSION_insert(ctx->sessions, c);
/*
int ret = 0;
if ((c != NULL) && (c->session_id_length != 0)) {
- if (lck)
- CRYPTO_THREAD_write_lock(ctx->lock);
+ if (lck) {
+ if (!CRYPTO_THREAD_write_lock(ctx->lock))
+ return 0;
+ }
if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) != NULL) {
ret = 1;
r = lh_SSL_SESSION_delete(ctx->sessions, r);
if (ret)
SSL_SESSION_free(r);
- } else
- ret = 0;
+ }
return ret;
}
if (tp.cache == NULL)
return;
tp.time = t;
- CRYPTO_THREAD_write_lock(s->lock);
+ if (!CRYPTO_THREAD_write_lock(s->lock))
+ return;
i = lh_SSL_SESSION_get_down_load(s->sessions);
lh_SSL_SESSION_set_down_load(s->sessions, 0);
lh_SSL_SESSION_doall_TIMEOUT_PARAM(tp.cache, timeout_cb, &tp);
OSSL_NAMEMAP *nm = NULL;
int ok;
- ok = TEST_true(ossl_namemap_empty(NULL))
+ ok = TEST_int_eq(ossl_namemap_empty(NULL), 1)
&& TEST_ptr(nm = ossl_namemap_new())
- && TEST_true(ossl_namemap_empty(nm))
+ && TEST_int_eq(ossl_namemap_empty(nm), 1)
&& TEST_int_ne(ossl_namemap_add_name(nm, 0, NAME1), 0)
- && TEST_false(ossl_namemap_empty(nm));
+ && TEST_int_eq(ossl_namemap_empty(nm), 0);
ossl_namemap_free(nm);
return ok;
}