diff options
| author | Vijay Anusuri <vanusuri@mvista.com> | 2025-06-09 16:39:23 +0530 |
|---|---|---|
| committer | Steve Sakoman <steve@sakoman.com> | 2025-06-13 08:42:35 -0700 |
| commit | 57421fdde6b8202f64ff0bdf911e56398fc07853 (patch) | |
| tree | bd97dd6d565dc61239cb8c0667007d90dcf380f5 | |
| parent | 50475a377af20298fe3f18cd81c261ffe851bcf8 (diff) | |
| download | poky-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.patch | 100 | ||||
| -rw-r--r-- | meta/recipes-devtools/git/git/CVE-2024-50349-0002.patch | 321 | ||||
| -rw-r--r-- | meta/recipes-devtools/git/git/CVE-2024-52006.patch | 165 | ||||
| -rw-r--r-- | meta/recipes-devtools/git/git_2.35.7.bb | 3 |
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 @@ | |||
| 1 | From c903985bf7e772e2d08275c1a95c8a55ab011577 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Johannes Schindelin <johannes.schindelin@gmx.de> | ||
| 3 | Date: Thu, 7 Nov 2024 08:57:52 +0100 | ||
| 4 | Subject: [PATCH] credential_format(): also encode <host>[:<port>] | ||
| 5 | |||
| 6 | An upcoming change wants to sanitize the credential password prompt | ||
| 7 | where a URL is displayed that may potentially come from a `.gitmodules` | ||
| 8 | file. To this end, the `credential_format()` function is employed. | ||
| 9 | |||
| 10 | To sanitize the host name (and optional port) part of the URL, we need a | ||
| 11 | new mode of the `strbuf_add_percentencode()` function because the | ||
| 12 | current mode is both too strict and too lenient: too strict because it | ||
| 13 | encodes `:`, `[` and `]` (which should be left unencoded in | ||
| 14 | `<host>:<port>` and in IPv6 addresses), and too lenient because it does | ||
| 15 | not encode invalid host name characters `/`, `_` and `~`. | ||
| 16 | |||
| 17 | So let's introduce and use a new mode specifically to encode the host | ||
| 18 | name and optional port part of a URI, leaving alpha-numerical | ||
| 19 | characters, periods, colons and brackets alone and encoding all others. | ||
| 20 | |||
| 21 | This only leads to a change of behavior for URLs that contain invalid | ||
| 22 | host names. | ||
| 23 | |||
| 24 | Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> | ||
| 25 | |||
| 26 | Upstream-Status: Backport [https://github.com/git/git/commit/c903985bf7e772e2d08275c1a95c8a55ab011577] | ||
| 27 | CVE: CVE-2024-50349 | ||
| 28 | Signed-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 | |||
| 36 | diff --git a/credential.c b/credential.c | ||
| 37 | index 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); | ||
| 50 | diff --git a/strbuf.c b/strbuf.c | ||
| 51 | index 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); | ||
| 65 | diff --git a/strbuf.h b/strbuf.h | ||
| 66 | index 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 | ||
| 77 | diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh | ||
| 78 | index 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 @@ | |||
| 1 | From 7725b8100ffbbff2750ee4d61a0fcc1f53a086e8 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Johannes Schindelin <johannes.schindelin@gmx.de> | ||
| 3 | Date: Wed, 30 Oct 2024 13:26:10 +0100 | ||
| 4 | Subject: [PATCH] credential: sanitize the user prompt | ||
| 5 | |||
| 6 | When asking the user interactively for credentials, we want to avoid | ||
| 7 | misleading them e.g. via control sequences that pretend that the URL | ||
| 8 | targets a trusted host when it does not. | ||
| 9 | |||
| 10 | While Git learned, over the course of the preceding commits, to disallow | ||
| 11 | URLs containing URL-encoded control characters by default, credential | ||
| 12 | helpers are still allowed to specify values very freely (apart from Line | ||
| 13 | Feed and NUL characters, anything is allowed), and this would allow, | ||
| 14 | say, a username containing control characters to be specified that would | ||
| 15 | then be displayed in the interactive terminal prompt asking the user for | ||
| 16 | the password, potentially sending those control characters directly to | ||
| 17 | the terminal. This is undesirable because control characters can be used | ||
| 18 | to mislead users to divulge secret information to untrusted sites. | ||
| 19 | |||
| 20 | To prevent such an attack vector, let's add a `git_prompt()` that forces | ||
| 21 | the displayed text to be sanitized, i.e. displaying question marks | ||
| 22 | instead of control characters. | ||
| 23 | |||
| 24 | Note: 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 | ||
| 26 | reason for that: this string specifies a user name, not a | ||
| 27 | <username>@<hostname> combination! In the context of t5541, the actual | ||
| 28 | combination looks like this: `user%40@127.0.0.1:5541`. Therefore, these | ||
| 29 | string replacements document a net improvement introduced by this | ||
| 30 | commit, as `user@host@127.0.0.1` could have left readers wondering where | ||
| 31 | the user name ends and where the host name begins. | ||
| 32 | |||
| 33 | Hinted-at-by: Jeff King <peff@peff.net> | ||
| 34 | Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> | ||
| 35 | |||
| 36 | Upstream-Status: Backport [https://github.com/git/git/commit/7725b8100ffbbff2750ee4d61a0fcc1f53a086e8] | ||
| 37 | CVE: CVE-2024-50349 | ||
| 38 | Signed-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 | |||
| 49 | diff --git a/Documentation/config/credential.txt b/Documentation/config/credential.txt | ||
| 50 | index 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 | ||
| 66 | diff --git a/credential.c b/credential.c | ||
| 67 | index 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 | ||
| 91 | diff --git a/credential.h b/credential.h | ||
| 92 | index 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. */ | ||
| 113 | diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh | ||
| 114 | index 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 | ||
| 149 | diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh | ||
| 150 | index 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 | |||
| 180 | diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh | ||
| 181 | index 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' ' | ||
| 244 | diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh | ||
| 245 | index 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 | -- | ||
| 320 | 2.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 @@ | |||
| 1 | From b01b9b81d36759cdcd07305e78765199e1bc2060 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Johannes Schindelin <johannes.schindelin@gmx.de> | ||
| 3 | Date: Mon, 4 Nov 2024 14:48:22 +0100 | ||
| 4 | Subject: [PATCH] credential: disallow Carriage Returns in the protocol by | ||
| 5 | default | ||
| 6 | |||
| 7 | While Git has documented that the credential protocol is line-based, | ||
| 8 | with newlines as terminators, the exact shape of a newline has not been | ||
| 9 | documented. | ||
| 10 | |||
| 11 | From Git's perspective, which is firmly rooted in the Linux ecosystem, | ||
| 12 | it is clear that "a newline" means a Line Feed character. | ||
| 13 | |||
| 14 | However, even Git's credential protocol respects Windows line endings | ||
| 15 | (a Carriage Return character followed by a Line Feed character, "CR/LF") | ||
| 16 | by virtue of using `strbuf_getline()`. | ||
| 17 | |||
| 18 | There is a third category of line endings that has been used originally | ||
| 19 | by MacOS, and that is respected by the default line readers of .NET and | ||
| 20 | node.js: bare Carriage Returns. | ||
| 21 | |||
| 22 | Git cannot handle those, and what is worse: Git's remedy against | ||
| 23 | CVE-2020-5260 does not catch when credential helpers are used that | ||
| 24 | interpret bare Carriage Returns as newlines. | ||
| 25 | |||
| 26 | Git Credential Manager addressed this as CVE-2024-50338, but other | ||
| 27 | credential helpers may still be vulnerable. So let's not only disallow | ||
| 28 | Line Feed characters as part of the values in the credential protocol, | ||
| 29 | but also disallow Carriage Return characters. | ||
| 30 | |||
| 31 | In the unlikely event that a credential helper relies on Carriage | ||
| 32 | Returns in the protocol, introduce an escape hatch via the | ||
| 33 | `credential.protectProtocol` config setting. | ||
| 34 | |||
| 35 | This addresses CVE-2024-52006. | ||
| 36 | |||
| 37 | Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> | ||
| 38 | |||
| 39 | Upstream-Status: Backport [https://github.com/git/git/commit/b01b9b81d36759cdcd07305e78765199e1bc2060] | ||
| 40 | CVE: CVE-2024-52006 | ||
| 41 | Signed-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 | |||
| 49 | diff --git a/Documentation/config/credential.txt b/Documentation/config/credential.txt | ||
| 50 | index 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 | ||
| 65 | diff --git a/credential.c b/credential.c | ||
| 66 | index 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, | ||
| 114 | diff --git a/credential.h b/credential.h | ||
| 115 | index 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. */ | ||
| 136 | diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh | ||
| 137 | index 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 | -- | ||
| 164 | 2.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 | ||
| 28 | S = "${WORKDIR}/git-${PV}" | 31 | S = "${WORKDIR}/git-${PV}" |
