]> git.ipfire.org Git - thirdparty/gnulib.git/commitdiff
crypto/sha3-buffer, crypto/sha3: Protect against double frees (regr. today).
authorCollin Funk <collin.funk1@gmail.com>
Sat, 6 Sep 2025 23:38:08 +0000 (16:38 -0700)
committerCollin Funk <collin.funk1@gmail.com>
Sat, 6 Sep 2025 23:38:08 +0000 (16:38 -0700)
* lib/sha3.c (sha3_free_ctx): Only free the EVP_MD_CTX if it is not
NULL, and set it to NULL after freeing.
(DEFINE_SHA3_INIT_CTX, sha3_finish_ctx, sha3_process_bytes): Leave
freeing memory to the caller.
* lib/sha3-stream.c (sha3_xxx_stream): Call sha3_free_ctx on success and
if sha3_init_ctx fails.
* tests/test-sha3-224-buffer.c (main): Add a test that would otherwise
segfault without this patch.
* tests/test-sha3-256-buffer.c (main): Likewise.
* tests/test-sha3-384-buffer.c (main): Likewise.
* tests/test-sha3-512-buffer.c (main): Likewise.

ChangeLog
lib/sha3-stream.c
lib/sha3.c
lib/sha3.h
tests/test-sha3-224-buffer.c
tests/test-sha3-256-buffer.c
tests/test-sha3-384-buffer.c
tests/test-sha3-512-buffer.c

index 5133c402b3e460a084ccee04c136be54d979d51f..49505aaaf9e04e105a19d263a8bc0ee74493d630 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2025-09-06  Collin Funk  <collin.funk1@gmail.com>
 
+       crypto/sha3-buffer, crypto/sha3: Protect against double frees (regr. today).
+       * lib/sha3.c (sha3_free_ctx): Only free the EVP_MD_CTX if it is not
+       NULL, and set it to NULL after freeing.
+       (DEFINE_SHA3_INIT_CTX, sha3_finish_ctx, sha3_process_bytes): Leave
+       freeing memory to the caller.
+       * lib/sha3-stream.c (sha3_xxx_stream): Call sha3_free_ctx on success and
+       if sha3_init_ctx fails.
+       * tests/test-sha3-224-buffer.c (main): Add a test that would otherwise
+       segfault without this patch.
+       * tests/test-sha3-256-buffer.c (main): Likewise.
+       * tests/test-sha3-384-buffer.c (main): Likewise.
+       * tests/test-sha3-512-buffer.c (main): Likewise.
+
        crypto/sha3-buffer: Set errno when OpenSSL functions fail.
        * lib/sha3.c: Include <errno.h>
        (DEFINE_SHA3_INIT_CTX): Set errno to ENOMEM if function fails.
index 43c056e22a3f2bb8bba73f13ae7a9c6b174db3a3..d071ea06f9abdda00df86888acf607535e368ef2 100644 (file)
@@ -57,6 +57,7 @@ sha3_xxx_stream (FILE *stream, char const *alg, void *resblock,
   if (! init_ctx (&ctx))
     {
       free (buffer);
+      sha3_free_ctx (ctx);
       return 1;
     }
   size_t sum;
@@ -135,6 +136,8 @@ sha3_xxx_stream (FILE *stream, char const *alg, void *resblock,
       sha3_free_ctx (&ctx);
       return 1;
     }
+
+  sha3_free_ctx (ctx);
   return 0;
 }
 
index 93b53c8368754a510db028a86bce8b7195d3ba9a..551b4822ff1f3ba1e057df4a15a899a834dd5e7d 100644 (file)
@@ -347,7 +347,6 @@ sha3_process_block (const void *buffer, size_t len, struct sha3_ctx *ctx)
     if (result == 0)                                                    \
       {                                                                 \
         errno = ENOMEM;                                                 \
-        sha3_free_ctx (ctx);                                            \
         return false;                                                   \
       }                                                                 \
     return true;                                                        \
@@ -361,7 +360,11 @@ DEFINE_SHA3_INIT_CTX (512)
 void
 sha3_free_ctx (struct sha3_ctx *ctx)
 {
-  EVP_MD_CTX_free (ctx->evp_ctx);
+  if (ctx->evp_ctx != NULL)
+    {
+      EVP_MD_CTX_free (ctx->evp_ctx);
+      ctx->evp_ctx = NULL;
+    }
 }
 
 void *
@@ -375,7 +378,6 @@ void *
 sha3_finish_ctx (struct sha3_ctx *ctx, void *resbuf)
 {
   int result = EVP_DigestFinal_ex (ctx->evp_ctx, resbuf, NULL);
-  sha3_free_ctx (ctx);
   if (result == 0)
     {
       errno = EINVAL;
@@ -408,7 +410,6 @@ sha3_process_bytes (const void *buffer, size_t len, struct sha3_ctx *ctx)
   if (result == 0)
     {
       errno = EINVAL;
-      sha3_free_ctx (ctx);
       return false;
     }
   return true;
index 259f0d1f56b95e6febc924baf3bc6c86fa5f26c6..bd3a0954820cb391d91eb18f64b9426c99d2712b 100644 (file)
@@ -68,8 +68,7 @@ extern bool sha3_256_init_ctx (struct sha3_ctx *ctx);
 extern bool sha3_384_init_ctx (struct sha3_ctx *ctx);
 extern bool sha3_512_init_ctx (struct sha3_ctx *ctx);
 
-/* Free memory allocated by the init_structure.  This is only required if
-   OpenSSL is used.  */
+/* Free memory allocated by the init_structure.  */
 extern void sha3_free_ctx (struct sha3_ctx *ctx);
 
 /* Starting with the result of former calls of this function (or the
index 0fe5f329d8f8d0769daacb77bc9b4feeb05ec4ce..50512a7e52ce06bbfccdb62c5ed50ea230cb5aef 100644 (file)
@@ -89,5 +89,16 @@ main (void)
       free (large);
     }
 
+  /* Check that sha3_free_ctx can be called multiple times without
+     crashing.  */
+  {
+    struct sha3_ctx ctx;
+    if (sha3_224_init_ctx (&ctx))
+      {
+        sha3_free_ctx (&ctx);
+        sha3_free_ctx (&ctx);
+      }
+  }
+
   return 0;
 }
index 8d47874adca2951c985ff95b37744e469f4561a7..58775718136db57eba9a1571bc7c1098950ccaae 100644 (file)
@@ -90,5 +90,16 @@ main (void)
       free (large);
     }
 
+  /* Check that sha3_free_ctx can be called multiple times without
+     crashing.  */
+  {
+    struct sha3_ctx ctx;
+    if (sha3_256_init_ctx (&ctx))
+      {
+        sha3_free_ctx (&ctx);
+        sha3_free_ctx (&ctx);
+      }
+  }
+
   return 0;
 }
index c85408ed4a7c2f4fb5067ce4ac3c82db00102933..8f6ff7ef5206736d93829285cf1ca6ab7dee5015 100644 (file)
@@ -95,5 +95,16 @@ main (void)
       free (large);
     }
 
+  /* Check that sha3_free_ctx can be called multiple times without
+     crashing.  */
+  {
+    struct sha3_ctx ctx;
+    if (sha3_384_init_ctx (&ctx))
+      {
+        sha3_free_ctx (&ctx);
+        sha3_free_ctx (&ctx);
+      }
+  }
+
   return 0;
 }
index 535dfde168a511ee785899c6ec226f5e93be05d1..3be928507e7e988b9b4b6ccaa8e3e8ea8ccef39c 100644 (file)
@@ -101,5 +101,16 @@ main (void)
       free (large);
     }
 
+  /* Check that sha3_free_ctx can be called multiple times without
+     crashing.  */
+  {
+    struct sha3_ctx ctx;
+    if (sha3_512_init_ctx (&ctx))
+      {
+        sha3_free_ctx (&ctx);
+        sha3_free_ctx (&ctx);
+      }
+  }
+
   return 0;
 }