summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVijay Anusuri <vanusuri@mvista.com>2025-06-09 16:39:23 +0530
committerSteve Sakoman <steve@sakoman.com>2025-06-13 08:42:35 -0700
commit57421fdde6b8202f64ff0bdf911e56398fc07853 (patch)
treebd97dd6d565dc61239cb8c0667007d90dcf380f5
parent50475a377af20298fe3f18cd81c261ffe851bcf8 (diff)
downloadpoky-57421fdde6b8202f64ff0bdf911e56398fc07853.tar.gz
git: Fix CVE-2024-50349 and CVE-2024-52006
Upstream-Status: Backport from https://github.com/git/git/commit/c903985bf7e772e2d08275c1a95c8a55ab011577 & https://github.com/git/git/commit/7725b8100ffbbff2750ee4d61a0fcc1f53a086e8 & https://github.com/git/git/commit/b01b9b81d36759cdcd07305e78765199e1bc2060 (From OE-Core rev: ed112b58ad0d40bfa36e53a370e964e6a20d694e) Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r--meta/recipes-devtools/git/git/CVE-2024-50349-0001.patch100
-rw-r--r--meta/recipes-devtools/git/git/CVE-2024-50349-0002.patch321
-rw-r--r--meta/recipes-devtools/git/git/CVE-2024-52006.patch165
-rw-r--r--meta/recipes-devtools/git/git_2.35.7.bb3
4 files changed, 589 insertions, 0 deletions
diff --git a/meta/recipes-devtools/git/git/CVE-2024-50349-0001.patch b/meta/recipes-devtools/git/git/CVE-2024-50349-0001.patch
new file mode 100644
index 0000000000..a4567f83f5
--- /dev/null
+++ b/meta/recipes-devtools/git/git/CVE-2024-50349-0001.patch
@@ -0,0 +1,100 @@
1From c903985bf7e772e2d08275c1a95c8a55ab011577 Mon Sep 17 00:00:00 2001
2From: Johannes Schindelin <johannes.schindelin@gmx.de>
3Date: Thu, 7 Nov 2024 08:57:52 +0100
4Subject: [PATCH] credential_format(): also encode <host>[:<port>]
5
6An upcoming change wants to sanitize the credential password prompt
7where a URL is displayed that may potentially come from a `.gitmodules`
8file. To this end, the `credential_format()` function is employed.
9
10To sanitize the host name (and optional port) part of the URL, we need a
11new mode of the `strbuf_add_percentencode()` function because the
12current mode is both too strict and too lenient: too strict because it
13encodes `:`, `[` and `]` (which should be left unencoded in
14`<host>:<port>` and in IPv6 addresses), and too lenient because it does
15not encode invalid host name characters `/`, `_` and `~`.
16
17So let's introduce and use a new mode specifically to encode the host
18name and optional port part of a URI, leaving alpha-numerical
19characters, periods, colons and brackets alone and encoding all others.
20
21This only leads to a change of behavior for URLs that contain invalid
22host names.
23
24Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
25
26Upstream-Status: Backport [https://github.com/git/git/commit/c903985bf7e772e2d08275c1a95c8a55ab011577]
27CVE: CVE-2024-50349
28Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
29---
30 credential.c | 3 ++-
31 strbuf.c | 4 +++-
32 strbuf.h | 1 +
33 t/t0300-credentials.sh | 13 +++++++++++++
34 4 files changed, 19 insertions(+), 2 deletions(-)
35
36diff --git a/credential.c b/credential.c
37index f32011343f9400..572f1785da7d3e 100644
38--- a/credential.c
39+++ b/credential.c
40@@ -164,7 +164,8 @@ static void credential_format(struct credential *c, struct strbuf *out)
41 strbuf_addch(out, '@');
42 }
43 if (c->host)
44- strbuf_addstr(out, c->host);
45+ strbuf_add_percentencode(out, c->host,
46+ STRBUF_ENCODE_HOST_AND_PORT);
47 if (c->path) {
48 strbuf_addch(out, '/');
49 strbuf_add_percentencode(out, c->path, 0);
50diff --git a/strbuf.c b/strbuf.c
51index c383f41a3c5ccc..756b96c56157c3 100644
52--- a/strbuf.c
53+++ b/strbuf.c
54@@ -492,7 +492,9 @@ void strbuf_add_percentencode(struct strbuf *dst, const char *src, int flags)
55 unsigned char ch = src[i];
56 if (ch <= 0x1F || ch >= 0x7F ||
57 (ch == '/' && (flags & STRBUF_ENCODE_SLASH)) ||
58- strchr(URL_UNSAFE_CHARS, ch))
59+ ((flags & STRBUF_ENCODE_HOST_AND_PORT) ?
60+ !isalnum(ch) && !strchr("-.:[]", ch) :
61+ !!strchr(URL_UNSAFE_CHARS, ch)))
62 strbuf_addf(dst, "%%%02X", (unsigned char)ch);
63 else
64 strbuf_addch(dst, ch);
65diff --git a/strbuf.h b/strbuf.h
66index f6dbb9681ee768..f9f8bb0381b3c5 100644
67--- a/strbuf.h
68+++ b/strbuf.h
69@@ -380,6 +380,7 @@ size_t strbuf_expand_dict_cb(struct strbuf *sb,
70 void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src);
71
72 #define STRBUF_ENCODE_SLASH 1
73+#define STRBUF_ENCODE_HOST_AND_PORT 2
74
75 /**
76 * Append the contents of a string to a strbuf, percent-encoding any characters
77diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh
78index c66d91e82d8bc7..cb91be1427f1d2 100755
79--- a/t/t0300-credentials.sh
80+++ b/t/t0300-credentials.sh
81@@ -514,6 +514,19 @@ test_expect_success 'match percent-encoded values in username' '
82 EOF
83 '
84
85+test_expect_success 'match percent-encoded values in hostname' '
86+ test_config "credential.https://a%20b%20c/.helper" "$HELPER" &&
87+ check fill <<-\EOF
88+ url=https://a b c/
89+ --
90+ protocol=https
91+ host=a b c
92+ username=foo
93+ password=bar
94+ --
95+ EOF
96+'
97+
98 test_expect_success 'fetch with multiple path components' '
99 test_unconfig credential.helper &&
100 test_config credential.https://example.com/foo/repo.git.helper "verbatim foo bar" &&
diff --git a/meta/recipes-devtools/git/git/CVE-2024-50349-0002.patch b/meta/recipes-devtools/git/git/CVE-2024-50349-0002.patch
new file mode 100644
index 0000000000..6135b00737
--- /dev/null
+++ b/meta/recipes-devtools/git/git/CVE-2024-50349-0002.patch
@@ -0,0 +1,321 @@
1From 7725b8100ffbbff2750ee4d61a0fcc1f53a086e8 Mon Sep 17 00:00:00 2001
2From: Johannes Schindelin <johannes.schindelin@gmx.de>
3Date: Wed, 30 Oct 2024 13:26:10 +0100
4Subject: [PATCH] credential: sanitize the user prompt
5
6When asking the user interactively for credentials, we want to avoid
7misleading them e.g. via control sequences that pretend that the URL
8targets a trusted host when it does not.
9
10While Git learned, over the course of the preceding commits, to disallow
11URLs containing URL-encoded control characters by default, credential
12helpers are still allowed to specify values very freely (apart from Line
13Feed and NUL characters, anything is allowed), and this would allow,
14say, a username containing control characters to be specified that would
15then be displayed in the interactive terminal prompt asking the user for
16the password, potentially sending those control characters directly to
17the terminal. This is undesirable because control characters can be used
18to mislead users to divulge secret information to untrusted sites.
19
20To prevent such an attack vector, let's add a `git_prompt()` that forces
21the displayed text to be sanitized, i.e. displaying question marks
22instead of control characters.
23
24Note: While this commit's diff changes a lot of `user@host` strings to
25`user%40host`, which may look suspicious on the surface, there is a good
26reason for that: this string specifies a user name, not a
27<username>@<hostname> combination! In the context of t5541, the actual
28combination looks like this: `user%40@127.0.0.1:5541`. Therefore, these
29string replacements document a net improvement introduced by this
30commit, as `user@host@127.0.0.1` could have left readers wondering where
31the user name ends and where the host name begins.
32
33Hinted-at-by: Jeff King <peff@peff.net>
34Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
35
36Upstream-Status: Backport [https://github.com/git/git/commit/7725b8100ffbbff2750ee4d61a0fcc1f53a086e8]
37CVE: CVE-2024-50349
38Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
39---
40 Documentation/config/credential.txt | 6 ++++++
41 credential.c | 7 ++++++-
42 credential.h | 4 +++-
43 t/t0300-credentials.sh | 20 ++++++++++++++++++++
44 t/t5541-http-push-smart.sh | 6 +++---
45 t/t5550-http-fetch-dumb.sh | 14 +++++++-------
46 t/t5551-http-fetch-smart.sh | 16 ++++++++--------
47 7 files changed, 53 insertions(+), 20 deletions(-)
48
49diff --git a/Documentation/config/credential.txt b/Documentation/config/credential.txt
50index 512f318..fd8113d 100644
51--- a/Documentation/config/credential.txt
52+++ b/Documentation/config/credential.txt
53@@ -14,6 +14,12 @@ credential.useHttpPath::
54 or https URL to be important. Defaults to false. See
55 linkgit:gitcredentials[7] for more information.
56
57+credential.sanitizePrompt::
58+ By default, user names and hosts that are shown as part of the
59+ password prompt are not allowed to contain control characters (they
60+ will be URL-encoded by default). Configure this setting to `false` to
61+ override that behavior.
62+
63 credential.username::
64 If no username is set for a network authentication, use this username
65 by default. See credential.<context>.* below, and
66diff --git a/credential.c b/credential.c
67index 195556d..a071ead 100644
68--- a/credential.c
69+++ b/credential.c
70@@ -66,6 +66,8 @@ static int credential_config_callback(const char *var, const char *value,
71 }
72 else if (!strcmp(key, "usehttppath"))
73 c->use_http_path = git_config_bool(var, value);
74+ else if (!strcmp(key, "sanitizeprompt"))
75+ c->sanitize_prompt = git_config_bool(var, value);
76
77 return 0;
78 }
79@@ -177,7 +179,10 @@ static char *credential_ask_one(const char *what, struct credential *c,
80 struct strbuf prompt = STRBUF_INIT;
81 char *r;
82
83- credential_describe(c, &desc);
84+ if (c->sanitize_prompt)
85+ credential_format(c, &desc);
86+ else
87+ credential_describe(c, &desc);
88 if (desc.len)
89 strbuf_addf(&prompt, "%s for '%s': ", what, desc.buf);
90 else
91diff --git a/credential.h b/credential.h
92index f430e77..222bbf1 100644
93--- a/credential.h
94+++ b/credential.h
95@@ -119,7 +119,8 @@ struct credential {
96 configured:1,
97 quit:1,
98 use_http_path:1,
99- username_from_proto:1;
100+ username_from_proto:1,
101+ sanitize_prompt:1;
102
103 char *username;
104 char *password;
105@@ -130,6 +131,7 @@ struct credential {
106
107 #define CREDENTIAL_INIT { \
108 .helpers = STRING_LIST_INIT_DUP, \
109+ .sanitize_prompt = 1, \
110 }
111
112 /* Initialize a credential structure, setting all fields to empty. */
113diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh
114index c13be4f..9e27499 100755
115--- a/t/t0300-credentials.sh
116+++ b/t/t0300-credentials.sh
117@@ -35,6 +35,10 @@ test_expect_success 'setup helper scripts' '
118 test -z "$pass" || echo password=$pass
119 EOF
120
121+ write_script git-credential-cntrl-in-username <<-\EOF &&
122+ printf "username=\\007latrix Lestrange\\n"
123+ EOF
124+
125 PATH="$PWD:$PATH"
126 '
127
128@@ -731,4 +735,20 @@ test_expect_success 'credential config with partial URLs' '
129 test_i18ngrep "skipping credential lookup for key" stderr
130 '
131
132+BEL="$(printf '\007')"
133+
134+test_expect_success 'interactive prompt is sanitized' '
135+ check fill cntrl-in-username <<-EOF
136+ protocol=https
137+ host=example.org
138+ --
139+ protocol=https
140+ host=example.org
141+ username=${BEL}latrix Lestrange
142+ password=askpass-password
143+ --
144+ askpass: Password for ${SQ}https://%07latrix%20Lestrange@example.org${SQ}:
145+ EOF
146+'
147+
148 test_done
149diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
150index 8ca50f8..66e7da0 100755
151--- a/t/t5541-http-push-smart.sh
152+++ b/t/t5541-http-push-smart.sh
153@@ -363,7 +363,7 @@ test_expect_success 'push over smart http with auth' '
154 git push "$HTTPD_URL"/auth/smart/test_repo.git &&
155 git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
156 log -1 --format=%s >actual &&
157- expect_askpass both user@host &&
158+ expect_askpass both user%40host &&
159 test_cmp expect actual
160 '
161
162@@ -375,7 +375,7 @@ test_expect_success 'push to auth-only-for-push repo' '
163 git push "$HTTPD_URL"/auth-push/smart/test_repo.git &&
164 git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \
165 log -1 --format=%s >actual &&
166- expect_askpass both user@host &&
167+ expect_askpass both user%40host &&
168 test_cmp expect actual
169 '
170
171@@ -405,7 +405,7 @@ test_expect_success 'push into half-auth-complete requires password' '
172 git push "$HTTPD_URL/half-auth-complete/smart/half-auth.git" &&
173 git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/half-auth.git" \
174 log -1 --format=%s >actual &&
175- expect_askpass both user@host &&
176+ expect_askpass both user%40host &&
177 test_cmp expect actual
178 '
179
180diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh
181index 2592039..fed22e5 100755
182--- a/t/t5550-http-fetch-dumb.sh
183+++ b/t/t5550-http-fetch-dumb.sh
184@@ -95,13 +95,13 @@ test_expect_success 'http auth can use user/pass in URL' '
185 test_expect_success 'http auth can use just user in URL' '
186 set_askpass wrong pass@host &&
187 git clone "$HTTPD_URL_USER/auth/dumb/repo.git" clone-auth-pass &&
188- expect_askpass pass user@host
189+ expect_askpass pass user%40host
190 '
191
192 test_expect_success 'http auth can request both user and pass' '
193 set_askpass user@host pass@host &&
194 git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-both &&
195- expect_askpass both user@host
196+ expect_askpass both user%40host
197 '
198
199 test_expect_success 'http auth respects credential helper config' '
200@@ -119,14 +119,14 @@ test_expect_success 'http auth can get username from config' '
201 test_config_global "credential.$HTTPD_URL.username" user@host &&
202 set_askpass wrong pass@host &&
203 git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-user &&
204- expect_askpass pass user@host
205+ expect_askpass pass user%40host
206 '
207
208 test_expect_success 'configured username does not override URL' '
209 test_config_global "credential.$HTTPD_URL.username" wrong &&
210 set_askpass wrong pass@host &&
211 git clone "$HTTPD_URL_USER/auth/dumb/repo.git" clone-auth-user2 &&
212- expect_askpass pass user@host
213+ expect_askpass pass user%40host
214 '
215
216 test_expect_success 'set up repo with http submodules' '
217@@ -147,7 +147,7 @@ test_expect_success 'cmdline credential config passes to submodule via clone' '
218 set_askpass wrong pass@host &&
219 git -c "credential.$HTTPD_URL.username=user@host" \
220 clone --recursive super super-clone &&
221- expect_askpass pass user@host
222+ expect_askpass pass user%40host
223 '
224
225 test_expect_success 'cmdline credential config passes submodule via fetch' '
226@@ -158,7 +158,7 @@ test_expect_success 'cmdline credential config passes submodule via fetch' '
227 git -C super-clone \
228 -c "credential.$HTTPD_URL.username=user@host" \
229 fetch --recurse-submodules &&
230- expect_askpass pass user@host
231+ expect_askpass pass user%40host
232 '
233
234 test_expect_success 'cmdline credential config passes submodule update' '
235@@ -175,7 +175,7 @@ test_expect_success 'cmdline credential config passes submodule update' '
236 git -C super-clone \
237 -c "credential.$HTTPD_URL.username=user@host" \
238 submodule update &&
239- expect_askpass pass user@host
240+ expect_askpass pass user%40host
241 '
242
243 test_expect_success 'fetch changes via http' '
244diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh
245index f92c79c..53a21f6 100755
246--- a/t/t5551-http-fetch-smart.sh
247+++ b/t/t5551-http-fetch-smart.sh
248@@ -142,7 +142,7 @@ test_expect_success 'clone from password-protected repository' '
249 echo two >expect &&
250 set_askpass user@host pass@host &&
251 git clone --bare "$HTTPD_URL/auth/smart/repo.git" smart-auth &&
252- expect_askpass both user@host &&
253+ expect_askpass both user%40host &&
254 git --git-dir=smart-auth log -1 --format=%s >actual &&
255 test_cmp expect actual
256 '
257@@ -160,7 +160,7 @@ test_expect_success 'clone from auth-only-for-objects repository' '
258 echo two >expect &&
259 set_askpass user@host pass@host &&
260 git clone --bare "$HTTPD_URL/auth-fetch/smart/repo.git" half-auth &&
261- expect_askpass both user@host &&
262+ expect_askpass both user%40host &&
263 git --git-dir=half-auth log -1 --format=%s >actual &&
264 test_cmp expect actual
265 '
266@@ -185,14 +185,14 @@ test_expect_success 'redirects send auth to new location' '
267 set_askpass user@host pass@host &&
268 git -c credential.useHttpPath=true \
269 clone $HTTPD_URL/smart-redir-auth/repo.git repo-redir-auth &&
270- expect_askpass both user@host auth/smart/repo.git
271+ expect_askpass both user%40host auth/smart/repo.git
272 '
273
274 test_expect_success 'GIT_TRACE_CURL redacts auth details' '
275 rm -rf redact-auth trace &&
276 set_askpass user@host pass@host &&
277 GIT_TRACE_CURL="$(pwd)/trace" git clone --bare "$HTTPD_URL/auth/smart/repo.git" redact-auth &&
278- expect_askpass both user@host &&
279+ expect_askpass both user%40host &&
280
281 # Ensure that there is no "Basic" followed by a base64 string, but that
282 # the auth details are redacted
283@@ -204,7 +204,7 @@ test_expect_success 'GIT_CURL_VERBOSE redacts auth details' '
284 rm -rf redact-auth trace &&
285 set_askpass user@host pass@host &&
286 GIT_CURL_VERBOSE=1 git clone --bare "$HTTPD_URL/auth/smart/repo.git" redact-auth 2>trace &&
287- expect_askpass both user@host &&
288+ expect_askpass both user%40host &&
289
290 # Ensure that there is no "Basic" followed by a base64 string, but that
291 # the auth details are redacted
292@@ -217,7 +217,7 @@ test_expect_success 'GIT_TRACE_CURL does not redact auth details if GIT_TRACE_RE
293 set_askpass user@host pass@host &&
294 GIT_TRACE_REDACT=0 GIT_TRACE_CURL="$(pwd)/trace" \
295 git clone --bare "$HTTPD_URL/auth/smart/repo.git" redact-auth &&
296- expect_askpass both user@host &&
297+ expect_askpass both user%40host &&
298
299 grep -i "Authorization: Basic [0-9a-zA-Z+/]" trace
300 '
301@@ -524,7 +524,7 @@ test_expect_success 'http auth remembers successful credentials' '
302 # the first request prompts the user...
303 set_askpass user@host pass@host &&
304 git ls-remote "$HTTPD_URL/auth/smart/repo.git" >/dev/null &&
305- expect_askpass both user@host &&
306+ expect_askpass both user%40host &&
307
308 # ...and the second one uses the stored value rather than
309 # prompting the user.
310@@ -555,7 +555,7 @@ test_expect_success 'http auth forgets bogus credentials' '
311 # us to prompt the user again.
312 set_askpass user@host pass@host &&
313 git ls-remote "$HTTPD_URL/auth/smart/repo.git" >/dev/null &&
314- expect_askpass both user@host
315+ expect_askpass both user%40host
316 '
317
318 test_expect_success 'client falls back from v2 to v0 to match server' '
319--
3202.25.1
321
diff --git a/meta/recipes-devtools/git/git/CVE-2024-52006.patch b/meta/recipes-devtools/git/git/CVE-2024-52006.patch
new file mode 100644
index 0000000000..403f9752b7
--- /dev/null
+++ b/meta/recipes-devtools/git/git/CVE-2024-52006.patch
@@ -0,0 +1,165 @@
1From b01b9b81d36759cdcd07305e78765199e1bc2060 Mon Sep 17 00:00:00 2001
2From: Johannes Schindelin <johannes.schindelin@gmx.de>
3Date: Mon, 4 Nov 2024 14:48:22 +0100
4Subject: [PATCH] credential: disallow Carriage Returns in the protocol by
5 default
6
7While Git has documented that the credential protocol is line-based,
8with newlines as terminators, the exact shape of a newline has not been
9documented.
10
11From Git's perspective, which is firmly rooted in the Linux ecosystem,
12it is clear that "a newline" means a Line Feed character.
13
14However, even Git's credential protocol respects Windows line endings
15(a Carriage Return character followed by a Line Feed character, "CR/LF")
16by virtue of using `strbuf_getline()`.
17
18There is a third category of line endings that has been used originally
19by MacOS, and that is respected by the default line readers of .NET and
20node.js: bare Carriage Returns.
21
22Git cannot handle those, and what is worse: Git's remedy against
23CVE-2020-5260 does not catch when credential helpers are used that
24interpret bare Carriage Returns as newlines.
25
26Git Credential Manager addressed this as CVE-2024-50338, but other
27credential helpers may still be vulnerable. So let's not only disallow
28Line Feed characters as part of the values in the credential protocol,
29but also disallow Carriage Return characters.
30
31In the unlikely event that a credential helper relies on Carriage
32Returns in the protocol, introduce an escape hatch via the
33`credential.protectProtocol` config setting.
34
35This addresses CVE-2024-52006.
36
37Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
38
39Upstream-Status: Backport [https://github.com/git/git/commit/b01b9b81d36759cdcd07305e78765199e1bc2060]
40CVE: CVE-2024-52006
41Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
42---
43 Documentation/config/credential.txt | 5 +++++
44 credential.c | 19 +++++++++++++------
45 credential.h | 4 +++-
46 t/t0300-credentials.sh | 16 ++++++++++++++++
47 4 files changed, 37 insertions(+), 7 deletions(-)
48
49diff --git a/Documentation/config/credential.txt b/Documentation/config/credential.txt
50index fd8113d..9cadca7 100644
51--- a/Documentation/config/credential.txt
52+++ b/Documentation/config/credential.txt
53@@ -20,6 +20,11 @@ credential.sanitizePrompt::
54 will be URL-encoded by default). Configure this setting to `false` to
55 override that behavior.
56
57+credential.protectProtocol::
58+ By default, Carriage Return characters are not allowed in the protocol
59+ that is used when Git talks to a credential helper. This setting allows
60+ users to override this default.
61+
62 credential.username::
63 If no username is set for a network authentication, use this username
64 by default. See credential.<context>.* below, and
65diff --git a/credential.c b/credential.c
66index a071ead..b427d55 100644
67--- a/credential.c
68+++ b/credential.c
69@@ -68,6 +68,8 @@ static int credential_config_callback(const char *var, const char *value,
70 c->use_http_path = git_config_bool(var, value);
71 else if (!strcmp(key, "sanitizeprompt"))
72 c->sanitize_prompt = git_config_bool(var, value);
73+ else if (!strcmp(key, "protectprotocol"))
74+ c->protect_protocol = git_config_bool(var, value);
75
76 return 0;
77 }
78@@ -255,7 +257,8 @@ int credential_read(struct credential *c, FILE *fp)
79 return 0;
80 }
81
82-static void credential_write_item(FILE *fp, const char *key, const char *value,
83+static void credential_write_item(const struct credential *c,
84+ FILE *fp, const char *key, const char *value,
85 int required)
86 {
87 if (!value && required)
88@@ -264,16 +267,20 @@ static void credential_write_item(FILE *fp, const char *key, const char *value,
89 return;
90 if (strchr(value, '\n'))
91 die("credential value for %s contains newline", key);
92+ if (c->protect_protocol && strchr(value, '\r'))
93+ die("credential value for %s contains carriage return\n"
94+ "If this is intended, set `credential.protectProtocol=false`",
95+ key);
96 fprintf(fp, "%s=%s\n", key, value);
97 }
98
99 void credential_write(const struct credential *c, FILE *fp)
100 {
101- credential_write_item(fp, "protocol", c->protocol, 1);
102- credential_write_item(fp, "host", c->host, 1);
103- credential_write_item(fp, "path", c->path, 0);
104- credential_write_item(fp, "username", c->username, 0);
105- credential_write_item(fp, "password", c->password, 0);
106+ credential_write_item(c, fp, "protocol", c->protocol, 1);
107+ credential_write_item(c, fp, "host", c->host, 1);
108+ credential_write_item(c, fp, "path", c->path, 0);
109+ credential_write_item(c, fp, "username", c->username, 0);
110+ credential_write_item(c, fp, "password", c->password, 0);
111 }
112
113 static int run_credential_helper(struct credential *c,
114diff --git a/credential.h b/credential.h
115index 222bbf1..b4b837c 100644
116--- a/credential.h
117+++ b/credential.h
118@@ -120,7 +120,8 @@ struct credential {
119 quit:1,
120 use_http_path:1,
121 username_from_proto:1,
122- sanitize_prompt:1;
123+ sanitize_prompt:1,
124+ protect_protocol:1;
125
126 char *username;
127 char *password;
128@@ -132,6 +133,7 @@ struct credential {
129 #define CREDENTIAL_INIT { \
130 .helpers = STRING_LIST_INIT_DUP, \
131 .sanitize_prompt = 1, \
132+ .protect_protocol = 1, \
133 }
134
135 /* Initialize a credential structure, setting all fields to empty. */
136diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh
137index 9e27499..ca158fe 100755
138--- a/t/t0300-credentials.sh
139+++ b/t/t0300-credentials.sh
140@@ -626,6 +626,22 @@ test_expect_success 'url parser rejects embedded newlines' '
141 test_cmp expect stderr
142 '
143
144+test_expect_success 'url parser rejects embedded carriage returns' '
145+ test_config credential.helper "!true" &&
146+ test_must_fail git credential fill 2>stderr <<-\EOF &&
147+ url=https://example%0d.com/
148+ EOF
149+ cat >expect <<-\EOF &&
150+ fatal: credential value for host contains carriage return
151+ If this is intended, set `credential.protectProtocol=false`
152+ EOF
153+ test_cmp expect stderr &&
154+ GIT_ASKPASS=true \
155+ git -c credential.protectProtocol=false credential fill <<-\EOF
156+ url=https://example%0d.com/
157+ EOF
158+'
159+
160 test_expect_success 'host-less URLs are parsed as empty host' '
161 check fill "verbatim foo bar" <<-\EOF
162 url=cert:///path/to/cert.pem
163--
1642.25.1
165
diff --git a/meta/recipes-devtools/git/git_2.35.7.bb b/meta/recipes-devtools/git/git_2.35.7.bb
index 94352d38ef..765180a38d 100644
--- a/meta/recipes-devtools/git/git_2.35.7.bb
+++ b/meta/recipes-devtools/git/git_2.35.7.bb
@@ -23,6 +23,9 @@ SRC_URI = "${KERNELORG_MIRROR}/software/scm/git/git-${PV}.tar.gz;name=tarball \
23 file://CVE-2024-32021-0001.patch \ 23 file://CVE-2024-32021-0001.patch \
24 file://CVE-2024-32021-0002.patch \ 24 file://CVE-2024-32021-0002.patch \
25 file://CVE-2024-32465.patch \ 25 file://CVE-2024-32465.patch \
26 file://CVE-2024-50349-0001.patch \
27 file://CVE-2024-50349-0002.patch \
28 file://CVE-2024-52006.patch \
26 " 29 "
27 30
28S = "${WORKDIR}/git-${PV}" 31S = "${WORKDIR}/git-${PV}"