git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Patrick Steinhardt <ps@pks.im>
To: git@vger.kernel.org
Cc: Eric Sunshine <sunshine@sunshineco.com>,
	Junio C Hamano <gitster@pobox.com>
Subject: [PATCH v2 2/3] cache-tree: detect mismatching number of index entries
Date: Mon, 7 Oct 2024 06:38:18 +0200	[thread overview]
Message-ID: <d63087c53c5e57c63fe27a7a7dffa8fdb312f30a.1728275640.git.ps@pks.im> (raw)
In-Reply-To: <cover.1728275640.git.ps@pks.im>

In t4058 we have some tests that exercise git-read-tree(1) when used
with a tree that contains duplicate entries. While the expectation is
that we fail, we ideally should fail gracefully without a segfault.

But that is not the case: we never check that the number of entries in
the cache-tree is less than or equal to the number of entries in the
index. This can lead to an out-of-bounds read as we unconditionally
access `istate->cache[idx]`, where `idx` is controlled by the number of
cache-tree entries and the current position therein. The result is a
segfault.

Fix this segfault by adding a sanity check for the number of index
entries before dereferencing them.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 cache-tree.c               |  5 +++++
 t/t4058-diff-duplicates.sh | 12 ++++++------
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/cache-tree.c b/cache-tree.c
index 4228b6fad4..1e62567308 100644
--- a/cache-tree.c
+++ b/cache-tree.c
@@ -933,6 +933,11 @@ static int verify_one(struct repository *r,
 		pos = 0;
 	}
 
+	if (it->entry_count + pos > istate->cache_nr) {
+		ret = error(_("corrupted cache-tree has entries not present in index"));
+		goto out;
+	}
+
 	i = 0;
 	while (i < it->entry_count) {
 		struct cache_entry *ce = istate->cache[pos + i];
diff --git a/t/t4058-diff-duplicates.sh b/t/t4058-diff-duplicates.sh
index 2501c89c1c..3f602adb05 100755
--- a/t/t4058-diff-duplicates.sh
+++ b/t/t4058-diff-duplicates.sh
@@ -132,15 +132,15 @@ test_expect_success 'create a few commits' '
 	rm commit_id up final
 '
 
-test_expect_failure 'git read-tree does not segfault' '
-	test_when_finished rm .git/index.lock &&
-	test_might_fail git read-tree --reset base
+test_expect_success 'git read-tree does not segfault' '
+	test_must_fail git read-tree --reset base 2>err &&
+	test_grep "error: corrupted cache-tree has entries not present in index" err
 '
 
-test_expect_failure 'reset --hard does not segfault' '
-	test_when_finished rm .git/index.lock &&
+test_expect_success 'reset --hard does not segfault' '
 	git checkout base &&
-	test_might_fail git reset --hard
+	test_must_fail git reset --hard 2>err &&
+	test_grep "error: corrupted cache-tree has entries not present in index" err
 '
 
 test_expect_failure 'git diff HEAD does not segfault' '
-- 
2.47.0.rc0.dirty


  parent reply	other threads:[~2024-10-07  4:38 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-17  7:13 [PATCH 0/3] cache-tree: fix segfaults with invalid cache-trees Patrick Steinhardt
2024-09-17  7:13 ` [PATCH 1/3] cache-tree: refactor verification to return error codes Patrick Steinhardt
2024-09-17 17:05   ` Eric Sunshine
2024-09-18  5:11     ` Patrick Steinhardt
2024-09-17  7:13 ` [PATCH 2/3] cache-tree: detect mismatching number of index entries Patrick Steinhardt
2024-09-19  1:35   ` Junio C Hamano
2024-09-24  6:48     ` Patrick Steinhardt
2024-09-24 17:01       ` Junio C Hamano
2024-09-17  7:13 ` [PATCH 3/3] unpack-trees: detect mismatching number of cache-tree/index entries Patrick Steinhardt
2024-10-07  4:38 ` [PATCH v2 0/3] cache-tree: fix segfaults with invalid cache-trees Patrick Steinhardt
2024-10-07  4:38   ` [PATCH v2 1/3] cache-tree: refactor verification to return error codes Patrick Steinhardt
2024-10-07  4:38   ` Patrick Steinhardt [this message]
2024-10-07  4:38   ` [PATCH v2 3/3] unpack-trees: detect mismatching number of cache-tree/index entries Patrick Steinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d63087c53c5e57c63fe27a7a7dffa8fdb312f30a.1728275640.git.ps@pks.im \
    --to=ps@pks.im \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=sunshine@sunshineco.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).