diff options
authorNatanael Copa <ncopa@alpinelinux.org>2022-03-15 12:27:30 +0100
committerNatanael Copa <ncopa@alpinelinux.org>2022-03-15 12:27:30 +0100
commit234c8fe7737f97ec355b069a1f0c8764af8b7e43 (patch)
parent89960635e0894c7e1e3a305bc43072dac8c55570 (diff)
main/git: backport fix for CVE-2021-40330
2 files changed, 107 insertions, 2 deletions
diff --git a/main/git/APKBUILD b/main/git/APKBUILD
index 78ec663fd9f..997df31b0e7 100644
--- a/main/git/APKBUILD
+++ b/main/git/APKBUILD
@@ -2,6 +2,8 @@
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
# secfixes:
+# 2.26.3-r1:
+# - CVE-2021-40330
# 2.26.3-r0:
# - CVE-2021-21300
# 2.26.2-r0:
@@ -31,7 +33,7 @@
pkgdesc="Distributed version control system"
@@ -62,6 +64,7 @@ subpackages="$pkgname-doc
+ CVE-2021-40330.patch
@@ -289,4 +292,5 @@ _perl_config() {
sha512sums="a88f8ab156f12770590110b30da83631f19a349f3b7af25fd0a5e8f03c78daec0a4935e9a1a5637f100c147cc57fca4aa3386e18756a6382983e7baa7456e398 git-2.26.3.tar.xz
89528cdd14c51fd568aa61cf6c5eae08ea0844e59f9af9292da5fc6c268261f4166017d002d494400945e248df6b844e2f9f9cd2d9345d516983f5a110e4c42a git-daemon.initd
-fbf1f425206a76e2a8f82342537ed939ff7e623d644c086ca2ced5f69b36734695f9f80ebda1728f75a94d6cd2fcb71bf845b64239368caab418e4d368c141ec git-daemon.confd"
+fbf1f425206a76e2a8f82342537ed939ff7e623d644c086ca2ced5f69b36734695f9f80ebda1728f75a94d6cd2fcb71bf845b64239368caab418e4d368c141ec git-daemon.confd
+739ed7c43e97384d970058b0edd58a665b1f879f87cd469e85991e6be3a3714be8c52326217f107861afd08c815ddd7a98230286cacd5a21757e5a1739152159 CVE-2021-40330.patch"
diff --git a/main/git/CVE-2021-40330.patch b/main/git/CVE-2021-40330.patch
new file mode 100644
index 00000000000..1722b530e4c
--- /dev/null
+++ b/main/git/CVE-2021-40330.patch
@@ -0,0 +1,101 @@
+From a02ea577174ab8ed18f847cf1693f213e0b9c473 Mon Sep 17 00:00:00 2001
+From: Jeff King <peff@peff.net>
+Date: Thu, 7 Jan 2021 04:43:58 -0500
+Subject: [PATCH] git_connect_git(): forbid newlines in host and path
+When we connect to a git:// server, we send an initial request that
+looks something like:
+ 002dgit-upload-pack repo.git\0host=example.com
+If the repo path contains a newline, then it's included literally, and
+we get:
+ 002egit-upload-pack repo
+ .git\0host=example.com
+This works fine if you really do have a newline in your repository name;
+the server side uses the pktline framing to parse the string, not
+newlines. However, there are many _other_ protocols in the wild that do
+parse on newlines, such as HTTP. So a carefully constructed git:// URL
+can actually turn into a valid HTTP request. For example:
+ git://localhost:1234/%0d%0a%0d%0aGET%20/%20HTTP/1.1 %0d%0aHost:localhost%0d%0a%0d%0a
+ 0050git-upload-pack /
+ GET / HTTP/1.1
+ Host:localhost
+ host=localhost:1234
+on the wire. Again, this isn't a problem for a real Git server, but it
+does mean that feeding a malicious URL to Git (e.g., through a
+submodule) can cause it to make unexpected cross-protocol requests.
+Since repository names with newlines are presumably quite rare (and
+indeed, we already disallow them in git-over-http), let's just disallow
+them over this protocol.
+Hostnames could likewise inject a newline, but this is unlikely a
+problem in practice; we'd try resolving the hostname with a newline in
+it, which wouldn't work. Still, it doesn't hurt to err on the side of
+caution there, since we would not expect them to work in the first
+The ssh and local code paths are unaffected by this patch. In both cases
+we're trying to run upload-pack via a shell, and will quote the newline
+so that it makes it intact. An attacker can point an ssh url at an
+arbitrary port, of course, but unless there's an actual ssh server
+there, we'd never get as far as sending our shell command anyway. We
+_could_ similarly restrict newlines in those protocols out of caution,
+but there seems little benefit to doing so.
+The new test here is run alongside the git-daemon tests, which cover the
+same protocol, but it shouldn't actually contact the daemon at all. In
+theory we could make the test more robust by setting up an actual
+repository with a newline in it (so that our clone would succeed if our
+new check didn't kick in). But a repo directory with newline in it is
+likely not portable across all filesystems. Likewise, we could check
+git-daemon's log that it was not contacted at all, but we do not
+currently record the log (and anyway, it would make the test racy with
+the daemon's log write). We'll just check the client-side stderr to make
+sure we hit the expected code path.
+Reported-by: Harold Kim <h.kim@flatt.tech>
+Signed-off-by: Jeff King <peff@peff.net>
+Signed-off-by: Junio C Hamano <gitster@pobox.com>
+ connect.c | 2 ++
+ t/t5570-git-daemon.sh | 5 +++++
+ 2 files changed, 7 insertions(+)
+diff --git a/connect.c b/connect.c
+index 79f1b3b24257a..7b4b65751d43d 100644
+--- a/connect.c
++++ b/connect.c
+@@ -1063,6 +1063,8 @@ static struct child_process *git_connect_git(int fd[2], char *hostandport,
+ target_host = xstrdup(hostandport);
+ transport_check_allowed("git");
++ if (strchr(target_host, '\n') || strchr(path, '\n'))
++ die(_("newline is forbidden in git:// hosts and repo paths"));
+ /*
+ * These underlying connection commands die() if they
+diff --git a/t/t5570-git-daemon.sh b/t/t5570-git-daemon.sh
+index 7466aad111fe4..336d417a90f87 100755
+--- a/t/t5570-git-daemon.sh
++++ b/t/t5570-git-daemon.sh
+@@ -102,6 +102,11 @@ test_expect_success 'fetch notices corrupt idx' '
+ )
+ '
++test_expect_success 'client refuses to ask for repo with newline' '
++ test_must_fail git clone "$GIT_DAEMON_URL/repo$LF.git" dst 2>stderr &&
++ test_i18ngrep newline.is.forbidden stderr
+ test_remote_error()
+ {
+ do_export=YesPlease