Sync with 2.31.7
* maint-2.31: Git 2.31.7 Git 2.30.8 apply: fix writing behind newly created symbolic links dir-iterator: prevent top-level symlinks without FOLLOW_SYMLINKS clone: delay picking a transport until after get_repo_path() t5619: demonstrate clone_local() with ambiguous transport
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -44,4 +44,85 @@ test_expect_success 'apply --index symlink patch' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'symlink setup' '
|
||||
ln -s .git symlink &&
|
||||
git add symlink &&
|
||||
git commit -m "add symlink"
|
||||
'
|
||||
|
||||
test_expect_success SYMLINKS 'symlink escape when creating new files' '
|
||||
test_when_finished "git reset --hard && git clean -dfx" &&
|
||||
|
||||
cat >patch <<-EOF &&
|
||||
diff --git a/symlink b/renamed-symlink
|
||||
similarity index 100%
|
||||
rename from symlink
|
||||
rename to renamed-symlink
|
||||
--
|
||||
diff --git /dev/null b/renamed-symlink/create-me
|
||||
new file mode 100644
|
||||
index 0000000..039727e
|
||||
--- /dev/null
|
||||
+++ b/renamed-symlink/create-me
|
||||
@@ -0,0 +1,1 @@
|
||||
+busted
|
||||
EOF
|
||||
|
||||
test_must_fail git apply patch 2>stderr &&
|
||||
cat >expected_stderr <<-EOF &&
|
||||
error: affected file ${SQ}renamed-symlink/create-me${SQ} is beyond a symbolic link
|
||||
EOF
|
||||
test_cmp expected_stderr stderr &&
|
||||
! test_path_exists .git/create-me
|
||||
'
|
||||
|
||||
test_expect_success SYMLINKS 'symlink escape when modifying file' '
|
||||
test_when_finished "git reset --hard && git clean -dfx" &&
|
||||
touch .git/modify-me &&
|
||||
|
||||
cat >patch <<-EOF &&
|
||||
diff --git a/symlink b/renamed-symlink
|
||||
similarity index 100%
|
||||
rename from symlink
|
||||
rename to renamed-symlink
|
||||
--
|
||||
diff --git a/renamed-symlink/modify-me b/renamed-symlink/modify-me
|
||||
index 1111111..2222222 100644
|
||||
--- a/renamed-symlink/modify-me
|
||||
+++ b/renamed-symlink/modify-me
|
||||
@@ -0,0 +1,1 @@
|
||||
+busted
|
||||
EOF
|
||||
|
||||
test_must_fail git apply patch 2>stderr &&
|
||||
cat >expected_stderr <<-EOF &&
|
||||
error: renamed-symlink/modify-me: No such file or directory
|
||||
EOF
|
||||
test_cmp expected_stderr stderr &&
|
||||
test_must_be_empty .git/modify-me
|
||||
'
|
||||
|
||||
test_expect_success SYMLINKS 'symlink escape when deleting file' '
|
||||
test_when_finished "git reset --hard && git clean -dfx && rm .git/delete-me" &&
|
||||
touch .git/delete-me &&
|
||||
|
||||
cat >patch <<-EOF &&
|
||||
diff --git a/symlink b/renamed-symlink
|
||||
similarity index 100%
|
||||
rename from symlink
|
||||
rename to renamed-symlink
|
||||
--
|
||||
diff --git a/renamed-symlink/delete-me b/renamed-symlink/delete-me
|
||||
deleted file mode 100644
|
||||
index 1111111..0000000 100644
|
||||
EOF
|
||||
|
||||
test_must_fail git apply patch 2>stderr &&
|
||||
cat >expected_stderr <<-EOF &&
|
||||
error: renamed-symlink/delete-me: No such file or directory
|
||||
EOF
|
||||
test_cmp expected_stderr stderr &&
|
||||
test_path_is_file .git/delete-me
|
||||
'
|
||||
|
||||
test_done
|
||||
|
||||
@@ -344,4 +344,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
|
||||
|
||||
70
t/t5619-clone-local-ambiguous-transport.sh
Executable file
70
t/t5619-clone-local-ambiguous-transport.sh
Executable file
@@ -0,0 +1,70 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='test local clone with ambiguous transport'
|
||||
|
||||
. ./test-lib.sh
|
||||
. "$TEST_DIRECTORY/lib-httpd.sh"
|
||||
|
||||
if ! test_have_prereq SYMLINKS
|
||||
then
|
||||
skip_all='skipping test, symlink support unavailable'
|
||||
test_done
|
||||
fi
|
||||
|
||||
start_httpd
|
||||
|
||||
REPO="$HTTPD_DOCUMENT_ROOT_PATH/sub.git"
|
||||
URI="$HTTPD_URL/dumb/sub.git"
|
||||
|
||||
test_expect_success 'setup' '
|
||||
mkdir -p sensitive &&
|
||||
echo "secret" >sensitive/secret &&
|
||||
|
||||
git init --bare "$REPO" &&
|
||||
test_commit_bulk -C "$REPO" --ref=main 1 &&
|
||||
|
||||
git -C "$REPO" update-ref HEAD main &&
|
||||
git -C "$REPO" update-server-info &&
|
||||
|
||||
git init malicious &&
|
||||
(
|
||||
cd malicious &&
|
||||
|
||||
git submodule add "$URI" &&
|
||||
|
||||
mkdir -p repo/refs &&
|
||||
touch repo/refs/.gitkeep &&
|
||||
printf "ref: refs/heads/a" >repo/HEAD &&
|
||||
ln -s "$(cd .. && pwd)/sensitive" repo/objects &&
|
||||
|
||||
mkdir -p "$HTTPD_URL/dumb" &&
|
||||
ln -s "../../../.git/modules/sub/../../../repo/" "$URI" &&
|
||||
|
||||
git add . &&
|
||||
git commit -m "initial commit"
|
||||
) &&
|
||||
|
||||
# Delete all of the references in our malicious submodule to
|
||||
# avoid the client attempting to checkout any objects (which
|
||||
# will be missing, and thus will cause the clone to fail before
|
||||
# we can trigger the exploit).
|
||||
git -C "$REPO" for-each-ref --format="delete %(refname)" >in &&
|
||||
git -C "$REPO" update-ref --stdin <in &&
|
||||
git -C "$REPO" update-server-info
|
||||
'
|
||||
|
||||
test_expect_success 'ambiguous transport does not lead to arbitrary file-inclusion' '
|
||||
git clone malicious clone &&
|
||||
test_must_fail git -C clone submodule update --init 2>err &&
|
||||
|
||||
test_path_is_missing clone/.git/modules/sub/objects/secret &&
|
||||
# We would actually expect "transport .file. not allowed" here,
|
||||
# but due to quirks of the URL detection in Git, we mis-parse
|
||||
# the absolute path as a bogus URL and die before that step.
|
||||
#
|
||||
# This works for now, and if we ever fix the URL detection, it
|
||||
# is OK to change this to detect the transport error.
|
||||
grep "protocol .* is not supported" err
|
||||
'
|
||||
|
||||
test_done
|
||||
Reference in New Issue
Block a user