diff options
author | Richard Levitte <levitte@openssl.org> | 2019-03-14 21:51:50 +0100 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2019-03-18 14:27:02 +0100 |
commit | a383083194b882a904ae66fcf74ebc348602407c (patch) | |
tree | 3595ff7b0a6161c63cc8d9bc2e971d3c9f64bd03 /crypto/core_fetch.c | |
parent | 7bb19a0f950dd87607133d526e31a083f35921fd (diff) |
Replumbing: better reference counter control in ossl_method_construct()
Fully assume that the method constructors use reference counting.
Otherwise, we may leak memory, or loose track and do a double free.
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8341)
Diffstat (limited to 'crypto/core_fetch.c')
-rw-r--r-- | crypto/core_fetch.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/crypto/core_fetch.c b/crypto/core_fetch.c index bfdd36d429..d38e1325c6 100644 --- a/crypto/core_fetch.c +++ b/crypto/core_fetch.c @@ -39,25 +39,33 @@ static int ossl_method_construct_this(OSSL_PROVIDER *provider, void *cbdata) data->mcm_data)) == NULL) continue; + /* + * Note regarding putting the method in stores: + * + * we don't need to care if it actually got in or not here. + * If it didn't get in, it will simply not be available when + * ossl_method_construct() tries to get it from the store. + * + * It is *expected* that the put function increments the refcnt + * of the passed method. + */ + if (data->force_store || !no_store) { /* * If we haven't been told not to store, * add to the global store */ - if (!data->mcm->put(data->libctx, NULL, - thismap->property_definition, - method, data->mcm_data)) { - data->mcm->destruct(method, data->mcm_data); - continue; - } + data->mcm->put(data->libctx, NULL, + thismap->property_definition, + method, data->mcm_data); } - if (!data->mcm->put(data->libctx, data->store, - thismap->property_definition, - method, data->mcm_data)) { - data->mcm->destruct(method, data->mcm_data); - continue; - } + data->mcm->put(data->libctx, data->store, + thismap->property_definition, + method, data->mcm_data); + + /* refcnt-- because we're dropping the reference */ + data->mcm->destruct(method, data->mcm_data); } return 1; |