Skip to content

Commit bd43ac0

Browse files
committed
Merge branch 'js/adjust-tests-to-explicitly-access-bare-repo' into seen
Some tests assume that bare repository accesses are by default allowed; rewrite some of them to avoid the assumption, rewrite others to explicitly set safe.bareRepository to allow them. * js/adjust-tests-to-explicitly-access-bare-repo: safe.bareRepository: default to "explicit" with WITH_BREAKING_CHANGES status tests: filter `.gitconfig` from status output ls-files tests: filter `.gitconfig` from `--others` output t5601: restore `.gitconfig` after includeIf test t1305: use `--git-dir=.` for bare repo in include cycle test t1300: remove global config settings injected by test-lib.sh t7900: do not let `$HOME/.gitconfig` interfere with XDG tests test-lib: allow bare repository access when breaking changes are enabled
2 parents 684fe22 + ee05756 commit bd43ac0

21 files changed

Lines changed: 127 additions & 13 deletions

Documentation/BreakingChanges.adoc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,30 @@ would be significant, we may decide to defer this change to a subsequent minor
216216
release. This evaluation will also take into account our own experience with
217217
how painful it is to keep Rust an optional component.
218218

219+
* The default value of `safe.bareRepository` will change from `all` to
220+
`explicit`. It is all too easy for an attacker to trick a user into cloning a
221+
repository that contains an embedded bare repository with malicious hooks
222+
configured. If the user enters that subdirectory and runs any Git command, Git
223+
discovers the bare repository and the hooks fire. The user does not even need
224+
to run a Git command explicitly: many shell prompts run `git status` in the
225+
background to display branch and dirty state information, and `git status` in
226+
turn may invoke the fsmonitor hook if so configured, making the user
227+
vulnerable the moment they `cd` into the directory. The `safe.bareRepository`
228+
configuration variable was introduced in 8959555cee (setup_git_directory():
229+
add an owner check for the top-level directory, 2022-03-02) with a default of
230+
`all` to preserve backwards compatibility.
231+
+
232+
Changing the default to `explicit` means that Git will refuse to work with bare
233+
repositories that are discovered implicitly by walking up the directory tree.
234+
Bare repositories specified explicitly via the `--git-dir` command-line option
235+
or the `GIT_DIR` environment variable continue to work regardless of this
236+
setting. Repositories that look like a `.git` directory, a worktree, or a
237+
submodule directory are also unaffected.
238+
+
239+
Users who rely on implicit discovery of bare repositories can restore the
240+
previous behavior by setting `safe.bareRepository=all` in their global or
241+
system configuration.
242+
219243
=== Removals
220244

221245
* Support for grafting commits has long been superseded by git-replace(1).

Documentation/config/safe.adoc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,23 @@ safe.bareRepository::
22
Specifies which bare repositories Git will work with. The currently
33
supported values are:
44
+
5-
* `all`: Git works with all bare repositories. This is the default.
5+
* `all`: Git works with all bare repositories. This is the default in
6+
Git 2.x.
67
* `explicit`: Git only works with bare repositories specified via
78
the top-level `--git-dir` command-line option, or the `GIT_DIR`
8-
environment variable (see linkgit:git[1]).
9+
environment variable (see linkgit:git[1]). This will be the default
10+
in Git 3.0.
911
+
1012
If you do not use bare repositories in your workflow, then it may be
1113
beneficial to set `safe.bareRepository` to `explicit` in your global
1214
config. This will protect you from attacks that involve cloning a
1315
repository that contains a bare repository and running a Git command
1416
within that directory.
1517
+
18+
If you use bare repositories regularly and want to preserve the current
19+
behavior after upgrading to Git 3.0, set `safe.bareRepository` to `all`
20+
in your global or system config.
21+
+
1622
This config setting is only respected in protected configuration (see
1723
<<SCOPES>>). This prevents untrusted repositories from tampering with
1824
this value.

setup.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,7 +1480,11 @@ static int allowed_bare_repo_cb(const char *key, const char *value,
14801480

14811481
static enum allowed_bare_repo get_allowed_bare_repo(void)
14821482
{
1483+
#ifdef WITH_BREAKING_CHANGES
1484+
enum allowed_bare_repo result = ALLOWED_BARE_REPO_EXPLICIT;
1485+
#else
14831486
enum allowed_bare_repo result = ALLOWED_BARE_REPO_ALL;
1487+
#endif
14841488
git_protected_config(allowed_bare_repo_cb, &result);
14851489
return result;
14861490
}

t/t0035-safe-bare-repository.sh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,16 @@ test_expect_success 'setup an embedded bare repo, secondary worktree and submodu
4444
test_path_is_dir outer-repo/.git/modules/subn
4545
'
4646

47-
test_expect_success 'safe.bareRepository unset' '
47+
test_expect_success !WITH_BREAKING_CHANGES 'safe.bareRepository unset' '
4848
test_unconfig --global safe.bareRepository &&
4949
expect_accepted_implicit -C outer-repo/bare-repo
5050
'
5151

52+
test_expect_success WITH_BREAKING_CHANGES 'safe.bareRepository unset (defaults to explicit)' '
53+
test_unconfig --global safe.bareRepository &&
54+
expect_rejected -C outer-repo/bare-repo
55+
'
56+
5257
test_expect_success 'safe.bareRepository=all' '
5358
test_config_global safe.bareRepository all &&
5459
expect_accepted_implicit -C outer-repo/bare-repo
@@ -63,7 +68,8 @@ test_expect_success 'safe.bareRepository in the repository' '
6368
# safe.bareRepository must not be "explicit", otherwise
6469
# git config fails with "fatal: not in a git directory" (like
6570
# safe.directory)
66-
test_config -C outer-repo/bare-repo safe.bareRepository all &&
71+
test_when_finished "git config --file outer-repo/bare-repo/config --unset safe.bareRepository" &&
72+
git config --file outer-repo/bare-repo/config safe.bareRepository all &&
6773
test_config_global safe.bareRepository explicit &&
6874
expect_rejected -C outer-repo/bare-repo
6975
'

t/t1300-config.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
1111
. ./test-lib.sh
1212
. "$TEST_DIRECTORY"/lib-terminal.sh
1313

14+
# test-lib.sh may have added global config (e.g. safe.bareRepository)
15+
# that would appear in "git config --list" output and break tests
16+
# that expect exact config contents.
17+
test_expect_success 'remove global config from test-lib.sh' '
18+
test_might_fail git config --global --unset-all safe.bareRepository
19+
'
20+
1421
for mode in legacy subcommands
1522
do
1623

t/t1305-config-include.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,9 +350,9 @@ test_expect_success 'conditional include, onbranch, implicit /** for /' '
350350

351351
test_expect_success 'include cycles are detected' '
352352
git init --bare cycle &&
353-
git -C cycle config include.path cycle &&
353+
git -C cycle --git-dir=. config include.path cycle &&
354354
git config -f cycle/cycle include.path config &&
355-
test_must_fail git -C cycle config --get-all test.value 2>stderr &&
355+
test_must_fail git -C cycle --git-dir=. config --get-all test.value 2>stderr &&
356356
grep "exceeded maximum include depth" stderr
357357
'
358358

t/t3000-ls-files-others.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,23 +53,27 @@ test_expect_success 'setup: expected output' '
5353

5454
test_expect_success 'ls-files --others' '
5555
git ls-files --others >output &&
56+
test_filter_gitconfig output &&
5657
test_cmp expected1 output
5758
'
5859

5960
test_expect_success 'ls-files --others --directory' '
6061
git ls-files --others --directory >output &&
62+
test_filter_gitconfig output &&
6163
test_cmp expected2 output
6264
'
6365

6466
test_expect_success '--no-empty-directory hides empty directory' '
6567
git ls-files --others --directory --no-empty-directory >output &&
68+
test_filter_gitconfig output &&
6669
test_cmp expected3 output
6770
'
6871

6972
test_expect_success 'ls-files --others handles non-submodule .git' '
7073
mkdir not-a-submodule &&
7174
echo foo >not-a-submodule/.git &&
7275
git ls-files -o >output &&
76+
test_filter_gitconfig output &&
7377
test_cmp expected1 output
7478
'
7579

t/t3001-ls-files-others-exclude.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ test_expect_success 'git ls-files --others with various exclude options.' '
7272
--exclude-per-directory=.gitignore \
7373
--exclude-from=.git/ignore \
7474
>output &&
75+
test_filter_gitconfig output &&
7576
test_cmp expect output
7677
'
7778

@@ -84,6 +85,7 @@ test_expect_success 'git ls-files --others with \r\n line endings.' '
8485
--exclude-per-directory=.gitignore \
8586
--exclude-from=.git/ignore \
8687
>output &&
88+
test_filter_gitconfig output &&
8789
test_cmp expect output
8890
'
8991

@@ -99,6 +101,7 @@ test_expect_success 'git ls-files --others with various exclude options.' '
99101
--exclude-per-directory=.gitignore \
100102
--exclude-from=.git/ignore \
101103
>output &&
104+
test_filter_gitconfig output &&
102105
test_cmp expect output
103106
'
104107

t/t3002-ls-files-dashpath.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ test_expect_success 'setup' '
2424
test_expect_success 'git ls-files without path restriction.' '
2525
test_when_finished "rm -f expect" &&
2626
git ls-files --others >output &&
27+
test_filter_gitconfig output &&
2728
cat >expect <<-\EOF &&
2829
--
2930
-foo
@@ -63,6 +64,7 @@ test_expect_success 'git ls-files with path restriction with -- --.' '
6364
test_expect_success 'git ls-files with no path restriction.' '
6465
test_when_finished "rm -f expect" &&
6566
git ls-files --others -- >output &&
67+
test_filter_gitconfig output &&
6668
cat >expect <<-\EOF &&
6769
--
6870
-foo

t/t3009-ls-files-others-nonsubmodule.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ test_expect_success 'setup: directories' '
3636

3737
test_expect_success 'ls-files --others handles untracked git repositories' '
3838
git ls-files -o >output &&
39+
test_filter_gitconfig output &&
3940
cat >expect <<-EOF &&
4041
nonrepo-untracked-file/untracked
4142
output

0 commit comments

Comments
 (0)