git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 2/2] setup: allow Git.pm to do unsafe repo checking

From
Michael McClimon <michael@mcclimon.org>
Date
Oct 22, 2022, 01:19 UTC
Message-ID
<20221022011931.43992-3-michael@mcclimon.org>
In-Reply-To
<20221022011931.43992-1-michael@mcclimon.org>

The previous commit exposes a security flaw: it is possible to bypass unsafe repository checks by using Git.pm, where before the syntax error accidentally prohibited it. This problem occurs because Git.pm sets GIT_DIR explicitly, which bypasses the safe repository checks.

Fix this by introducing a new environment variable, GIT_PERL_FORCE_OWNERSHIP_CHECK, which we set true in Git.pm. In setup.c, if that environment variable is true, force ownership checks even if an explicit GIT_DIR is provided.

Signed-off-by: Michael McClimon <michael@mcclimon.org>
---
 perl/Git.pm         |  1 +
 setup.c             |  3 +++
 t/t9700-perl-git.sh |  4 ++++
 t/t9700/test.pl     | 18 ++++++++++++++++++
 4 files changed, 26 insertions(+)
diff --git a/perl/Git.pm b/perl/Git.pm
index cf15ead6..002c29bb 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -1674,6 +1674,7 @@ sub _cmd_exec {
 sub _setup_git_cmd_env {
 	my $self = shift;
 	if ($self) {
+		$ENV{GIT_PERL_FORCE_OWNERSHIP_CHECK} = 1;
 		$self->repo_path() and $ENV{'GIT_DIR'} = $self->repo_path();
 		$self->repo_path() and $self->wc_path()
 			and $ENV{'GIT_WORK_TREE'} = $self->wc_path();
diff --git a/setup.c b/setup.c
index cefd5f63..33d4e6fd 100644
--- a/setup.c
+++ b/setup.c
@@ -1250,6 +1250,9 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
 	 */
 	gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
 	if (gitdirenv) {
+		if (git_env_bool("GIT_PERL_FORCE_OWNERSHIP_CHECK", 0) &&
+		    !ensure_valid_ownership(NULL, NULL, gitdirenv, report))
+			return GIT_DIR_INVALID_OWNERSHIP;
 		strbuf_addstr(gitdir, gitdirenv);
 		return GIT_DIR_EXPLICIT;
 	}
diff --git a/t/t9700-perl-git.sh b/t/t9700-perl-git.sh
index 4aa5d90d..b14a40b1 100755
--- a/t/t9700-perl-git.sh
+++ b/t/t9700-perl-git.sh
@@ -45,6 +45,10 @@ test_expect_success \
      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
diff --git a/t/t9700/test.pl b/t/t9700/test.pl
index e046f7db..1c91019f 100755
--- a/t/t9700/test.pl
+++ b/t/t9700/test.pl
@@ -142,6 +142,24 @@ sub adjust_dirsep {
 		     "abc\"\\ \x07\x08\x09\x0a\x0b\x0c\x0d\x01 ",
 		     'unquote escape sequences');
 
+# safe directory
+{
+	local $ENV{GIT_TEST_ASSUME_DIFFERENT_OWNER} = 1;
+	# Save stderr to a tempfile so we can check the contents
+	open our $tmpstderr2, ">&STDERR" or die "cannot save STDERR";
+	my $tmperr = "unsafeerr.tmp";
+	open STDERR, ">", "$tmperr" or die "cannot redirect STDERR to $tmperr";
+	my $failed = eval { Git->repository(Directory => "$abs_repo_dir/bare.git") };
+	ok(!$failed, "reject unsafe repository");
+	like($@, qr/not a git repository/i, "unsafe error message");
+	open TEMPFILE, "<", "$tmperr" or die "Can't open $tmperr $!";
+	my $errcontents;
+	{ local $/; $errcontents = <TEMPFILE>; }
+	like($errcontents, qr/dubious ownership/, "dubious ownership message");
+	close STDERR or die "cannot close temp stderr";
+	open STDERR, ">&", $tmpstderr2 or die "cannot restore STDERR";
+}
+
 printf "1..%d\n", Test::More->builder->current_test;
 
 my $is_passing = eval { Test::More->is_passing };
-- 
2.38.1.130.g45c9f05c
Previous: Michael McClimonNext: Junio C Hamano
Message 11 of 23 in “Git.pm: add semicolon after catch statement”
  1. 0/1 Git.pm: add semicolon after catch statementMichael McClimon, Oct 16, 2022
  2. 1/1 Git.pm: add semicolon after catch statementMichael McClimon, Oct 16, 2022
  3. Jeff KingOct 16, 2022
  4. Michael McClimonOct 17, 2022
  5. Jeff KingOct 17, 2022
  6. Michael McClimonOct 18, 2022
  7. Johannes SchindelinNov 10, 2022
  8. Jeff KingNov 10, 2022
  9. 0/2 Fix behavior of Git.pm in unsafe bare repositoriesMichael McClimon, Oct 22, 2022
  10. 1/2 Git.pm: add semicolon after catch statementMichael McClimon, Oct 22, 2022
  11. 2/2 setup: allow Git.pm to do unsafe repo checkingMichael McClimon, Oct 22, 2022
  12. Junio C HamanoOct 22, 2022
  13. Jeff KingOct 22, 2022
  14. Junio C HamanoOct 22, 2022
  15. Ævar Arnfjörð BjarmasonOct 22, 2022
  16. Jeff KingOct 22, 2022
  17. Ævar Arnfjörð BjarmasonOct 24, 2022
  18. Jeff KingOct 24, 2022
  19. Jeff KingOct 22, 2022
  20. Jeff KingOct 22, 2022
  21. Michael McClimonOct 22, 2022
  22. Jeff KingOct 24, 2022
  23. Junio C HamanoOct 22, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.