]> git.ipfire.org Git - thirdparty/git.git/commitdiff
unpack-trees: don't leak memory in verify_clean_subdirectory()
authorÆvar Arnfjörð Bjarmason <avarab@gmail.com>
Thu, 7 Oct 2021 09:46:09 +0000 (11:46 +0200)
committerJunio C Hamano <gitster@pobox.com>
Thu, 7 Oct 2021 22:29:02 +0000 (15:29 -0700)
Fix two different but related memory leaks in
verify_clean_subdirectory(). We leaked both the "pathbuf" if
read_directory() returned non-zero, and we never cleaned up our own
"struct dir_struct" either.

 * "pathbuf": When the read_directory() call followed by the
   free(pathbuf) was added in c81935348be (Fix switching to a branch
   with D/F when current branch has file D., 2007-03-15) we didn't
   bother to free() before we called die().

   But when this code was later libified in 203a2fe1170 (Allow callers
   of unpack_trees() to handle failure, 2008-02-07) we started to leak
   as we returned data to the caller. This fixes that memory leak,
   which can be observed under SANITIZE=leak with e.g. the
   "t1001-read-tree-m-2way.sh" test.

 * "struct dir_struct": We've leaked the dir_struct ever since this
   code was added back in c81935348be.

   When that commit was written there wasn't an equivalent of
   dir_clear(). Since it was added in 270be816049 (dir.c: provide
   clear_directory() for reclaiming dir_struct memory, 2013-01-06)
   we've omitted freeing the memory allocated here.

   This memory leak could also be observed under SANITIZE=leak and the
   "t1001-read-tree-m-2way.sh" test.

This makes all the test in "t1001-read-tree-m-2way.sh" pass under
"GIT_TEST_PASSING_SANITIZE_LEAK=true", we'd previously die in tests
25, 26 & 28.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
t/t1001-read-tree-m-2way.sh
unpack-trees.c

index 1057a96b2498d1a8abf87f21f90d108eee2c2f96..d1115528cb9461495f3ad1e934beb1cd3682f97c 100755 (executable)
@@ -20,6 +20,8 @@ In the test, these paths are used:
        rezrov  - in H, deleted in M
        yomin   - not in H or M
 '
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-read-tree.sh
 
index 8ea0a542da8d9f92efcb30964bc8b14c534f834f..c8d590fa37d078a0993e96d299dddf439c51b1db 100644 (file)
@@ -2136,9 +2136,10 @@ static int verify_clean_subdirectory(const struct cache_entry *ce,
        if (o->dir)
                d.exclude_per_dir = o->dir->exclude_per_dir;
        i = read_directory(&d, o->src_index, pathbuf, namelen+1, NULL);
+       dir_clear(&d);
+       free(pathbuf);
        if (i)
                return add_rejected_path(o, ERROR_NOT_UPTODATE_DIR, ce->name);
-       free(pathbuf);
        return cnt;
 }