mirror of
https://github.com/openssl/openssl.git
synced 2025-02-17 14:32:04 +08:00
property: add locking for the property string database
This previously relied on the caller locking the property store correctly. This is no longer the case so the string database now requires locking. Fixes #15866 Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15871)
This commit is contained in:
parent
e3c507797a
commit
3377f34fb8
@ -35,6 +35,7 @@ DEFINE_LHASH_OF(PROPERTY_STRING);
|
||||
typedef LHASH_OF(PROPERTY_STRING) PROP_TABLE;
|
||||
|
||||
typedef struct {
|
||||
CRYPTO_RWLOCK *lock;
|
||||
PROP_TABLE *prop_names;
|
||||
PROP_TABLE *prop_values;
|
||||
OSSL_PROPERTY_IDX prop_name_idx;
|
||||
@ -74,6 +75,7 @@ static void property_string_data_free(void *vpropdata)
|
||||
if (propdata == NULL)
|
||||
return;
|
||||
|
||||
CRYPTO_THREAD_lock_free(propdata->lock);
|
||||
property_table_free(&propdata->prop_names);
|
||||
property_table_free(&propdata->prop_values);
|
||||
propdata->prop_name_idx = propdata->prop_value_idx = 0;
|
||||
@ -87,6 +89,10 @@ static void *property_string_data_new(OSSL_LIB_CTX *ctx) {
|
||||
if (propdata == NULL)
|
||||
return NULL;
|
||||
|
||||
propdata->lock = CRYPTO_THREAD_lock_new();
|
||||
if (propdata->lock == NULL)
|
||||
goto err;
|
||||
|
||||
propdata->prop_names = lh_PROPERTY_STRING_new(&property_hash,
|
||||
&property_cmp);
|
||||
if (propdata->prop_names == NULL)
|
||||
@ -128,40 +134,40 @@ static PROPERTY_STRING *new_property_string(const char *s,
|
||||
return ps;
|
||||
}
|
||||
|
||||
static OSSL_PROPERTY_IDX ossl_property_string(PROP_TABLE *t,
|
||||
static OSSL_PROPERTY_IDX ossl_property_string(CRYPTO_RWLOCK *lock,
|
||||
PROP_TABLE *t,
|
||||
OSSL_PROPERTY_IDX *pidx,
|
||||
const char *s)
|
||||
{
|
||||
PROPERTY_STRING p, *ps, *ps_new;
|
||||
|
||||
p.s = s;
|
||||
if (!CRYPTO_THREAD_read_lock(lock)) {
|
||||
ERR_raise(ERR_LIB_CRYPTO, ERR_R_UNABLE_TO_GET_READ_LOCK);
|
||||
return 0;
|
||||
}
|
||||
ps = lh_PROPERTY_STRING_retrieve(t, &p);
|
||||
if (ps == NULL && pidx != NULL)
|
||||
if ((ps_new = new_property_string(s, pidx)) != NULL) {
|
||||
if (ps == NULL && pidx != NULL) {
|
||||
CRYPTO_THREAD_unlock(lock);
|
||||
if (!CRYPTO_THREAD_write_lock(lock)) {
|
||||
ERR_raise(ERR_LIB_CRYPTO, ERR_R_UNABLE_TO_GET_WRITE_LOCK);
|
||||
return 0;
|
||||
}
|
||||
ps = lh_PROPERTY_STRING_retrieve(t, &p);
|
||||
if (ps == NULL && (ps_new = new_property_string(s, pidx)) != NULL) {
|
||||
lh_PROPERTY_STRING_insert(t, ps_new);
|
||||
if (lh_PROPERTY_STRING_error(t)) {
|
||||
property_free(ps_new);
|
||||
CRYPTO_THREAD_unlock(lock);
|
||||
return 0;
|
||||
}
|
||||
ps = ps_new;
|
||||
}
|
||||
}
|
||||
CRYPTO_THREAD_unlock(lock);
|
||||
return ps != NULL ? ps->idx : 0;
|
||||
}
|
||||
|
||||
OSSL_PROPERTY_IDX ossl_property_name(OSSL_LIB_CTX *ctx, const char *s,
|
||||
int create)
|
||||
{
|
||||
PROPERTY_STRING_DATA *propdata
|
||||
= ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_PROPERTY_STRING_INDEX,
|
||||
&property_string_data_method);
|
||||
|
||||
if (propdata == NULL)
|
||||
return 0;
|
||||
return ossl_property_string(propdata->prop_names,
|
||||
create ? &propdata->prop_name_idx : NULL,
|
||||
s);
|
||||
}
|
||||
|
||||
struct find_str_st {
|
||||
const char *str;
|
||||
OSSL_PROPERTY_IDX idx;
|
||||
@ -189,13 +195,32 @@ static const char *ossl_property_str(int name, OSSL_LIB_CTX *ctx,
|
||||
findstr.str = NULL;
|
||||
findstr.idx = idx;
|
||||
|
||||
if (!CRYPTO_THREAD_read_lock(propdata->lock)) {
|
||||
ERR_raise(ERR_LIB_CRYPTO, ERR_R_UNABLE_TO_GET_READ_LOCK);
|
||||
return NULL;
|
||||
}
|
||||
lh_PROPERTY_STRING_doall_arg(name ? propdata->prop_names
|
||||
: propdata->prop_values,
|
||||
find_str_fn, &findstr);
|
||||
CRYPTO_THREAD_unlock(propdata->lock);
|
||||
|
||||
return findstr.str;
|
||||
}
|
||||
|
||||
OSSL_PROPERTY_IDX ossl_property_name(OSSL_LIB_CTX *ctx, const char *s,
|
||||
int create)
|
||||
{
|
||||
PROPERTY_STRING_DATA *propdata
|
||||
= ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_PROPERTY_STRING_INDEX,
|
||||
&property_string_data_method);
|
||||
|
||||
if (propdata == NULL)
|
||||
return 0;
|
||||
return ossl_property_string(propdata->lock, propdata->prop_names,
|
||||
create ? &propdata->prop_name_idx : NULL,
|
||||
s);
|
||||
}
|
||||
|
||||
const char *ossl_property_name_str(OSSL_LIB_CTX *ctx, OSSL_PROPERTY_IDX idx)
|
||||
{
|
||||
return ossl_property_str(1, ctx, idx);
|
||||
@ -210,7 +235,7 @@ OSSL_PROPERTY_IDX ossl_property_value(OSSL_LIB_CTX *ctx, const char *s,
|
||||
|
||||
if (propdata == NULL)
|
||||
return 0;
|
||||
return ossl_property_string(propdata->prop_values,
|
||||
return ossl_property_string(propdata->lock, propdata->prop_values,
|
||||
create ? &propdata->prop_value_idx : NULL,
|
||||
s);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user