diff --git a/SOURCES/git-cve-2018-17456-tests.patch b/SOURCES/git-cve-2018-17456-tests.patch new file mode 100644 index 0000000..e365cf2 --- /dev/null +++ b/SOURCES/git-cve-2018-17456-tests.patch @@ -0,0 +1,164 @@ +From 90243e8192574f43bb84be01528504ec230d7fd3 Mon Sep 17 00:00:00 2001 +From: Pavel Cahyna +Date: Fri, 19 Oct 2018 10:55:43 +0200 +Subject: [PATCH 2/2] submodule-config: ban submodule urls that start with dash + - tests + +Our tests cover two cases: + + 1. A file url with "./" continues to work, showing that + there's an escape hatch for people with truly silly + repo names. + + 2. A url starting with "-" is rejected. + +Note that we expect case (2) to fail, but it would have done +so even without this commit, for the reasons given above. +So instead of just expecting failure, let's also check for +the magic word "ignoring" on stderr. That lets us know that +we failed for the right reason. + +[pc: backported to 1.8.3.1 by avoiding -C in tests] + +submodule-config: ban submodule paths that start with a dash - test + +There are two minor differences to the tests in t7416 (that +covered urls): + + 1. We don't have a "./-sub" escape hatch to make this + work, since the submodule code expects to be able to + match canonical index names to the path field (so you + are free to add submodule config with that path, but we + would never actually use it, since an index entry would + never start with "./"). + + 2. After this patch, cloning actually succeeds. Since we + ignore the submodule.*.path value, we fail to find a + config stanza for our submodule at all, and simply + treat it as inactive. We still check for the "ignoring" + message. + +[jn: + - the original patch expects 'git clone' to succeed in + the test because v2.13.0-rc0~10^2~3 (clone: teach + --recurse-submodules to optionally take a pathspec, + 2017-03-17) makes 'git clone' skip invalid submodules. + Updated the test to pass in older Git versions where the + submodule name check makes 'git clone' fail.] + +[pc: + - avoid -C in tests + - reimplement git mv of a submodule, git mv gained that functionality later.] + +fsck: detect submodule urls starting with dash - tests + +[pc: backported to 1.8.3.1 by avoiding -C in tests ] + +fsck: detect submodule paths starting with dash - test + +commit 1a7fd1fb2998002da6e9ff2ee46e1bdd25ee8404 upstream. + +[pc: backported to 1.8.3.1 by avoiding -C in tests ] +--- + t/t7416-submodule-dash-url.sh | 49 +++++++++++++++++++++++++++++++++++++++++++ + t/t7417-submodule-path-url.sh | 32 ++++++++++++++++++++++++++++ + 2 files changed, 81 insertions(+) + create mode 100755 t/t7416-submodule-dash-url.sh + create mode 100755 t/t7417-submodule-path-url.sh + +diff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh +new file mode 100755 +index 000000000..e85f2e9d2 +--- /dev/null ++++ b/t/t7416-submodule-dash-url.sh +@@ -0,0 +1,49 @@ ++#!/bin/sh ++ ++test_description='check handling of .gitmodule url with dash' ++. ./test-lib.sh ++ ++test_expect_success 'create submodule with protected dash in url' ' ++ git init upstream && ++ ( cd upstream && git commit --allow-empty -m base ) && ++ mv upstream ./-upstream && ++ git submodule add ./-upstream sub && ++ git add sub .gitmodules && ++ git commit -m submodule ++' ++ ++test_expect_success 'clone can recurse submodule' ' ++ test_when_finished "rm -rf dst" && ++ git clone --recurse-submodules . dst && ++ echo base >expect && ++ ( cd dst/sub && git log -1 --format=%s ) >actual && ++ test_cmp expect actual ++' ++ ++test_expect_success 'fsck accepts protected dash' ' ++ test_when_finished "rm -rf dst" && ++ git init --bare dst && ++ ( cd dst && git config transfer.fsckObjects true ) && ++ git push dst HEAD ++' ++ ++test_expect_success 'remove ./ protection from .gitmodules url' ' ++ perl -i -pe "s{\./}{}" .gitmodules && ++ git commit -am "drop protection" ++' ++ ++test_expect_success 'clone rejects unprotected dash' ' ++ test_when_finished "rm -rf dst" && ++ test_must_fail git clone --recurse-submodules . dst 2>err && ++ test_i18ngrep "may be interpreted as a command-line option" err ++' ++ ++test_expect_success 'fsck rejects unprotected dash' ' ++ test_when_finished "rm -rf dst" && ++ git init --bare dst && ++ ( cd dst && git config transfer.fsckObjects true ) && ++ test_must_fail git push dst HEAD 2>err && ++ test_i18ngrep "disallowed submodule url" err ++' ++ ++test_done +diff --git a/t/t7417-submodule-path-url.sh b/t/t7417-submodule-path-url.sh +new file mode 100755 +index 000000000..141b42a11 +--- /dev/null ++++ b/t/t7417-submodule-path-url.sh +@@ -0,0 +1,32 @@ ++#!/bin/sh ++ ++test_description='check handling of .gitmodule path with dash' ++. ./test-lib.sh ++ ++test_expect_success 'create submodule with dash in path' ' ++ git init upstream && ++ ( cd upstream && git commit --allow-empty -m base ) && ++ git submodule add ./upstream sub && ++ mv -- sub -sub && ++ git rm --cached sub && ++ sed -i -e "/=.*sub$/s/sub/-sub/" .git/modules/sub/config && ++ sed -i -e "/=.*sub$/s/sub/-sub/" .gitmodules && ++ git add -- -sub .git/modules/sub/config .gitmodules && ++ git commit -m submodule ++' ++ ++test_expect_success 'clone rejects unprotected dash' ' ++ test_when_finished "rm -rf dst" && ++ test_might_fail git clone --recurse-submodules . dst 2>err && ++ test_i18ngrep "may be interpreted as a command-line option" err ++' ++ ++test_expect_success 'fsck rejects unprotected dash' ' ++ test_when_finished "rm -rf dst" && ++ git init --bare dst && ++ ( cd dst && git config transfer.fsckObjects true ) && ++ test_must_fail git push dst HEAD 2>err && ++ test_i18ngrep "disallowed submodule path" err ++' ++ ++test_done +-- +2.14.4 + diff --git a/SOURCES/git-cve-2018-17456.patch b/SOURCES/git-cve-2018-17456.patch new file mode 100644 index 0000000..0f595bb --- /dev/null +++ b/SOURCES/git-cve-2018-17456.patch @@ -0,0 +1,254 @@ +From d819a25360ba38dfec31e37413963adf5688db80 Mon Sep 17 00:00:00 2001 +From: Jeff King +Date: Mon, 24 Sep 2018 04:32:15 -0400 +Subject: [PATCH 1/2] submodule--helper: use "--" to signal end of clone + options + +commit 98afac7a7cefdca0d2c4917dd8066a59f7088265 upstream. + +When we clone a submodule, we call "git clone $url $path". +But there's nothing to say that those components can't begin +with a dash themselves, confusing git-clone into thinking +they're options. Let's pass "--" to make it clear what we +expect. + +There's no test here, because it's actually quite hard to +make these names work, even with "git clone" parsing them +correctly. And we're going to restrict these cases even +further in future commits. So we'll leave off testing until +then; this is just the minimal fix to prevent us from doing +something stupid with a badly formed entry. + +[jn: backported to 2.1.y by applying to git-submodule.sh + instead of submodule--helper] + +Reported-by: joernchen +Signed-off-by: Jeff King +Signed-off-by: Junio C Hamano +Signed-off-by: Jonathan Nieder + +submodule-config: ban submodule urls that start with dash + +commit f6adec4e329ef0e25e14c63b735a5956dc67b8bc upstream. + +The previous commit taught the submodule code to invoke our +"git clone $url $path" with a "--" separator so that we +aren't confused by urls or paths that start with dashes. + +However, that's just one code path. It's not clear if there +are others, and it would be an easy mistake to add one in +the future. Moreover, even with the fix in the previous +commit, it's quite hard to actually do anything useful with +such an entry. Any url starting with a dash must fall into +one of three categories: + + - it's meant as a file url, like "-path". But then any + clone is not going to have the matching path, since it's + by definition relative inside the newly created clone. If + you spell it as "./-path", the submodule code sees the + "/" and translates this to an absolute path, so it at + least works (assuming the receiver has the same + filesystem layout as you). But that trick does not apply + for a bare "-path". + + - it's meant as an ssh url, like "-host:path". But this + already doesn't work, as we explicitly disallow ssh + hostnames that begin with a dash (to avoid option + injection against ssh). + + - it's a remote-helper scheme, like "-scheme::data". This + _could_ work if the receiver bends over backwards and + creates a funny-named helper like "git-remote--scheme". + But normally there would not be any helper that matches. + +Since such a url does not work today and is not likely to do +anything useful in the future, let's simply disallow them +entirely. That protects the existing "git clone" path (in a +belt-and-suspenders way), along with any others that might +exist. + +[jn: backported to 2.1.y by porting to shell] +[pc: backported to 1.8.3.1 by using $sm_path instead of $displayname + and split tests into a separate commit] + +Signed-off-by: Jeff King +Signed-off-by: Junio C Hamano +Signed-off-by: Jonathan Nieder + +submodule-config: ban submodule paths that start with a dash + +commit 273c61496f88c6495b886acb1041fe57965151da upstream. + +We recently banned submodule urls that look like +command-line options. This is the matching change to ban +leading-dash paths. + +As with the urls, this should not break any use cases that +currently work. Even with our "--" separator passed to +git-clone, git-submodule.sh gets confused. Without the code +portion of this patch, the clone of "-sub" added in t7417 +would yield results like: + + /path/to/git-submodule: 410: cd: Illegal option -s + /path/to/git-submodule: 417: cd: Illegal option -s + /path/to/git-submodule: 410: cd: Illegal option -s + /path/to/git-submodule: 417: cd: Illegal option -s + Fetched in submodule path '-sub', but it did not contain b56243f8f4eb91b2f1f8109452e659f14dd3fbe4. D +irect fetching of that commit failed. + +Moreover, naively adding such a submodule doesn't work: + + $ git submodule add $url -sub + The following path is ignored by one of your .gitignore files: + -sub + +even though there is no such ignore pattern (the test script +hacks around this with a well-placed "git mv"). + +Unlike leading-dash urls, though, it's possible that such a +path _could_ be useful if we eventually made it work. So +this commit should be seen not as recommending a particular +policy, but rather temporarily closing off a broken and +possibly dangerous code-path. We may revisit this decision +later. + +[jn: ported to git-submodule.sh + pc: split the test into a separate commit ] + +fsck: detect submodule urls starting with dash + +commit a124133e1e6ab5c7a9fef6d0e6bcb084e3455b46 upstream. + +Urls with leading dashes can cause mischief on older +versions of Git. We should detect them so that they can be +rejected by receive.fsckObjects, preventing modern versions +of git from being a vector by which attacks can spread. + +[jn: backported to 2.1.y: using error_func instead of report + to report fsck errors] + +[pc: split tests into a separate commit] + +Signed-off-by: Jeff King +Signed-off-by: Junio C Hamano +Signed-off-by: Jonathan Nieder + +fsck: detect submodule paths starting with dash + +commit 1a7fd1fb2998002da6e9ff2ee46e1bdd25ee8404 upstream. + +As with urls, submodule paths with dashes are ignored by +git, but may end up confusing older versions. Detecting them +via fsck lets us prevent modern versions of git from being a +vector to spread broken .gitmodules to older versions. + +Compared to blocking leading-dash urls, though, this +detection may be less of a good idea: + + 1. While such paths provide confusing and broken results, + they don't seem to actually work as option injections + against anything except "cd". In particular, the + submodule code seems to canonicalize to an absolute + path before running "git clone" (so it passes + /your/clone/-sub). + + 2. It's more likely that we may one day make such names + actually work correctly. Even after we revert this fsck + check, it will continue to be a hassle until hosting + servers are all updated. + +On the other hand, it's not entirely clear that the behavior +in older versions is safe. And if we do want to eventually +allow this, we may end up doing so with a special syntax +anyway (e.g., writing "./-sub" in the .gitmodules file, and +teaching the submodule code to canonicalize it when +comparing). + +So on balance, this is probably a good protection. + +[jn: backported to 2.1.y: using error_func instead of report + to report fsck errors] + +[pc: split test to a separate commit] +--- + fsck.c | 10 ++++++++++ + git-submodule.sh | 20 +++++++++++++++----- + 2 files changed, 25 insertions(+), 5 deletions(-) + +diff --git a/fsck.c b/fsck.c +index 811724125..90d641066 100644 +--- a/fsck.c ++++ b/fsck.c +@@ -442,6 +442,16 @@ static int fsck_gitmodules_fn(const char *var, const char *value, void *vdata) + data->ret += data->error_func(data->obj, FSCK_ERROR, + "disallowed submodule name: %s", + name); ++ if (!strcmp(key, "url") && value && ++ looks_like_command_line_option(value)) ++ data->ret += data->error_func(data->obj, FSCK_ERROR, ++ "disallowed submodule url: %s", ++ value); ++ if (!strcmp(key, "path") && value && ++ looks_like_command_line_option(value)) ++ data->ret += data->error_func(data->obj, FSCK_ERROR, ++ "disallowed submodule path: %s", ++ value); + free(name); + + return 0; +diff --git a/git-submodule.sh b/git-submodule.sh +index e958ce840..b5176ecc3 100755 +--- a/git-submodule.sh ++++ b/git-submodule.sh +@@ -205,6 +205,11 @@ module_name() + re=$(printf '%s\n' "$1" | sed -e 's/[].[^$\\*]/\\&/g') + name=$( git config -f .gitmodules --get-regexp '^submodule\..*\.path$' | + sed -n -e 's|^submodule\.\(.*\)\.path '"$re"'$|\1|p' ) ++ case "$sm_path" in ++ -*) ++ die "$(eval_gettext "Submodule path '\$sm_path' may be interpreted as a command-line option")" ++ ;; ++ esac + test -z "$name" && + die "$(eval_gettext "No submodule mapping found in .gitmodules for path '\$sm_path'")" + check_module_name "$name" +@@ -248,7 +253,7 @@ module_clone() + ( + clear_local_git_env + git clone $quiet -n ${reference:+"$reference"} \ +- --separate-git-dir "$gitdir" "$url" "$sm_path" ++ --separate-git-dir "$gitdir" -- "$url" "$sm_path" + ) || + die "$(eval_gettext "Clone of '\$url' into submodule path '\$sm_path' failed")" + fi +@@ -547,11 +552,13 @@ cmd_init() + if test -z "$(git config "submodule.$name.url")" + then + url=$(git config -f .gitmodules submodule."$name".url) +- test -z "$url" && +- die "$(eval_gettext "No url found for submodule path '\$sm_path' in .gitmodules")" +- +- # Possibly a url relative to parent + case "$url" in ++ "") ++ die "$(eval_gettext "No url found for submodule path '\$sm_path' in .gitmodules")" ++ ;; ++ -*) ++ die "$(eval_gettext "Submodule at path '\$sm_path' has url '\$url' which may be interpreted as a command-line option")" ++ ;; + ./*|../*) + url=$(resolve_relative_url "$url") || exit + ;; +@@ -1213,6 +1220,9 @@ cmd_sync() + + # Possibly a url relative to parent + case "$url" in ++ -*) ++ die "$(eval_gettext "Submodule at path '\$sm_path' has url '\$url' which may be interpreted as a command-line option")" ++ ;; + ./*|../*) + # rewrite foo/bar as ../.. to find path from + # submodule work tree to superproject work tree +-- +2.14.4 + diff --git a/SPECS/git.spec b/SPECS/git.spec index 9dd375c..426e3e7 100644 --- a/SPECS/git.spec +++ b/SPECS/git.spec @@ -25,7 +25,7 @@ Name: git Version: 1.8.3.1 -Release: 19%{?dist} +Release: 20%{?dist} Summary: Fast Version Control System License: GPLv2 Group: Development/Tools @@ -65,6 +65,8 @@ Patch15: 0008-Fix-CVE-2017-8386.patch Patch16: git-cve-2017-1000117.patch Patch19: git-cve-2018-11235.patch Patch20: 0001-Switch-git-instaweb-default-to-apache.patch +Patch21: git-cve-2018-17456.patch +Patch22: git-cve-2018-17456-tests.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -317,8 +319,10 @@ Requires: gnome-keyring %patch18 -p1 %patch19 -p1 %patch20 -p1 +%patch21 -p1 +%patch22 -p1 -chmod a+x t/t0011-hashmap.sh t/t1307-config-blob.sh t/t4139-apply-escape.sh t/t7415-submodule-names.sh +chmod a+x t/t0011-hashmap.sh t/t1307-config-blob.sh t/t4139-apply-escape.sh t/t7415-submodule-names.sh t/t7416-submodule-dash-url.sh t/t7417-submodule-path-url.sh # Use these same options for every invocation of 'make'. # Otherwise it will rebuild in %%install due to flags changes. @@ -633,6 +637,11 @@ rm -rf %{buildroot} # No files for you! %changelog +* Fri Oct 19 2018 Pavel Cahyna - 1.8.3.1-20 +- Fix CVE-2018-17456: arbitrary code execution via .gitmodules + Thanks to Jonathan Nieder for backporting to 2.1.x + and to Steve Beattie for backporting to 1.9.1 + * Wed Aug 29 2018 Sebastian Kisela - 1.8.3.1-19 - Fix httpd modules path to be independent from system architecture. Upstream commit: 1976311aa285549599e5a451d7ad72b55a2b60e2