diff options
| -rw-r--r-- | meta/recipes-devtools/git/files/CVE-2021-40330.patch | 108 | ||||
| -rw-r--r-- | meta/recipes-devtools/git/git.inc | 4 |
2 files changed, 111 insertions, 1 deletions
diff --git a/meta/recipes-devtools/git/files/CVE-2021-40330.patch b/meta/recipes-devtools/git/files/CVE-2021-40330.patch new file mode 100644 index 0000000000..725f98f0b7 --- /dev/null +++ b/meta/recipes-devtools/git/files/CVE-2021-40330.patch | |||
| @@ -0,0 +1,108 @@ | |||
| 1 | From e77ca0c7d577408878d2b3e8c7336e6119cb3931 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Minjae Kim <flowergom@gmail.com> | ||
| 3 | Date: Thu, 25 Nov 2021 06:36:26 +0000 | ||
| 4 | Subject: [PATCH] git_connect_git(): forbid newlines in host and path | ||
| 5 | |||
| 6 | When we connect to a git:// server, we send an initial request that | ||
| 7 | looks something like: | ||
| 8 | |||
| 9 | 002dgit-upload-pack repo.git\0host=example.com | ||
| 10 | |||
| 11 | If the repo path contains a newline, then it's included literally, and | ||
| 12 | we get: | ||
| 13 | |||
| 14 | 002egit-upload-pack repo | ||
| 15 | .git\0host=example.com | ||
| 16 | |||
| 17 | This works fine if you really do have a newline in your repository name; | ||
| 18 | the server side uses the pktline framing to parse the string, not | ||
| 19 | newlines. However, there are many _other_ protocols in the wild that do | ||
| 20 | parse on newlines, such as HTTP. So a carefully constructed git:// URL | ||
| 21 | can actually turn into a valid HTTP request. For example: | ||
| 22 | |||
| 23 | git://localhost:1234/%0d%0a%0d%0aGET%20/%20HTTP/1.1 %0d%0aHost:localhost%0d%0a%0d%0a | ||
| 24 | |||
| 25 | becomes: | ||
| 26 | |||
| 27 | 0050git-upload-pack / | ||
| 28 | GET / HTTP/1.1 | ||
| 29 | Host:localhost | ||
| 30 | |||
| 31 | host=localhost:1234 | ||
| 32 | |||
| 33 | on the wire. Again, this isn't a problem for a real Git server, but it | ||
| 34 | does mean that feeding a malicious URL to Git (e.g., through a | ||
| 35 | submodule) can cause it to make unexpected cross-protocol requests. | ||
| 36 | Since repository names with newlines are presumably quite rare (and | ||
| 37 | indeed, we already disallow them in git-over-http), let's just disallow | ||
| 38 | them over this protocol. | ||
| 39 | |||
| 40 | Hostnames could likewise inject a newline, but this is unlikely a | ||
| 41 | problem in practice; we'd try resolving the hostname with a newline in | ||
| 42 | it, which wouldn't work. Still, it doesn't hurt to err on the side of | ||
| 43 | caution there, since we would not expect them to work in the first | ||
| 44 | place. | ||
| 45 | |||
| 46 | The ssh and local code paths are unaffected by this patch. In both cases | ||
| 47 | we're trying to run upload-pack via a shell, and will quote the newline | ||
| 48 | so that it makes it intact. An attacker can point an ssh url at an | ||
| 49 | arbitrary port, of course, but unless there's an actual ssh server | ||
| 50 | there, we'd never get as far as sending our shell command anyway. We | ||
| 51 | _could_ similarly restrict newlines in those protocols out of caution, | ||
| 52 | but there seems little benefit to doing so. | ||
| 53 | |||
| 54 | The new test here is run alongside the git-daemon tests, which cover the | ||
| 55 | same protocol, but it shouldn't actually contact the daemon at all. In | ||
| 56 | theory we could make the test more robust by setting up an actual | ||
| 57 | repository with a newline in it (so that our clone would succeed if our | ||
| 58 | new check didn't kick in). But a repo directory with newline in it is | ||
| 59 | likely not portable across all filesystems. Likewise, we could check | ||
| 60 | git-daemon's log that it was not contacted at all, but we do not | ||
| 61 | currently record the log (and anyway, it would make the test racy with | ||
| 62 | the daemon's log write). We'll just check the client-side stderr to make | ||
| 63 | sure we hit the expected code path. | ||
| 64 | |||
| 65 | Reported-by: Harold Kim <h.kim@flatt.tech> | ||
| 66 | Signed-off-by: Jeff King <peff@peff.net> | ||
| 67 | Signed-off-by: Junio C Hamano <gitster@pobox.com> | ||
| 68 | |||
| 69 | Upstream-Status: Backported [https://github.com/git/git/commit/a02ea577174ab8ed18f847cf1693f213e0b9c473] | ||
| 70 | CVE: CVE-2021-40330 | ||
| 71 | Signed-off-by: Minjae Kim <flowergom@gmail.com> | ||
| 72 | --- | ||
| 73 | connect.c | 2 ++ | ||
| 74 | t/t5570-git-daemon.sh | 5 +++++ | ||
| 75 | 2 files changed, 7 insertions(+) | ||
| 76 | |||
| 77 | diff --git a/connect.c b/connect.c | ||
| 78 | index b6451ab..929de9a 100644 | ||
| 79 | --- a/connect.c | ||
| 80 | +++ b/connect.c | ||
| 81 | @@ -1064,6 +1064,8 @@ static struct child_process *git_connect_git(int fd[2], char *hostandport, | ||
| 82 | target_host = xstrdup(hostandport); | ||
| 83 | |||
| 84 | transport_check_allowed("git"); | ||
| 85 | + if (strchr(target_host, '\n') || strchr(path, '\n')) | ||
| 86 | + die(_("newline is forbidden in git:// hosts and repo paths")); | ||
| 87 | |||
| 88 | /* | ||
| 89 | * These underlying connection commands die() if they | ||
| 90 | diff --git a/t/t5570-git-daemon.sh b/t/t5570-git-daemon.sh | ||
| 91 | index 34487bb..79cd218 100755 | ||
| 92 | --- a/t/t5570-git-daemon.sh | ||
| 93 | +++ b/t/t5570-git-daemon.sh | ||
| 94 | @@ -103,6 +103,11 @@ test_expect_success 'fetch notices corrupt idx' ' | ||
| 95 | ) | ||
| 96 | ' | ||
| 97 | |||
| 98 | +test_expect_success 'client refuses to ask for repo with newline' ' | ||
| 99 | + test_must_fail git clone "$GIT_DAEMON_URL/repo$LF.git" dst 2>stderr && | ||
| 100 | + test_i18ngrep newline.is.forbidden stderr | ||
| 101 | +' | ||
| 102 | + | ||
| 103 | test_remote_error() | ||
| 104 | { | ||
| 105 | do_export=YesPlease | ||
| 106 | -- | ||
| 107 | 2.17.1 | ||
| 108 | |||
diff --git a/meta/recipes-devtools/git/git.inc b/meta/recipes-devtools/git/git.inc index 2b75bed055..a89dd42e8b 100644 --- a/meta/recipes-devtools/git/git.inc +++ b/meta/recipes-devtools/git/git.inc | |||
| @@ -10,7 +10,9 @@ PROVIDES_append_class-native = " git-replacement-native" | |||
| 10 | SRC_URI = "${KERNELORG_MIRROR}/software/scm/git/git-${PV}.tar.gz;name=tarball \ | 10 | SRC_URI = "${KERNELORG_MIRROR}/software/scm/git/git-${PV}.tar.gz;name=tarball \ |
| 11 | ${KERNELORG_MIRROR}/software/scm/git/git-manpages-${PV}.tar.gz;name=manpages \ | 11 | ${KERNELORG_MIRROR}/software/scm/git/git-manpages-${PV}.tar.gz;name=manpages \ |
| 12 | file://CVE-2021-21300.patch \ | 12 | file://CVE-2021-21300.patch \ |
| 13 | file://fixsort.patch" | 13 | file://fixsort.patch \ |
| 14 | file://CVE-2021-40330.patch \ | ||
| 15 | " | ||
| 14 | 16 | ||
| 15 | S = "${WORKDIR}/git-${PV}" | 17 | S = "${WORKDIR}/git-${PV}" |
| 16 | 18 | ||
