]> git.ipfire.org Git - thirdparty/git.git/commitdiff
patch-id: discard hash when done
authorJeff King <peff@peff.net>
Thu, 2 Jul 2026 08:04:11 +0000 (04:04 -0400)
committerJunio C Hamano <gitster@pobox.com>
Thu, 2 Jul 2026 16:50:47 +0000 (09:50 -0700)
When computing a patch-id, we have a flush_one_hunk() helper that calls
git_hash_final() on our running hunk git_hash_ctx, and then
reinitializes that context for the next hunk.

When we run out of hunks to look at, we return, discarding the
git_hash_ctx. This can cause a leak if the hash implementation we are
using allocates any memory during its initialization. This includes
OpenSSL >= 3.0, for both SHA-1 and SHA-256. Normally we would not use
SHA-1 here at all, as we only recommend using non-DC implementations for
the "unsafe" variant (and patch-id, though they probably _could_ use the
unsafe variant, were never taught to do so).

But it is certainly a problem for SHA-256, which you can see with:

  make SANITIZE=leak \
       OPENSSL_SHA256=1 \
       GIT_TEST_DEFAULT_HASH=sha256 \
       test

That results in leak failures of 60 scripts, 57 of which are fixed by
this patch (basically anything which runs rebase will hit this case).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/patch-id.c
diff.c

index 2781598ede6ea065d8847077598016526ce6fb4b..57d9bd4a656d1a102d1b4d910328aafb17135613 100644 (file)
@@ -173,6 +173,7 @@ static size_t get_one_patchid(struct object_id *next_oid, struct object_id *resu
                oidclr(next_oid, the_repository->hash_algo);
 
        flush_one_hunk(result, &ctx);
+       git_hash_discard(&ctx);
 
        return patchlen;
 }
diff --git a/diff.c b/diff.c
index 397e38b41cc6fa5cd46a460c11902c0944047988..f631bf1e2aa47d651686dbb2365a9fdb288fd0e9 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -6958,6 +6958,7 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid
                flush_one_hunk(oid, &ctx);
        }
 
+       git_hash_discard(&ctx);
        return 0;
 }