git/t/t9700-perl-git.sh
Jeff King 20da61f25f Git.pm: trust rev-parse to find bare repositories
When initializing a repository object, we run "git rev-parse --git-dir"
to let the C version of Git find the correct directory. But curiously,
if this fails we don't automatically say "not a git repository".
Instead, we do our own pure-perl check to see if we're in a bare
repository.

This makes little sense, as rev-parse will report both bare and non-bare
directories. This logic comes from d5c7721d58 (Git.pm: Add support for
subdirectories inside of working copies, 2006-06-24), but I don't see
any reason given why we can't just rely on rev-parse. Worse, because we
treat any non-error response from rev-parse as a non-bare repository,
we'll erroneously set the object's WorkingCopy, even in a bare
repository.

But it gets worse. Since 8959555cee (setup_git_directory(): add an owner
check for the top-level directory, 2022-03-02), it's actively wrong (and
dangerous). The perl code doesn't implement the same ownership checks.
And worse, after "finding" the bare repository, it sets GIT_DIR in the
environment, which tells any subsequent Git commands that we've
confirmed the directory is OK, and to trust us. I.e., it re-opens the
vulnerability plugged by 8959555cee when using Git.pm's repository
discovery code.

We can fix this by just relying on rev-parse to tell us when we're not
in a repository, which fixes the vulnerability. Furthermore, we'll ask
its --is-bare-repository function to tell us if we're bare or not, and
rely on that.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-10-22 16:39:48 -07:00

58 lines
1.5 KiB
Bash
Executable file

#!/bin/sh
#
# Copyright (c) 2008 Lea Wiemann
#
test_description='perl interface (Git.pm)'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-perl.sh
skip_all_if_no_Test_More
# set up test repository
test_expect_success \
'set up test repository' \
'echo "test file 1" > file1 &&
echo "test file 2" > file2 &&
mkdir directory1 &&
echo "in directory1" >> directory1/file &&
mkdir directory2 &&
echo "in directory2" >> directory2/file &&
git add . &&
git commit -m "first commit" &&
echo "new file in subdir 2" > directory2/file2 &&
git add . &&
git commit -m "commit in directory2" &&
echo "changed file 1" > file1 &&
git commit -a -m "second commit" &&
git config --add color.test.slot1 green &&
git config --add test.string value &&
git config --add test.dupstring value1 &&
git config --add test.dupstring value2 &&
git config --add test.booltrue true &&
git config --add test.boolfalse no &&
git config --add test.boolother other &&
git config --add test.int 2k &&
git config --add test.path "~/foo" &&
git config --add test.pathexpanded "$HOME/foo" &&
git config --add test.pathmulti foo &&
git config --add test.pathmulti bar
'
test_expect_success 'set up bare repository' '
git init --bare bare.git
'
test_expect_success 'use t9700/test.pl to test Git.pm' '
"$PERL_PATH" "$TEST_DIRECTORY"/t9700/test.pl 2>stderr &&
test_must_be_empty stderr
'
test_done