summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/git/git/CVE-2020-11008-4.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/git/git/CVE-2020-11008-4.patch')
-rw-r--r--meta/recipes-devtools/git/git/CVE-2020-11008-4.patch173
1 files changed, 173 insertions, 0 deletions
diff --git a/meta/recipes-devtools/git/git/CVE-2020-11008-4.patch b/meta/recipes-devtools/git/git/CVE-2020-11008-4.patch
new file mode 100644
index 0000000000..14e23466d4
--- /dev/null
+++ b/meta/recipes-devtools/git/git/CVE-2020-11008-4.patch
@@ -0,0 +1,173 @@
1From f8bf7099379990ad974c1ca8f51e1f28bf18cf2a Mon Sep 17 00:00:00 2001
2From: Jeff King <peff@peff.net>
3Date: Sat, 18 Apr 2020 20:50:48 -0700
4Subject: [PATCH 07/12] credential: refuse to operate when missing host or
5 protocol
6
7The credential helper protocol was designed to be very flexible: the
8fields it takes as input are treated as a pattern, and any missing
9fields are taken as wildcards. This allows unusual things like:
10
11 echo protocol=https | git credential reject
12
13to delete all stored https credentials (assuming the helpers themselves
14treat the input that way). But when helpers are invoked automatically by
15Git, this flexibility works against us. If for whatever reason we don't
16have a "host" field, then we'd match _any_ host. When you're filling a
17credential to send to a remote server, this is almost certainly not what
18you want.
19
20Prevent this at the layer that writes to the credential helper. Add a
21check to the credential API that the host and protocol are always passed
22in, and add an assertion to the credential_write function that speaks
23credential helper protocol to be doubly sure.
24
25There are a few ways this can be triggered in practice:
26
27 - the "git credential" command passes along arbitrary credential
28 parameters it reads from stdin.
29
30 - until the previous patch, when the host field of a URL is empty, we
31 would leave it unset (rather than setting it to the empty string)
32
33 - a URL like "example.com/foo.git" is treated by curl as if "http://"
34 was present, but our parser sees it as a non-URL and leaves all
35 fields unset
36
37 - the recent fix for URLs with embedded newlines blanks the URL but
38 otherwise continues. Rather than having the desired effect of
39 looking up no credential at all, many helpers will return _any_
40 credential
41
42Our earlier test for an embedded newline didn't catch this because it
43only checked that the credential was cleared, but didn't configure an
44actual helper. Configuring the "verbatim" helper in the test would show
45that it is invoked (it's obviously a silly helper which doesn't look at
46its input, but the point is that it shouldn't be run at all). Since
47we're switching this case to die(), we don't need to bother with a
48helper. We can see the new behavior just by checking that the operation
49fails.
50
51We'll add new tests covering partial input as well (these can be
52triggered through various means with url-parsing, but it's simpler to
53just check them directly, as we know we are covered even if the url
54parser changes behavior in the future).
55
56[jn: changed to die() instead of logging and showing a manual
57 username/password prompt]
58
59Reported-by: Carlo Arenas <carenas@gmail.com>
60Signed-off-by: Jeff King <peff@peff.net>
61Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
62
63Upstream-Status: Backport
64CVE: CVE-2020-11008 (4)
65Signed-off-by: Li Zhou <li.zhou@windriver.com>
66---
67 credential.c | 20 ++++++++++++++------
68 t/t0300-credentials.sh | 34 ++++++++++++++++++++++++++--------
69 2 files changed, 40 insertions(+), 14 deletions(-)
70
71diff --git a/credential.c b/credential.c
72index f2413ce..e08ed84 100644
73--- a/credential.c
74+++ b/credential.c
75@@ -89,6 +89,11 @@ static int proto_is_http(const char *s)
76
77 static void credential_apply_config(struct credential *c)
78 {
79+ if (!c->host)
80+ die(_("refusing to work with credential missing host field"));
81+ if (!c->protocol)
82+ die(_("refusing to work with credential missing protocol field"));
83+
84 if (c->configured)
85 return;
86 git_config(credential_config_callback, c);
87@@ -191,8 +196,11 @@ int credential_read(struct credential *c, FILE *fp)
88 return 0;
89 }
90
91-static void credential_write_item(FILE *fp, const char *key, const char *value)
92+static void credential_write_item(FILE *fp, const char *key, const char *value,
93+ int required)
94 {
95+ if (!value && required)
96+ BUG("credential value for %s is missing", key);
97 if (!value)
98 return;
99 if (strchr(value, '\n'))
100@@ -202,11 +210,11 @@ static void credential_write_item(FILE *fp, const char *key, const char *value)
101
102 void credential_write(const struct credential *c, FILE *fp)
103 {
104- credential_write_item(fp, "protocol", c->protocol);
105- credential_write_item(fp, "host", c->host);
106- credential_write_item(fp, "path", c->path);
107- credential_write_item(fp, "username", c->username);
108- credential_write_item(fp, "password", c->password);
109+ credential_write_item(fp, "protocol", c->protocol, 1);
110+ credential_write_item(fp, "host", c->host, 1);
111+ credential_write_item(fp, "path", c->path, 0);
112+ credential_write_item(fp, "username", c->username, 0);
113+ credential_write_item(fp, "password", c->password, 0);
114 }
115
116 static int run_credential_helper(struct credential *c,
117diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh
118index 1c1010b..646f845 100755
119--- a/t/t0300-credentials.sh
120+++ b/t/t0300-credentials.sh
121@@ -400,18 +400,16 @@ test_expect_success 'empty helper spec resets helper list' '
122 EOF
123 '
124
125-test_expect_success 'url parser ignores embedded newlines' '
126- check fill <<-EOF
127+test_expect_success 'url parser rejects embedded newlines' '
128+ test_must_fail git credential fill 2>stderr <<-\EOF &&
129 url=https://one.example.com?%0ahost=two.example.com/
130- --
131- username=askpass-username
132- password=askpass-password
133- --
134+ EOF
135+ cat >expect <<-\EOF &&
136 warning: url contains a newline in its host component: https://one.example.com?%0ahost=two.example.com/
137 warning: skipping credential lookup for url: https://one.example.com?%0ahost=two.example.com/
138- askpass: Username:
139- askpass: Password:
140+ fatal: refusing to work with credential missing host field
141 EOF
142+ test_i18ncmp expect stderr
143 '
144
145 test_expect_success 'host-less URLs are parsed as empty host' '
146@@ -431,4 +429,24 @@ test_expect_success 'host-less URLs are parsed as empty host' '
147 EOF
148 '
149
150+test_expect_success 'credential system refuses to work with missing host' '
151+ test_must_fail git credential fill 2>stderr <<-\EOF &&
152+ protocol=http
153+ EOF
154+ cat >expect <<-\EOF &&
155+ fatal: refusing to work with credential missing host field
156+ EOF
157+ test_i18ncmp expect stderr
158+'
159+
160+test_expect_success 'credential system refuses to work with missing protocol' '
161+ test_must_fail git credential fill 2>stderr <<-\EOF &&
162+ host=example.com
163+ EOF
164+ cat >expect <<-\EOF &&
165+ fatal: refusing to work with credential missing protocol field
166+ EOF
167+ test_i18ncmp expect stderr
168+'
169+
170 test_done
171--
1721.9.1
173