diff options
Diffstat (limited to 'meta/recipes-devtools/git/git/CVE-2020-11008-7.patch')
-rw-r--r-- | meta/recipes-devtools/git/git/CVE-2020-11008-7.patch | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/meta/recipes-devtools/git/git/CVE-2020-11008-7.patch b/meta/recipes-devtools/git/git/CVE-2020-11008-7.patch new file mode 100644 index 0000000000..5e3b6f1454 --- /dev/null +++ b/meta/recipes-devtools/git/git/CVE-2020-11008-7.patch @@ -0,0 +1,206 @@ +From 68acf8724e9cb2f67664dd980581c0022401daf0 Mon Sep 17 00:00:00 2001 +From: Jonathan Nieder <jrnieder@gmail.com> +Date: Sat, 18 Apr 2020 20:54:13 -0700 +Subject: [PATCH 10/12] credential: treat URL without scheme as invalid + +libcurl permits making requests without a URL scheme specified. In +this case, it guesses the URL from the hostname, so I can run + + git ls-remote http::ftp.example.com/path/to/repo + +and it would make an FTP request. + +Any user intentionally using such a URL is likely to have made a typo. +Unfortunately, credential_from_url is not able to determine the host and +protocol in order to determine appropriate credentials to send, and +until "credential: refuse to operate when missing host or protocol", +this resulted in another host's credentials being leaked to the named +host. + +Teach credential_from_url_gently to consider such a URL to be invalid +so that fsck can detect and block gitmodules files with such URLs, +allowing server operators to avoid serving them to downstream users +running older versions of Git. + +This also means that when such URLs are passed on the command line, Git +will print a clearer error so affected users can switch to the simpler +URL that explicitly specifies the host and protocol they intend. + +One subtlety: .gitmodules files can contain relative URLs, representing +a URL relative to the URL they were cloned from. The relative URL +resolver used for .gitmodules can follow ".." components out of the path +part and past the host part of a URL, meaning that such a relative URL +can be used to traverse from a https://foo.example.com/innocent +superproject to a https::attacker.example.com/exploit submodule. +Fortunately a leading ':' in the first path component after a series of +leading './' and '../' components is unlikely to show up in other +contexts, so we can catch this by detecting that pattern. + +Reported-by: Jeff King <peff@peff.net> +Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> +Reviewed-by: Jeff King <peff@peff.net> + +Upstream-Status: Backport +CVE: CVE-2020-11008 (7) +Signed-off-by: Li Zhou <li.zhou@windriver.com> +--- + credential.c | 7 +++++-- + fsck.c | 47 +++++++++++++++++++++++++++++++++++++++++-- + t/t5550-http-fetch-dumb.sh | 7 ++----- + t/t7416-submodule-dash-url.sh | 32 +++++++++++++++++++++++++++++ + 4 files changed, 84 insertions(+), 9 deletions(-) + +diff --git a/credential.c b/credential.c +index 22649d5..1e1aed5 100644 +--- a/credential.c ++++ b/credential.c +@@ -360,8 +360,11 @@ int credential_from_url_gently(struct credential *c, const char *url, + * (3) proto://<user>:<pass>@<host>/... + */ + proto_end = strstr(url, "://"); +- if (!proto_end) +- return 0; ++ if (!proto_end) { ++ if (!quiet) ++ warning(_("url has no scheme: %s"), url); ++ return -1; ++ } + cp = proto_end + 3; + at = strchr(cp, '@'); + colon = strchr(cp, ':'); +diff --git a/fsck.c b/fsck.c +index 0f21eb1..30eac29 100644 +--- a/fsck.c ++++ b/fsck.c +@@ -978,6 +978,34 @@ static int submodule_url_is_relative(const char *url) + } + + /* ++ * Count directory components that a relative submodule URL should chop ++ * from the remote_url it is to be resolved against. ++ * ++ * In other words, this counts "../" components at the start of a ++ * submodule URL. ++ * ++ * Returns the number of directory components to chop and writes a ++ * pointer to the next character of url after all leading "./" and ++ * "../" components to out. ++ */ ++static int count_leading_dotdots(const char *url, const char **out) ++{ ++ int result = 0; ++ while (1) { ++ if (starts_with_dot_dot_slash(url)) { ++ result++; ++ url += strlen("../"); ++ continue; ++ } ++ if (starts_with_dot_slash(url)) { ++ url += strlen("./"); ++ continue; ++ } ++ *out = url; ++ return result; ++ } ++} ++/* + * Check whether a transport is implemented by git-remote-curl. + * + * If it is, returns 1 and writes the URL that would be passed to +@@ -1024,15 +1052,30 @@ static int check_submodule_url(const char *url) + return -1; + + if (submodule_url_is_relative(url)) { ++ char *decoded; ++ const char *next; ++ int has_nl; ++ + /* + * This could be appended to an http URL and url-decoded; + * check for malicious characters. + */ +- char *decoded = url_decode(url); +- int has_nl = !!strchr(decoded, '\n'); ++ decoded = url_decode(url); ++ has_nl = !!strchr(decoded, '\n'); ++ + free(decoded); + if (has_nl) + return -1; ++ ++ /* ++ * URLs which escape their root via "../" can overwrite ++ * the host field and previous components, resolving to ++ * URLs like https::example.com/submodule.git that were ++ * susceptible to CVE-2020-11008. ++ */ ++ if (count_leading_dotdots(url, &next) > 0 && ++ *next == ':') ++ return -1; + } + + else if (url_to_curl_url(url, &curl_url)) { +diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh +index b811d89..1c9e5d3 100755 +--- a/t/t5550-http-fetch-dumb.sh ++++ b/t/t5550-http-fetch-dumb.sh +@@ -321,11 +321,8 @@ test_expect_success 'git client does not send an empty Accept-Language' ' + ' + + test_expect_success 'remote-http complains cleanly about malformed urls' ' +- # do not actually issue "list" or other commands, as we do not +- # want to rely on what curl would actually do with such a broken +- # URL. This is just about making sure we do not segfault during +- # initialization. +- test_must_fail git remote-http http::/example.com/repo.git ++ test_must_fail git remote-http http::/example.com/repo.git 2>stderr && ++ test_i18ngrep "url has no scheme" stderr + ' + + test_expect_success 'redirects can be forbidden/allowed' ' +diff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh +index afdd255..249dc3d 100755 +--- a/t/t7416-submodule-dash-url.sh ++++ b/t/t7416-submodule-dash-url.sh +@@ -60,6 +60,38 @@ test_expect_success 'trailing backslash is handled correctly' ' + test_i18ngrep ! "unknown option" err + ' + ++test_expect_success 'fsck rejects missing URL scheme' ' ++ git checkout --orphan missing-scheme && ++ cat >.gitmodules <<-\EOF && ++ [submodule "foo"] ++ url = http::one.example.com/foo.git ++ EOF ++ git add .gitmodules && ++ test_tick && ++ git commit -m "gitmodules with missing URL scheme" && ++ test_when_finished "rm -rf dst" && ++ git init --bare dst && ++ git -C dst config transfer.fsckObjects true && ++ test_must_fail git push dst HEAD 2>err && ++ grep gitmodulesUrl err ++' ++ ++test_expect_success 'fsck rejects relative URL resolving to missing scheme' ' ++ git checkout --orphan relative-missing-scheme && ++ cat >.gitmodules <<-\EOF && ++ [submodule "foo"] ++ url = "..\\../.\\../:one.example.com/foo.git" ++ EOF ++ git add .gitmodules && ++ test_tick && ++ git commit -m "gitmodules with relative URL that strips off scheme" && ++ test_when_finished "rm -rf dst" && ++ git init --bare dst && ++ git -C dst config transfer.fsckObjects true && ++ test_must_fail git push dst HEAD 2>err && ++ grep gitmodulesUrl err ++' ++ + test_expect_success 'fsck permits embedded newline with unrecognized scheme' ' + git checkout --orphan newscheme && + cat >.gitmodules <<-\EOF && +-- +1.9.1 + |