diff options
Diffstat (limited to 'meta/recipes-devtools/git/files/CVE-2023-22490-2.patch')
-rw-r--r-- | meta/recipes-devtools/git/files/CVE-2023-22490-2.patch | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/meta/recipes-devtools/git/files/CVE-2023-22490-2.patch b/meta/recipes-devtools/git/files/CVE-2023-22490-2.patch new file mode 100644 index 0000000000..0b5b40f827 --- /dev/null +++ b/meta/recipes-devtools/git/files/CVE-2023-22490-2.patch | |||
@@ -0,0 +1,122 @@ | |||
1 | From cf8f6ce02a13f4d1979a53241afbee15a293fce9 Mon Sep 17 00:00:00 2001 | ||
2 | From: Taylor Blau <me@ttaylorr.com> | ||
3 | Date: Tue, 24 Jan 2023 19:43:48 -0500 | ||
4 | Subject: [PATCH 2/3] clone: delay picking a transport until after get_repo_path() | ||
5 | |||
6 | In the previous commit, t5619 demonstrates an issue where two calls to | ||
7 | `get_repo_path()` could trick Git into using its local clone mechanism | ||
8 | in conjunction with a non-local transport. | ||
9 | |||
10 | That sequence is: | ||
11 | |||
12 | - the starting state is that the local path https:/example.com/foo is a | ||
13 | symlink that points to ../../../.git/modules/foo. So it's dangling. | ||
14 | |||
15 | - get_repo_path() sees that no such path exists (because it's | ||
16 | dangling), and thus we do not canonicalize it into an absolute path | ||
17 | |||
18 | - because we're using --separate-git-dir, we create .git/modules/foo. | ||
19 | Now our symlink is no longer dangling! | ||
20 | |||
21 | - we pass the url to transport_get(), which sees it as an https URL. | ||
22 | |||
23 | - we call get_repo_path() again, on the url. This second call was | ||
24 | introduced by f38aa83 (use local cloning if insteadOf makes a | ||
25 | local URL, 2014-07-17). The idea is that we want to pull the url | ||
26 | fresh from the remote.c API, because it will apply any aliases. | ||
27 | |||
28 | And of course now it sees that there is a local file, which is a | ||
29 | mismatch with the transport we already selected. | ||
30 | |||
31 | The issue in the above sequence is calling `transport_get()` before | ||
32 | deciding whether or not the repository is indeed local, and not passing | ||
33 | in an absolute path if it is local. | ||
34 | |||
35 | This is reminiscent of a similar bug report in [1], where it was | ||
36 | suggested to perform the `insteadOf` lookup earlier. Taking that | ||
37 | approach may not be as straightforward, since the intent is to store the | ||
38 | original URL in the config, but to actually fetch from the insteadOf | ||
39 | one, so conflating the two early on is a non-starter. | ||
40 | |||
41 | Note: we pass the path returned by `get_repo_path(remote->url[0])`, | ||
42 | which should be the same as `repo_name` (aside from any `insteadOf` | ||
43 | rewrites). | ||
44 | |||
45 | We *could* pass `absolute_pathdup()` of the same argument, which | ||
46 | 86521ac (Bring local clone's origin URL in line with that of a remote | ||
47 | clone, 2008-09-01) indicates may differ depending on the presence of | ||
48 | ".git/" for a non-bare repo. That matters for forming relative submodule | ||
49 | paths, but doesn't matter for the second call, since we're just feeding | ||
50 | it to the transport code, which is fine either way. | ||
51 | |||
52 | [1]: https://lore.kernel.org/git/CAMoD=Bi41mB3QRn3JdZL-FGHs4w3C2jGpnJB-CqSndO7FMtfzA@mail.gmail.com/ | ||
53 | |||
54 | Signed-off-by: Jeff King <peff@peff.net> | ||
55 | Signed-off-by: Taylor Blau <me@ttaylorr.com> | ||
56 | Signed-off-by: Junio C Hamano <gitster@pobox.com> | ||
57 | |||
58 | Upstream-Status: Backport | ||
59 | [https://github.com/git/git/commit/cf8f6ce02a13f4d1979a53241afbee15a293fce9] | ||
60 | CVE: CVE-2023-22490 | ||
61 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
62 | --- | ||
63 | builtin/clone.c | 8 ++++---- | ||
64 | t/t5619-clone-local-ambiguous-transport.sh | 15 +++++++++++---- | ||
65 | 2 files changed, 15 insertions(+), 8 deletions(-) | ||
66 | |||
67 | diff --git a/builtin/clone.c b/builtin/clone.c | ||
68 | index 53e04b1..b57e703 100644 | ||
69 | --- a/builtin/clone.c | ||
70 | +++ b/builtin/clone.c | ||
71 | @@ -1112,10 +1112,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix) | ||
72 | branch_top.buf); | ||
73 | refspec_append(&remote->fetch, default_refspec.buf); | ||
74 | |||
75 | - transport = transport_get(remote, remote->url[0]); | ||
76 | - transport_set_verbosity(transport, option_verbosity, option_progress); | ||
77 | - transport->family = family; | ||
78 | - | ||
79 | path = get_repo_path(remote->url[0], &is_bundle); | ||
80 | is_local = option_local != 0 && path && !is_bundle; | ||
81 | if (is_local) { | ||
82 | @@ -1135,6 +1131,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix) | ||
83 | } | ||
84 | if (option_local > 0 && !is_local) | ||
85 | warning(_("--local is ignored")); | ||
86 | + | ||
87 | + transport = transport_get(remote, path ? path : remote->url[0]); | ||
88 | + transport_set_verbosity(transport, option_verbosity, option_progress); | ||
89 | + transport->family = family; | ||
90 | transport->cloning = 1; | ||
91 | |||
92 | transport_set_option(transport, TRANS_OPT_KEEP, "yes"); | ||
93 | diff --git a/t/t5619-clone-local-ambiguous-transport.sh b/t/t5619-clone-local-ambiguous-transport.sh | ||
94 | index 7ebd31a..cce62bf 100644 | ||
95 | --- a/t/t5619-clone-local-ambiguous-transport.sh | ||
96 | +++ b/t/t5619-clone-local-ambiguous-transport.sh | ||
97 | @@ -53,11 +53,18 @@ test_expect_success 'setup' ' | ||
98 | git -C "$REPO" update-server-info | ||
99 | ' | ||
100 | |||
101 | -test_expect_failure 'ambiguous transport does not lead to arbitrary file-inclusion' ' | ||
102 | +test_expect_success 'ambiguous transport does not lead to arbitrary file-inclusion' ' | ||
103 | git clone malicious clone && | ||
104 | - git -C clone submodule update --init && | ||
105 | - | ||
106 | - test_path_is_missing clone/.git/modules/sub/objects/secret | ||
107 | + test_must_fail git -C clone submodule update --init 2>err && | ||
108 | + | ||
109 | + test_path_is_missing clone/.git/modules/sub/objects/secret && | ||
110 | + # We would actually expect "transport .file. not allowed" here, | ||
111 | + # but due to quirks of the URL detection in Git, we mis-parse | ||
112 | + # the absolute path as a bogus URL and die before that step. | ||
113 | + # | ||
114 | + # This works for now, and if we ever fix the URL detection, it | ||
115 | + # is OK to change this to detect the transport error. | ||
116 | + grep "protocol .* is not supported" err | ||
117 | ' | ||
118 | |||
119 | test_done | ||
120 | -- | ||
121 | 2.25.1 | ||
122 | |||