[PATCH 1/2] object-file: fix SEGV on free() regression in v2.34.0-rc2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Fix a regression introduced in my 96e41f58fe1 (fsck: report invalid
object type-path combinations, 2021-10-01). When fsck-ing blobs larger
than core.bigFileThreshold we'd free() a pointer to uninitialized
memory.

This issue would have been caught by SANITIZE=address, but since it
involves core.bigFileThreshold none of the existing tests in our test
suite covered it.

Running them with the "big_file_threshold" in "environment.c" changed
to say "6" would have shown this failure, but let's add a dedicated
test for this scenario based on Han Xin's report[1].

It would be a good follow-up change to add a GIT_TEST_* mode to run
all the tests with a low core.bigFileThreshold threshold.

Currently a lot of them fail (but none due to SANITIZE=address)
because they make implicit assumptions about the current hardcoded
setting of core.bigFileThreshold.

Around half the failures are due to us assuming that files larger than
that are binary, see 6bf3b813486 (diff --stat: mark any file larger
than core.bigfilethreshold binary, 2014-08-16) and the comment added
in 12426e114b2 (diff: do not short-cut CHECK_SIZE_ONLY check in
diff_populate_filespec(), 2017-03-01). The rest seem to all be
pack/loose-related, i.e. they're assuming that something ends up as a
loose object or in a pack.

The bug was introduced between v9 and v10[2] of the fsck series merged
in 061a21d36d8 (Merge branch 'ab/fsck-unexpected-type', 2021-10-25).

1. https://lore.kernel.org/git/20211111030302.75694-1-hanxin.hx@xxxxxxxxxxxxxxx/
2. https://lore.kernel.org/git/cover-v10-00.17-00000000000-20211001T091051Z-avarab@xxxxxxxxx/

Reported-by: Han Xin <chiyutianyi@xxxxxxxxx>
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx>
---
 object-file.c    | 2 ++
 t/t1050-large.sh | 8 ++++++++
 2 files changed, 10 insertions(+)

diff --git a/object-file.c b/object-file.c
index 02b79702748..ac476653a06 100644
--- a/object-file.c
+++ b/object-file.c
@@ -2528,6 +2528,8 @@ int read_loose_object(const char *path,
 	char hdr[MAX_HEADER_LEN];
 	unsigned long *size = oi->sizep;
 
+	*contents = NULL;
+
 	map = map_loose_object_1(the_repository, path, NULL, &mapsize);
 	if (!map) {
 		error_errno(_("unable to mmap %s"), path);
diff --git a/t/t1050-large.sh b/t/t1050-large.sh
index 4bab6a513c5..6bc1d76fb10 100755
--- a/t/t1050-large.sh
+++ b/t/t1050-large.sh
@@ -17,6 +17,14 @@ test_expect_success setup '
 	export GIT_ALLOC_LIMIT
 '
 
+test_expect_success 'enter "large" codepath, with small core.bigFileThreshold' '
+	test_when_finished "rm -rf repo" &&
+
+	git init --bare repo &&
+	echo large | git -C repo hash-object -w --stdin &&
+	git -C repo -c core.bigfilethreshold=4 fsck
+'
+
 # add a large file with different settings
 while read expect config
 do
-- 
2.34.0.rc2.795.g926201d1cc8




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux