diff options
Diffstat (limited to 'meta/recipes-devtools/git/git/CVE-2020-11008-5.patch')
-rw-r--r-- | meta/recipes-devtools/git/git/CVE-2020-11008-5.patch | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/meta/recipes-devtools/git/git/CVE-2020-11008-5.patch b/meta/recipes-devtools/git/git/CVE-2020-11008-5.patch new file mode 100644 index 0000000000..60f8d59082 --- /dev/null +++ b/meta/recipes-devtools/git/git/CVE-2020-11008-5.patch | |||
@@ -0,0 +1,211 @@ | |||
1 | From 3431abe8c0f64f4049a31298c0b1056baa7d81dc Mon Sep 17 00:00:00 2001 | ||
2 | From: Li Zhou <li.zhou@windriver.com> | ||
3 | Date: Mon, 27 Apr 2020 14:45:49 +0800 | ||
4 | Subject: [PATCH 08/12] fsck: convert gitmodules url to URL passed to curl | ||
5 | |||
6 | In 07259e74ec1 (fsck: detect gitmodules URLs with embedded newlines, | ||
7 | 2020-03-11), git fsck learned to check whether URLs in .gitmodules could | ||
8 | be understood by the credential machinery when they are handled by | ||
9 | git-remote-curl. | ||
10 | |||
11 | However, the check is overbroad: it checks all URLs instead of only | ||
12 | URLs that would be passed to git-remote-curl. In principle a git:// or | ||
13 | file:/// URL does not need to follow the same conventions as an http:// | ||
14 | URL; in particular, git:// and file:// protocols are not succeptible to | ||
15 | issues in the credential API because they do not support attaching | ||
16 | credentials. | ||
17 | |||
18 | In the HTTP case, the URL in .gitmodules does not always match the URL | ||
19 | that would be passed to git-remote-curl and the credential machinery: | ||
20 | Git's URL syntax allows specifying a remote helper followed by a "::" | ||
21 | delimiter and a URL to be passed to it, so that | ||
22 | |||
23 | git ls-remote http::https://example.com/repo.git | ||
24 | |||
25 | invokes git-remote-http with https://example.com/repo.git as its URL | ||
26 | argument. With today's checks, that distinction does not make a | ||
27 | difference, but for a check we are about to introduce (for empty URL | ||
28 | schemes) it will matter. | ||
29 | |||
30 | .gitmodules files also support relative URLs. To ensure coverage for the | ||
31 | https based embedded-newline attack, urldecode and check them directly | ||
32 | for embedded newlines. | ||
33 | |||
34 | Helped-by: Jeff King <peff@peff.net> | ||
35 | Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> | ||
36 | Reviewed-by: Jeff King <peff@peff.net> | ||
37 | |||
38 | Upstream-Status: Backport | ||
39 | CVE: CVE-2020-11008 (5) | ||
40 | Signed-off-by: Li Zhou <li.zhou@windriver.com> | ||
41 | --- | ||
42 | fsck.c | 94 ++++++++++++++++++++++++++++++++++++++++--- | ||
43 | t/t7416-submodule-dash-url.sh | 29 +++++++++++++ | ||
44 | 2 files changed, 118 insertions(+), 5 deletions(-) | ||
45 | |||
46 | diff --git a/fsck.c b/fsck.c | ||
47 | index ea46eea..0f21eb1 100644 | ||
48 | --- a/fsck.c | ||
49 | +++ b/fsck.c | ||
50 | @@ -9,6 +9,7 @@ | ||
51 | #include "tag.h" | ||
52 | #include "fsck.h" | ||
53 | #include "refs.h" | ||
54 | +#include "url.h" | ||
55 | #include "utf8.h" | ||
56 | #include "decorate.h" | ||
57 | #include "oidset.h" | ||
58 | @@ -948,17 +949,100 @@ static int fsck_tag(struct tag *tag, const char *data, | ||
59 | return fsck_tag_buffer(tag, data, size, options); | ||
60 | } | ||
61 | |||
62 | +/* | ||
63 | + * Like builtin/submodule--helper.c's starts_with_dot_slash, but without | ||
64 | + * relying on the platform-dependent is_dir_sep helper. | ||
65 | + * | ||
66 | + * This is for use in checking whether a submodule URL is interpreted as | ||
67 | + * relative to the current directory on any platform, since \ is a | ||
68 | + * directory separator on Windows but not on other platforms. | ||
69 | + */ | ||
70 | +static int starts_with_dot_slash(const char *str) | ||
71 | +{ | ||
72 | + return str[0] == '.' && (str[1] == '/' || str[1] == '\\'); | ||
73 | +} | ||
74 | + | ||
75 | +/* | ||
76 | + * Like starts_with_dot_slash, this is a variant of submodule--helper's | ||
77 | + * helper of the same name with the twist that it accepts backslash as a | ||
78 | + * directory separator even on non-Windows platforms. | ||
79 | + */ | ||
80 | +static int starts_with_dot_dot_slash(const char *str) | ||
81 | +{ | ||
82 | + return str[0] == '.' && starts_with_dot_slash(str + 1); | ||
83 | +} | ||
84 | + | ||
85 | +static int submodule_url_is_relative(const char *url) | ||
86 | +{ | ||
87 | + return starts_with_dot_slash(url) || starts_with_dot_dot_slash(url); | ||
88 | +} | ||
89 | + | ||
90 | +/* | ||
91 | + * Check whether a transport is implemented by git-remote-curl. | ||
92 | + * | ||
93 | + * If it is, returns 1 and writes the URL that would be passed to | ||
94 | + * git-remote-curl to the "out" parameter. | ||
95 | + * | ||
96 | + * Otherwise, returns 0 and leaves "out" untouched. | ||
97 | + * | ||
98 | + * Examples: | ||
99 | + * http::https://example.com/repo.git -> 1, https://example.com/repo.git | ||
100 | + * https://example.com/repo.git -> 1, https://example.com/repo.git | ||
101 | + * git://example.com/repo.git -> 0 | ||
102 | + * | ||
103 | + * This is for use in checking for previously exploitable bugs that | ||
104 | + * required a submodule URL to be passed to git-remote-curl. | ||
105 | + */ | ||
106 | +static int url_to_curl_url(const char *url, const char **out) | ||
107 | +{ | ||
108 | + /* | ||
109 | + * We don't need to check for case-aliases, "http.exe", and so | ||
110 | + * on because in the default configuration, is_transport_allowed | ||
111 | + * prevents URLs with those schemes from being cloned | ||
112 | + * automatically. | ||
113 | + */ | ||
114 | + if (skip_prefix(url, "http::", out) || | ||
115 | + skip_prefix(url, "https::", out) || | ||
116 | + skip_prefix(url, "ftp::", out) || | ||
117 | + skip_prefix(url, "ftps::", out)) | ||
118 | + return 1; | ||
119 | + if (starts_with(url, "http://") || | ||
120 | + starts_with(url, "https://") || | ||
121 | + starts_with(url, "ftp://") || | ||
122 | + starts_with(url, "ftps://")) { | ||
123 | + *out = url; | ||
124 | + return 1; | ||
125 | + } | ||
126 | + return 0; | ||
127 | +} | ||
128 | + | ||
129 | static int check_submodule_url(const char *url) | ||
130 | { | ||
131 | - struct credential c = CREDENTIAL_INIT; | ||
132 | - int ret; | ||
133 | + const char *curl_url; | ||
134 | |||
135 | if (looks_like_command_line_option(url)) | ||
136 | return -1; | ||
137 | |||
138 | - ret = credential_from_url_gently(&c, url, 1); | ||
139 | - credential_clear(&c); | ||
140 | - return ret; | ||
141 | + if (submodule_url_is_relative(url)) { | ||
142 | + /* | ||
143 | + * This could be appended to an http URL and url-decoded; | ||
144 | + * check for malicious characters. | ||
145 | + */ | ||
146 | + char *decoded = url_decode(url); | ||
147 | + int has_nl = !!strchr(decoded, '\n'); | ||
148 | + free(decoded); | ||
149 | + if (has_nl) | ||
150 | + return -1; | ||
151 | + } | ||
152 | + | ||
153 | + else if (url_to_curl_url(url, &curl_url)) { | ||
154 | + struct credential c = CREDENTIAL_INIT; | ||
155 | + int ret = credential_from_url_gently(&c, curl_url, 1); | ||
156 | + credential_clear(&c); | ||
157 | + return ret; | ||
158 | + } | ||
159 | + | ||
160 | + return 0; | ||
161 | } | ||
162 | |||
163 | struct fsck_gitmodules_data { | ||
164 | diff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh | ||
165 | index 41431b1..afdd255 100755 | ||
166 | --- a/t/t7416-submodule-dash-url.sh | ||
167 | +++ b/t/t7416-submodule-dash-url.sh | ||
168 | @@ -60,6 +60,20 @@ test_expect_success 'trailing backslash is handled correctly' ' | ||
169 | test_i18ngrep ! "unknown option" err | ||
170 | ' | ||
171 | |||
172 | +test_expect_success 'fsck permits embedded newline with unrecognized scheme' ' | ||
173 | + git checkout --orphan newscheme && | ||
174 | + cat >.gitmodules <<-\EOF && | ||
175 | + [submodule "foo"] | ||
176 | + url = "data://acjbkd%0akajfdickajkd" | ||
177 | + EOF | ||
178 | + git add .gitmodules && | ||
179 | + git commit -m "gitmodules with unrecognized scheme" && | ||
180 | + test_when_finished "rm -rf dst" && | ||
181 | + git init --bare dst && | ||
182 | + git -C dst config transfer.fsckObjects true && | ||
183 | + git push dst HEAD | ||
184 | +' | ||
185 | + | ||
186 | test_expect_success 'fsck rejects embedded newline in url' ' | ||
187 | # create an orphan branch to avoid existing .gitmodules objects | ||
188 | git checkout --orphan newline && | ||
189 | @@ -76,4 +90,19 @@ test_expect_success 'fsck rejects embedded newline in url' ' | ||
190 | grep gitmodulesUrl err | ||
191 | ' | ||
192 | |||
193 | +test_expect_success 'fsck rejects embedded newline in relative url' ' | ||
194 | + git checkout --orphan relative-newline && | ||
195 | + cat >.gitmodules <<-\EOF && | ||
196 | + [submodule "foo"] | ||
197 | + url = "./%0ahost=two.example.com/foo.git" | ||
198 | + EOF | ||
199 | + git add .gitmodules && | ||
200 | + git commit -m "relative url with newline" && | ||
201 | + test_when_finished "rm -rf dst" && | ||
202 | + git init --bare dst && | ||
203 | + git -C dst config transfer.fsckObjects true && | ||
204 | + test_must_fail git push dst HEAD 2>err && | ||
205 | + grep gitmodulesUrl err | ||
206 | +' | ||
207 | + | ||
208 | test_done | ||
209 | -- | ||
210 | 1.9.1 | ||
211 | |||