summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2019-09-05 11:44:21 (GMT)
committerJohannes Schindelin <johannes.schindelin@gmx.de>2019-12-05 14:37:06 (GMT)
commit817ddd64c20b29b2d86b3a0589f7ff88d1279109 (patch)
tree8aad21a3b28345494fbdfe71aed52d38ad5e29ae
parentd2c84dad1c88f40906799bc879f70b965efd8ba6 (diff)
downloadgit-817ddd64c20b29b2d86b3a0589f7ff88d1279109.zip
git-817ddd64c20b29b2d86b3a0589f7ff88d1279109.tar.gz
git-817ddd64c20b29b2d86b3a0589f7ff88d1279109.tar.bz2
mingw: refuse to access paths with illegal characters
Certain characters are not admissible in file names on Windows, even if Cygwin/MSYS2 (and therefore, Git for Windows' Bash) pretend that they are, e.g. `:`, `<`, `>`, etc Let's disallow those characters explicitly in Windows builds of Git. Note: just like trailing spaces or periods, it _is_ possible on Windows to create commits adding files with such illegal characters, as long as the operation leaves the worktree untouched. To allow for that, we continue to guard `is_valid_win32_path()` behind the config setting `core.protectNTFS`, so that users _can_ continue to do that, as long as they turn the protections off via that config setting. Among other problems, this prevents Git from trying to write to an "NTFS Alternate Data Stream" (which refers to metadata stored alongside a file, under a special name: "<filename>:<stream-name>"). This fix therefore also prevents an attack vector that was exploited in demonstrations of a number of recently-fixed security bugs. Further reading on illegal characters in Win32 filenames: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
-rw-r--r--compat/mingw.c10
-rw-r--r--compat/mingw.h7
-rwxr-xr-xt/t0060-path-utils.sh4
3 files changed, 18 insertions, 3 deletions
diff --git a/compat/mingw.c b/compat/mingw.c
index 17b4da1..3aea269 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -2134,6 +2134,8 @@ int is_valid_win32_path(const char *path)
if (!protect_ntfs)
return 1;
+ skip_dos_drive_prefix((char **)&path);
+
for (;;) {
char c = *(path++);
switch (c) {
@@ -2155,6 +2157,14 @@ int is_valid_win32_path(const char *path)
preceding_space_or_period = 1;
i++;
continue;
+ case ':': /* DOS drive prefix was already skipped */
+ case '<': case '>': case '"': case '|': case '?': case '*':
+ /* illegal character */
+ return 0;
+ default:
+ if (c > '\0' && c < '\x20')
+ /* illegal character */
+ return 0;
}
preceding_space_or_period = 0;
i++;
diff --git a/compat/mingw.h b/compat/mingw.h
index 8c49c1d..7482f19 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -431,8 +431,11 @@ int mingw_offset_1st_component(const char *path);
/**
* Verifies that the given path is a valid one on Windows.
*
- * In particular, path segments are disallowed which end in a period or a
- * space (except the special directories `.` and `..`).
+ * In particular, path segments are disallowed which
+ *
+ * - end in a period or a space (except the special directories `.` and `..`).
+ *
+ * - contain any of the reserved characters, e.g. `:`, `;`, `*`, etc
*
* Returns 1 upon success, otherwise 0.
*/
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 1171e0b..f7e2529 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -445,13 +445,15 @@ test_expect_success MINGW 'is_valid_path() on Windows' '
win32 \
"win32 x" \
../hello.txt \
+ C:\\git \
\
--not \
"win32 " \
"win32 /x " \
"win32." \
"win32 . ." \
- .../hello.txt
+ .../hello.txt \
+ colon:test
'
test_done