Skip to content

Commit

Permalink
property: reduce memory consumption when OPENSSL_SMALL_FOOTPRINT is d…
Browse files Browse the repository at this point in the history
…efined.

This takes out the lock step stacks that allow a fast property to name
resolution.  Follow on from #17325.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from #17388)

(cherry picked from commit 5764533)
Reviewed-by: Hugo Landau <hlandau@openssl.org>
  • Loading branch information
paulidale authored and t8m committed Nov 9, 2022
1 parent 8ea185e commit 852bb13
Showing 1 changed file with 46 additions and 4 deletions.
50 changes: 46 additions & 4 deletions crypto/property/property_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ typedef struct {
PROP_TABLE *prop_values;
OSSL_PROPERTY_IDX prop_name_idx;
OSSL_PROPERTY_IDX prop_value_idx;
#ifndef OPENSSL_SMALL_FOOTPRINT
STACK_OF(OPENSSL_CSTRING) *prop_namelist;
STACK_OF(OPENSSL_CSTRING) *prop_valuelist;
#endif
} PROPERTY_STRING_DATA;

static unsigned long property_hash(const PROPERTY_STRING *a)
Expand Down Expand Up @@ -80,9 +82,11 @@ static void property_string_data_free(void *vpropdata)
CRYPTO_THREAD_lock_free(propdata->lock);
property_table_free(&propdata->prop_names);
property_table_free(&propdata->prop_values);
#ifndef OPENSSL_SMALL_FOOTPRINT
sk_OPENSSL_CSTRING_free(propdata->prop_namelist);
sk_OPENSSL_CSTRING_free(propdata->prop_valuelist);
propdata->prop_namelist = propdata->prop_valuelist = NULL;
#endif
propdata->prop_name_idx = propdata->prop_value_idx = 0;

OPENSSL_free(propdata);
Expand All @@ -99,13 +103,17 @@ static void *property_string_data_new(OSSL_LIB_CTX *ctx) {
&property_cmp);
propdata->prop_values = lh_PROPERTY_STRING_new(&property_hash,
&property_cmp);
#ifndef OPENSSL_SMALL_FOOTPRINT
propdata->prop_namelist = sk_OPENSSL_CSTRING_new_null();
propdata->prop_valuelist = sk_OPENSSL_CSTRING_new_null();
#endif
if (propdata->lock == NULL
|| propdata->prop_names == NULL
|| propdata->prop_values == NULL
#ifndef OPENSSL_SMALL_FOOTPRINT
|| propdata->prop_namelist == NULL
|| propdata->prop_valuelist == NULL) {
|| propdata->prop_valuelist == NULL
#endif
|| propdata->prop_names == NULL
|| propdata->prop_values == NULL) {
property_string_data_free(propdata);
return NULL;
}
Expand Down Expand Up @@ -141,7 +149,6 @@ static OSSL_PROPERTY_IDX ossl_property_string(OSSL_LIB_CTX *ctx, int name,
{
PROPERTY_STRING p, *ps, *ps_new;
PROP_TABLE *t;
STACK_OF(OPENSSL_CSTRING) *slist;
OSSL_PROPERTY_IDX *pidx;
PROPERTY_STRING_DATA *propdata
= ossl_lib_ctx_get_data(ctx, OSSL_LIB_CTX_PROPERTY_STRING_INDEX,
Expand All @@ -166,19 +173,25 @@ static OSSL_PROPERTY_IDX ossl_property_string(OSSL_LIB_CTX *ctx, int name,
pidx = name ? &propdata->prop_name_idx : &propdata->prop_value_idx;
ps = lh_PROPERTY_STRING_retrieve(t, &p);
if (ps == NULL && (ps_new = new_property_string(s, pidx)) != NULL) {
#ifndef OPENSSL_SMALL_FOOTPRINT
STACK_OF(OPENSSL_CSTRING) *slist;

slist = name ? propdata->prop_namelist : propdata->prop_valuelist;
if (sk_OPENSSL_CSTRING_push(slist, ps_new->s) <= 0) {
property_free(ps_new);
CRYPTO_THREAD_unlock(propdata->lock);
return 0;
}
#endif
lh_PROPERTY_STRING_insert(t, ps_new);
if (lh_PROPERTY_STRING_error(t)) {
/*-
* Undo the previous push which means also decrementing the
* index and freeing the allocated storage.
*/
#ifndef OPENSSL_SMALL_FOOTPRINT
sk_OPENSSL_CSTRING_pop(slist);
#endif
property_free(ps_new);
--*pidx;
CRYPTO_THREAD_unlock(propdata->lock);
Expand All @@ -191,6 +204,21 @@ static OSSL_PROPERTY_IDX ossl_property_string(OSSL_LIB_CTX *ctx, int name,
return ps != NULL ? ps->idx : 0;
}

#ifdef OPENSSL_SMALL_FOOTPRINT
struct find_str_st {
const char *str;
OSSL_PROPERTY_IDX idx;
};

static void find_str_fn(PROPERTY_STRING *prop, void *vfindstr)
{
struct find_str_st *findstr = vfindstr;

if (prop->idx == findstr->idx)
findstr->str = prop->s;
}
#endif

static const char *ossl_property_str(int name, OSSL_LIB_CTX *ctx,
OSSL_PROPERTY_IDX idx)
{
Expand All @@ -206,8 +234,22 @@ static const char *ossl_property_str(int name, OSSL_LIB_CTX *ctx,
ERR_raise(ERR_LIB_CRYPTO, ERR_R_UNABLE_TO_GET_READ_LOCK);
return NULL;
}
#ifdef OPENSSL_SMALL_FOOTPRINT
{
struct find_str_st findstr;

findstr.str = NULL;
findstr.idx = idx;

lh_PROPERTY_STRING_doall_arg(name ? propdata->prop_names
: propdata->prop_values,
find_str_fn, &findstr);
r = findstr.str;
}
#else
r = sk_OPENSSL_CSTRING_value(name ? propdata->prop_namelist
: propdata->prop_valuelist, idx - 1);
#endif
CRYPTO_THREAD_unlock(propdata->lock);

return r;
Expand Down

0 comments on commit 852bb13

Please sign in to comment.