summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
authorTaylor Blau <me@ttaylorr.com>2023-01-24 19:43:51 -0500
committerJunio C Hamano <gitster@pobox.com>2023-01-24 16:52:16 -0800
commitbffc762f87ae8d18c6001bf0044a76004245754c (patch)
tree94ef671b634c0516c9643aa5e685ca31c0793453 /t
parentcf8f6ce02a13f4d1979a53241afbee15a293fce9 (diff)
downloadgit-bffc762f87ae8d18c6001bf0044a76004245754c.tar.gz
dir-iterator: prevent top-level symlinks without FOLLOW_SYMLINKS
When using the dir_iterator API, we first stat(2) the base path, and then use that as a starting point to enumerate the directory's contents. If the directory contains symbolic links, we will immediately die() upon encountering them without the `FOLLOW_SYMLINKS` flag. The same is not true when resolving the top-level directory, though. As explained in a previous commit, this oversight in 6f054f9fb3 (builtin/clone.c: disallow `--local` clones with symlinks, 2022-07-28) can be used as an attack vector to include arbitrary files on a victim's filesystem from outside of the repository. Prevent resolving top-level symlinks unless the FOLLOW_SYMLINKS flag is given, which will cause clones of a repository with a symlink'd "$GIT_DIR/objects" directory to fail. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 't')
-rwxr-xr-xt/t0066-dir-iterator.sh27
-rwxr-xr-xt/t5604-clone-reference.sh16
2 files changed, 42 insertions, 1 deletions
diff --git a/t/t0066-dir-iterator.sh b/t/t0066-dir-iterator.sh
index 92910e4e6c..c826f60f6d 100755
--- a/t/t0066-dir-iterator.sh
+++ b/t/t0066-dir-iterator.sh
@@ -109,7 +109,9 @@ test_expect_success SYMLINKS 'setup dirs with symlinks' '
mkdir -p dir5/a/c &&
ln -s ../c dir5/a/b/d &&
ln -s ../ dir5/a/b/e &&
- ln -s ../../ dir5/a/b/f
+ ln -s ../../ dir5/a/b/f &&
+
+ ln -s dir4 dir6
'
test_expect_success SYMLINKS 'dir-iterator should not follow symlinks by default' '
@@ -145,4 +147,27 @@ test_expect_success SYMLINKS 'dir-iterator should follow symlinks w/ follow flag
test_cmp expected-follow-sorted-output actual-follow-sorted-output
'
+test_expect_success SYMLINKS 'dir-iterator does not resolve top-level symlinks' '
+ test_must_fail test-tool dir-iterator ./dir6 >out &&
+
+ grep "ENOTDIR" out
+'
+
+test_expect_success SYMLINKS 'dir-iterator resolves top-level symlinks w/ follow flag' '
+ cat >expected-follow-sorted-output <<-EOF &&
+ [d] (a) [a] ./dir6/a
+ [d] (a/f) [f] ./dir6/a/f
+ [d] (a/f/c) [c] ./dir6/a/f/c
+ [d] (b) [b] ./dir6/b
+ [d] (b/c) [c] ./dir6/b/c
+ [f] (a/d) [d] ./dir6/a/d
+ [f] (a/e) [e] ./dir6/a/e
+ EOF
+
+ test-tool dir-iterator --follow-symlinks ./dir6 >out &&
+ sort out >actual-follow-sorted-output &&
+
+ test_cmp expected-follow-sorted-output actual-follow-sorted-output
+'
+
test_done
diff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh
index 9d32f1c4a4..4ff21d7ccf 100755
--- a/t/t5604-clone-reference.sh
+++ b/t/t5604-clone-reference.sh
@@ -341,4 +341,20 @@ test_expect_success SYMLINKS 'clone repo with symlinked or unknown files at obje
test_must_be_empty T--shared.objects-symlinks.raw
'
+test_expect_success SYMLINKS 'clone repo with symlinked objects directory' '
+ test_when_finished "rm -fr sensitive malicious" &&
+
+ mkdir -p sensitive &&
+ echo "secret" >sensitive/file &&
+
+ git init malicious &&
+ rm -fr malicious/.git/objects &&
+ ln -s "$(pwd)/sensitive" ./malicious/.git/objects &&
+
+ test_must_fail git clone --local malicious clone 2>err &&
+
+ test_path_is_missing clone &&
+ grep "failed to start iterator over" err
+'
+
test_done