diff options
author | slontis <shane.lontis@oracle.com> | 2021-09-02 16:39:21 +1000 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-09-03 12:31:59 +0200 |
commit | 85407b77543a2d4330dbb40f6b8520ea0894a716 (patch) | |
tree | 79891f58a905b7724ad6a5c1660bd59dc021ff9b /crypto/evp | |
parent | 6f2f59944826b5b7e033af438f5831493d0362c9 (diff) | |
download | openssl-85407b77543a2d4330dbb40f6b8520ea0894a716.tar.gz |
Fix double free in EVP_PKEY_CTX_dup()
If the internal operations dupctx() fails then a free is done (e.g. EVP_KEYEXCH_free()). If this is not set to NULL the EVP_PKEY_CTX_free() will do a double free.
This was found by testing kdf_dupctx() in kdf_exch.c (Note this always
fails since the internal KDF's do not have a dup method).
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/16495)
Diffstat (limited to 'crypto/evp')
-rw-r--r-- | crypto/evp/pmeth_lib.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 954166caae..1af1628823 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -500,6 +500,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) = pctx->op.kex.exchange->dupctx(pctx->op.kex.algctx); if (rctx->op.kex.algctx == NULL) { EVP_KEYEXCH_free(rctx->op.kex.exchange); + rctx->op.kex.exchange = NULL; goto err; } return rctx; @@ -517,6 +518,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) = pctx->op.sig.signature->dupctx(pctx->op.sig.algctx); if (rctx->op.sig.algctx == NULL) { EVP_SIGNATURE_free(rctx->op.sig.signature); + rctx->op.sig.signature = NULL; goto err; } return rctx; @@ -534,6 +536,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) = pctx->op.ciph.cipher->dupctx(pctx->op.ciph.algctx); if (rctx->op.ciph.algctx == NULL) { EVP_ASYM_CIPHER_free(rctx->op.ciph.cipher); + rctx->op.ciph.cipher = NULL; goto err; } return rctx; @@ -551,6 +554,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx) = pctx->op.encap.kem->dupctx(pctx->op.encap.algctx); if (rctx->op.encap.algctx == NULL) { EVP_KEM_free(rctx->op.encap.kem); + rctx->op.encap.kem = NULL; goto err; } return rctx; |