summaryrefslogtreecommitdiff
path: root/crypto/evp
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2021-12-10 17:17:27 +0000
committerMatt Caswell <matt@openssl.org>2022-01-10 16:38:35 +0000
commit357bccc8ba64ec8a5f587b04b5d6b6ca9e8dcbdc (patch)
tree1084f1b3497e0aee5b21aebead310d480a12cc7c /crypto/evp
parentd9ad5b16b32172df6f7d02cfb1c339cc85d0db01 (diff)
downloadopenssl-new-357bccc8ba64ec8a5f587b04b5d6b6ca9e8dcbdc.tar.gz
Fix a leak in EVP_DigestInit_ex()
If an EVP_MD_CTX is reused then memory allocated and stored in md_data can be leaked unless the EVP_MD's cleanup function is called. Fixes #17149 Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> (Merged from https://github.com/openssl/openssl/pull/17255)
Diffstat (limited to 'crypto/evp')
-rw-r--r--crypto/evp/digest.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index 5fe80a63f4..cdcb60092e 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -25,6 +25,19 @@
#include "crypto/evp.h"
#include "evp_local.h"
+static void cleanup_old_md_data(EVP_MD_CTX *ctx, int force)
+{
+ if (ctx->digest != NULL) {
+ if (ctx->digest->cleanup != NULL
+ && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
+ ctx->digest->cleanup(ctx);
+ if (ctx->md_data != NULL && ctx->digest->ctx_size > 0
+ && (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)
+ || force))
+ OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
+ ctx->md_data = NULL;
+ }
+}
void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force)
{
@@ -41,12 +54,7 @@ void evp_md_ctx_clear_digest(EVP_MD_CTX *ctx, int force)
* Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
* sometimes only copies of the context are ever finalised.
*/
- if (ctx->digest && ctx->digest->cleanup
- && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
- ctx->digest->cleanup(ctx);
- if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
- && (!EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE) || force))
- OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
+ cleanup_old_md_data(ctx, force);
if (force)
ctx->digest = NULL;
@@ -217,10 +225,7 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type,
goto legacy;
}
- if (ctx->digest != NULL && ctx->digest->ctx_size > 0) {
- OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
- ctx->md_data = NULL;
- }
+ cleanup_old_md_data(ctx, 1);
/* Start of non-legacy code below */
@@ -309,10 +314,8 @@ static int evp_md_init_internal(EVP_MD_CTX *ctx, const EVP_MD *type,
}
#endif
if (ctx->digest != type) {
- if (ctx->digest && ctx->digest->ctx_size) {
- OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size);
- ctx->md_data = NULL;
- }
+ cleanup_old_md_data(ctx, 1);
+
ctx->digest = type;
if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
ctx->update = type->update;