summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2020-12-16 17:01:06 +0100
committerRichard Levitte <levitte@openssl.org>2020-12-17 12:02:08 +0100
commit74cd923a78b490d46af9c3dc5c8dc7a741c5e576 (patch)
tree91eb3c50e9c31d66cef67281f0f9e67d5af906b4 /crypto
parent390f9bad69ce19f601abf131ceabf90aedc0d3d5 (diff)
EVP: Fix memory leak in EVP_PKEY_CTX_dup()
In most error cases, EVP_PKEY_CTX_dup() would only free the EVP_PKEY_CTX without freeing the duplicated contents. Fixes #13503 Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org> (Merged from https://github.com/openssl/openssl/pull/13661)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/evp/pmeth_lib.c46
1 files changed, 17 insertions, 29 deletions
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index f817173555..8fc309dc99 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -455,12 +455,6 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
{
EVP_PKEY_CTX *rctx;
- if (((pctx->pmeth == NULL) || (pctx->pmeth->copy == NULL))
- && ((EVP_PKEY_CTX_IS_DERIVE_OP(pctx)
- && pctx->op.kex.exchprovctx == NULL)
- || (EVP_PKEY_CTX_IS_SIGNATURE_OP(pctx)
- && pctx->op.sig.sigprovctx == NULL)))
- return NULL;
# ifndef OPENSSL_NO_ENGINE
/* Make sure it's safe to copy a pkey context using an ENGINE */
if (pctx->engine && !ENGINE_init(pctx->engine)) {
@@ -483,10 +477,8 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
rctx->propquery = NULL;
if (pctx->propquery != NULL) {
rctx->propquery = OPENSSL_strdup(pctx->propquery);
- if (rctx->propquery == NULL) {
- OPENSSL_free(rctx);
- return NULL;
- }
+ if (rctx->propquery == NULL)
+ goto err;
}
rctx->legacy_keytype = pctx->legacy_keytype;
@@ -494,16 +486,16 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
if (pctx->op.kex.exchange != NULL) {
rctx->op.kex.exchange = pctx->op.kex.exchange;
if (!EVP_KEYEXCH_up_ref(rctx->op.kex.exchange))
- goto end;
+ goto err;
}
if (pctx->op.kex.exchprovctx != NULL) {
if (!ossl_assert(pctx->op.kex.exchange != NULL))
- goto end;
+ goto err;
rctx->op.kex.exchprovctx
= pctx->op.kex.exchange->dupctx(pctx->op.kex.exchprovctx);
if (rctx->op.kex.exchprovctx == NULL) {
EVP_KEYEXCH_free(rctx->op.kex.exchange);
- goto end;
+ goto err;
}
return rctx;
}
@@ -511,16 +503,16 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
if (pctx->op.sig.signature != NULL) {
rctx->op.sig.signature = pctx->op.sig.signature;
if (!EVP_SIGNATURE_up_ref(rctx->op.sig.signature))
- goto end;
+ goto err;
}
if (pctx->op.sig.sigprovctx != NULL) {
if (!ossl_assert(pctx->op.sig.signature != NULL))
- goto end;
+ goto err;
rctx->op.sig.sigprovctx
= pctx->op.sig.signature->dupctx(pctx->op.sig.sigprovctx);
if (rctx->op.sig.sigprovctx == NULL) {
EVP_SIGNATURE_free(rctx->op.sig.signature);
- goto end;
+ goto err;
}
return rctx;
}
@@ -528,16 +520,16 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
if (pctx->op.ciph.cipher != NULL) {
rctx->op.ciph.cipher = pctx->op.ciph.cipher;
if (!EVP_ASYM_CIPHER_up_ref(rctx->op.ciph.cipher))
- goto end;
+ goto err;
}
if (pctx->op.ciph.ciphprovctx != NULL) {
if (!ossl_assert(pctx->op.ciph.cipher != NULL))
- goto end;
+ goto err;
rctx->op.ciph.ciphprovctx
= pctx->op.ciph.cipher->dupctx(pctx->op.ciph.ciphprovctx);
if (rctx->op.ciph.ciphprovctx == NULL) {
EVP_ASYM_CIPHER_free(rctx->op.ciph.cipher);
- goto end;
+ goto err;
}
return rctx;
}
@@ -545,22 +537,22 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
if (pctx->op.encap.kem != NULL) {
rctx->op.encap.kem = pctx->op.encap.kem;
if (!EVP_KEM_up_ref(rctx->op.encap.kem))
- goto end;
+ goto err;
}
if (pctx->op.encap.kemprovctx != NULL) {
if (!ossl_assert(pctx->op.encap.kem != NULL))
- goto end;
+ goto err;
rctx->op.encap.kemprovctx
= pctx->op.encap.kem->dupctx(pctx->op.encap.kemprovctx);
if (rctx->op.encap.kemprovctx == NULL) {
EVP_KEM_free(rctx->op.encap.kem);
- goto end;
+ goto err;
}
return rctx;
}
} else if (EVP_PKEY_CTX_IS_GEN_OP(pctx)) {
/* Not supported - This would need a gen_dupctx() to work */
- goto end;
+ goto err;
}
rctx->pmeth = pctx->pmeth;
@@ -587,17 +579,13 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
rctx->keymgmt = tmp_keymgmt;
return rctx;
}
- goto err;
- }
- if (pctx->pmeth->copy(rctx, pctx) > 0)
+ } else if (pctx->pmeth->copy(rctx, pctx) > 0) {
return rctx;
+ }
err:
rctx->pmeth = NULL;
EVP_PKEY_CTX_free(rctx);
return NULL;
-end:
- OPENSSL_free(rctx);
- return NULL;
}
int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth)