Free a fetched digest during EVP_MD_CTX_reset() not EVP_MD_free()
authorMatt Caswell <matt@openssl.org>
Thu, 26 Sep 2019 13:55:00 +0000 (14:55 +0100)
committerMatt Caswell <matt@openssl.org>
Thu, 3 Oct 2019 08:47:34 +0000 (09:47 +0100)
Otherwise a mem leak can occur since EVP_MD_free() calls
EVP_MD_CTX_reset() which then clears the contents of the ctx.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/10013)

crypto/evp/digest.c

index 6609e8f..874b16b 100644 (file)
@@ -34,8 +34,9 @@ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
         EVP_PKEY_CTX_free(ctx->pctx);
 #endif
 
         EVP_PKEY_CTX_free(ctx->pctx);
 #endif
 
-    if (ctx->digest == NULL || ctx->digest->prov == NULL)
-        goto legacy;
+    EVP_MD_free(ctx->fetched_digest);
+    ctx->fetched_digest = NULL;
+    ctx->reqdigest = NULL;
 
     if (ctx->provctx != NULL) {
         if (ctx->digest->freectx != NULL)
 
     if (ctx->provctx != NULL) {
         if (ctx->digest->freectx != NULL)
@@ -44,13 +45,7 @@ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
         EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
     }
 
         EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
     }
 
-    if (ctx->pctx != NULL)
-        goto legacy;
-
-    return 1;
-
     /* TODO(3.0): Remove legacy code below */
     /* TODO(3.0): Remove legacy code below */
- legacy:
 
     /*
      * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
 
     /*
      * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
@@ -67,6 +62,9 @@ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
 #if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE)
     ENGINE_finish(ctx->engine);
 #endif
 #if !defined(FIPS_MODE) && !defined(OPENSSL_NO_ENGINE)
     ENGINE_finish(ctx->engine);
 #endif
+
+    /* TODO(3.0): End of legacy code */
+
     OPENSSL_cleanse(ctx, sizeof(*ctx));
 
     return 1;
     OPENSSL_cleanse(ctx, sizeof(*ctx));
 
     return 1;
@@ -84,11 +82,6 @@ void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
 
     EVP_MD_CTX_reset(ctx);
 
 
     EVP_MD_CTX_reset(ctx);
 
-    EVP_MD_free(ctx->fetched_digest);
-    ctx->fetched_digest = NULL;
-    ctx->digest = NULL;
-    ctx->reqdigest = NULL;
-
     OPENSSL_free(ctx);
     return;
 }
     OPENSSL_free(ctx);
     return;
 }