From: Richard Levitte Date: Sat, 11 Apr 2020 11:16:22 +0000 (+0200) Subject: EVP: fix memleak in evp_pkey_downgrade() X-Git-Tag: openssl-3.0.0-alpha1~104 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=49276c3569656a17c24517ff0781967ced2c9658;hp=813d31717853252e777b810cb74fa5793fcbb154 EVP: fix memleak in evp_pkey_downgrade() The EVP_KEYMGMT pointer in the pkey is removed when downgrading, but wasn't necessarily freed when need, thus leaving an incorrect reference count. Reviewed-by: Matt Caswell Reviewed-by: Nicola Tuveri (Merged from https://github.com/openssl/openssl/pull/11328) --- diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index c1a8a8804d..9f04c72330 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -1559,8 +1559,11 @@ int evp_pkey_downgrade(EVP_PKEY *pk) evp_pkey_free_it(pk); if (EVP_PKEY_set_type(pk, type)) { /* If the key is typed but empty, we're done */ - if (keydata == NULL) + if (keydata == NULL) { + /* We're dropping the EVP_KEYMGMT */ + EVP_KEYMGMT_free(keymgmt); return 1; + } if (pk->ameth->import_from == NULL) { ERR_raise_data(ERR_LIB_EVP, EVP_R_NO_IMPORT_FUNCTION, @@ -1579,6 +1582,9 @@ int evp_pkey_downgrade(EVP_PKEY *pk) /* Synchronize the dirty count */ pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk); + + /* evp_keymgmt_export() increased the refcount... */ + EVP_KEYMGMT_free(keymgmt); return 1; } @@ -1597,6 +1603,8 @@ int evp_pkey_downgrade(EVP_PKEY *pk) ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR); return 0; } + /* EVP_PKEY_set_type_by_keymgmt() increased the refcount... */ + EVP_KEYMGMT_free(keymgmt); pk->keydata = keydata; evp_keymgmt_util_cache_keyinfo(pk); return 0; /* No downgrade, but at least the key is restored */