| From 1256ea63660648bd144e8260bc0effb3cd3ee10c Mon Sep 17 00:00:00 2001 |
| From: Johannes Schindelin <johannes.schindelin@gmx.de> |
| Date: Thu, 12 Sep 2019 14:54:05 +0200 |
| Subject: mingw: disallow backslash characters in tree objects' file names |
| |
| The backslash character is not a valid part of a file name on Windows. |
| Hence it is dangerous to allow writing files that were unpacked from |
| tree objects, when the stored file name contains a backslash character: |
| it will be misinterpreted as directory separator. |
| |
| This not only causes ambiguity when a tree contains a blob `a\b` and a |
| tree `a` that contains a blob `b`, but it also can be used as part of an |
| attack vector to side-step the careful protections against writing into |
| the `.git/` directory during a clone of a maliciously-crafted |
| repository. |
| |
| Let's prevent that, addressing CVE-2019-1354. |
| |
| Note: we guard against backslash characters in tree objects' file names |
| _only_ on Windows (because on other platforms, even on those where NTFS |
| volumes can be mounted, the backslash character is _not_ a directory |
| separator), and _only_ when `core.protectNTFS = true` (because users |
| might need to generate tree objects for other platforms, of course |
| without touching the worktree, e.g. using `git update-index |
| --cacheinfo`). |
| |
| Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> |
| (cherry picked from commit e1d911dd4c7b76a5a8cec0f5c8de15981e34da83) |
| Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> |
| --- |
| t/t1450-fsck.sh | 1 + |
| t/t7415-submodule-names.sh | 8 +++++--- |
| t/t9350-fast-export.sh | 1 + |
| tree-walk.c | 6 ++++++ |
| 4 files changed, 13 insertions(+), 3 deletions(-) |
| |
| diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh |
| index e20e8fa830..c767e2783b 100755 |
| --- a/t/t1450-fsck.sh |
| +++ b/t/t1450-fsck.sh |
| @@ -453,6 +453,7 @@ while read name path pretty; do |
| ( |
| git init $name-$type && |
| cd $name-$type && |
| + git config core.protectNTFS false && |
| echo content >file && |
| git add file && |
| git commit -m base && |
| diff --git a/t/t7415-submodule-names.sh b/t/t7415-submodule-names.sh |
| index c9369b10c7..9b69aed48e 100755 |
| --- a/t/t7415-submodule-names.sh |
| +++ b/t/t7415-submodule-names.sh |
| @@ -207,16 +207,18 @@ test_expect_success MINGW 'prevent git~1 squatting on Windows' ' |
| git hash-object -w --stdin)" && |
| rev="$(git rev-parse --verify HEAD)" && |
| hash="$(echo x | git hash-object -w --stdin)" && |
| - git update-index --add \ |
| + git -c core.protectNTFS=false update-index --add \ |
| --cacheinfo 100644,$modules,.gitmodules \ |
| --cacheinfo 160000,$rev,c \ |
| --cacheinfo 160000,$rev,d\\a \ |
| --cacheinfo 100644,$hash,d./a/x \ |
| --cacheinfo 100644,$hash,d./a/..git && |
| test_tick && |
| - git commit -m "module" |
| + git -c core.protectNTFS=false commit -m "module" && |
| + test_must_fail git show HEAD: 2>err && |
| + test_i18ngrep backslash err |
| ) && |
| - test_must_fail git \ |
| + test_must_fail git -c core.protectNTFS=false \ |
| clone --recurse-submodules squatting squatting-clone 2>err && |
| test_i18ngrep "directory not empty" err && |
| ! grep gitdir squatting-clone/d/a/git~2 |
| diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh |
| index 6a392e87bc..34124be778 100755 |
| --- a/t/t9350-fast-export.sh |
| +++ b/t/t9350-fast-export.sh |
| @@ -418,6 +418,7 @@ test_expect_success 'directory becomes symlink' ' |
| |
| test_expect_success 'fast-export quotes pathnames' ' |
| git init crazy-paths && |
| + test_config -C crazy-paths core.protectNTFS false && |
| (cd crazy-paths && |
| blob=$(echo foo | git hash-object -w --stdin) && |
| git update-index --add \ |
| diff --git a/tree-walk.c b/tree-walk.c |
| index 79bafbd1a2..bf07946ec4 100644 |
| --- a/tree-walk.c |
| +++ b/tree-walk.c |
| @@ -43,6 +43,12 @@ static int decode_tree_entry(struct tree_desc *desc, const char *buf, unsigned l |
| strbuf_addstr(err, _("empty filename in tree entry")); |
| return -1; |
| } |
| +#ifdef GIT_WINDOWS_NATIVE |
| + if (protect_ntfs && strchr(path, '\\')) { |
| + strbuf_addf(err, _("filename in tree entry contains backslash: '%s'"), path); |
| + return -1; |
| + } |
| +#endif |
| len = strlen(path) + 1; |
| |
| /* Initialize the descriptor entry */ |
| -- |
| 2.24.0.393.g34dc348eaf |
| |