summaryrefslogtreecommitdiffstats
path: root/crypto/property
diff options
context:
space:
mode:
authorPauli <pauli@openssl.org>2021-06-23 14:18:07 +1000
committerPauli <pauli@openssl.org>2021-06-24 15:51:48 +1000
commit3377f34fb8bcf560c83627ed44c99c09c0b6a772 (patch)
treee0a36ef84abf4a0a0955e3785cdf36ac06ba5101 /crypto/property
parente3c507797acc6049f5791062cd9b2fa5fe0aa824 (diff)
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)
Diffstat (limited to 'crypto/property')
-rw-r--r--crypto/property/property_string.c61
1 files changed, 43 insertions, 18 deletions
diff --git a/crypto/property/property_string.c b/crypto/property/property_string.c
index c9fde70a76..38deab5af0 100644
--- a/crypto/property/property_string.c
+++ b/crypto/property/property_string.c
@@ -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);
}