cygwin: disallow backslashes in file names

The backslash character is not a valid part of a file name on Windows. If, in Windows, Git attempts to write a file that has a backslash character in the filename, it will be incorrectly interpreted as a directory separator. This caused CVE-2019-1354 in MinGW, as this behaviour can be manipulated to cause the checkout to write to files it ought not write to, such as adding code to the .git/hooks directory. This was fixed by e1d911dd4c (mingw: disallow backslash characters in tree objects' file names, 2019-09-12). However, the vulnerability also exists in Cygwin: while Cygwin mostly provides a POSIX-like path system, it will still interpret a backslash as a directory separator. To avoid this vulnerability, CVE-2021-29468, extend the previous fix to also apply to Cygwin. Similarly, extend the test case added by the previous version of the commit. The test suite doesn't have an easy way to say "run this test if in MinGW or Cygwin", so add a new test prerequisite that covers both. As well as checking behaviour in the presence of paths containing backslashes, the existing test also checks behaviour in the presence of paths that differ only by the presence of a trailing ".". MinGW follows normal Windows application behaviour and treats them as the same path, but Cygwin more closely emulates *nix systems (at the expense of compatibility with native Windows applications) and will create and distinguish between such paths. Gate the relevant bit of that test accordingly. Reported-by: RyotaK <security@ryotak.me> Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Adam Dinwoodie <adam@dinwoodie.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Adam Dinwoodie committed Apr 29, 2021 at 21:11 UTC bccc37fdc7ec66377af454417013f7612aef75e6
3 files changed +11 -6
read-cache.c
+1 -1
@@ -985,7 +985,7 @@ inside:
985 }
986 }
987 if (protect_ntfs) {
988 -#ifdef GIT_WINDOWS_NATIVE
988 +#if defined GIT_WINDOWS_NATIVE || defined __CYGWIN__
989 if (c == '\\')
990 return 0;
991 #endif
t/t7415-submodule-names.sh
+8 -5
@@ -191,7 +191,7 @@ test_expect_success 'fsck detects corrupt .gitmodules' '
191 )
192 '
193
194 -test_expect_success MINGW 'prevent git~1 squatting on Windows' '
194 +test_expect_success WINDOWS 'prevent git~1 squatting on Windows' '
195 git init squatting &&
196 (
197 cd squatting &&
@@ -219,10 +219,13 @@ test_expect_success MINGW 'prevent git~1 squatting on Windows' '
219 test_tick &&
220 git -c core.protectNTFS=false commit -m "module"
221 ) &&
222 - test_must_fail git -c core.protectNTFS=false \
223 - clone --recurse-submodules squatting squatting-clone 2>err &&
224 - test_i18ngrep -e "directory not empty" -e "not an empty directory" err &&
225 - ! grep gitdir squatting-clone/d/a/git~2
222 + if test_have_prereq MINGW
223 + then
224 + test_must_fail git -c core.protectNTFS=false \
225 + clone --recurse-submodules squatting squatting-clone 2>err &&
226 + test_i18ngrep -e "directory not empty" -e "not an empty directory" err &&
227 + ! grep gitdir squatting-clone/d/a/git~2
228 + fi
229 '
230
231 test_expect_success 'git dirs of sibling submodules must not be nested' '
t/test-lib.sh
+2
@@ -1457,6 +1457,7 @@ case $uname_s in
1457 test_set_prereq NATIVE_CRLF
1458 test_set_prereq SED_STRIPS_CR
1459 test_set_prereq GREP_STRIPS_CR
1460 + test_set_prereq WINDOWS
1461 GIT_TEST_CMP=mingw_test_cmp
1462 ;;
1463 *CYGWIN*)
@@ -1465,6 +1466,7 @@ case $uname_s in
1466 test_set_prereq CYGWIN
1467 test_set_prereq SED_STRIPS_CR
1468 test_set_prereq GREP_STRIPS_CR
1469 + test_set_prereq WINDOWS
1470 ;;
1471 *)
1472 test_set_prereq POSIXPERM