summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/git/files/CVE-2023-22490-2.patch
diff options
context:
space:
mode:
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.patch122
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 @@
1From cf8f6ce02a13f4d1979a53241afbee15a293fce9 Mon Sep 17 00:00:00 2001
2From: Taylor Blau <me@ttaylorr.com>
3Date: Tue, 24 Jan 2023 19:43:48 -0500
4Subject: [PATCH 2/3] clone: delay picking a transport until after get_repo_path()
5
6In the previous commit, t5619 demonstrates an issue where two calls to
7`get_repo_path()` could trick Git into using its local clone mechanism
8in conjunction with a non-local transport.
9
10That 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
28And of course now it sees that there is a local file, which is a
29mismatch with the transport we already selected.
30
31The issue in the above sequence is calling `transport_get()` before
32deciding whether or not the repository is indeed local, and not passing
33in an absolute path if it is local.
34
35This is reminiscent of a similar bug report in [1], where it was
36suggested to perform the `insteadOf` lookup earlier. Taking that
37approach may not be as straightforward, since the intent is to store the
38original URL in the config, but to actually fetch from the insteadOf
39one, so conflating the two early on is a non-starter.
40
41Note: we pass the path returned by `get_repo_path(remote->url[0])`,
42which should be the same as `repo_name` (aside from any `insteadOf`
43rewrites).
44
45We *could* pass `absolute_pathdup()` of the same argument, which
4686521ac (Bring local clone's origin URL in line with that of a remote
47clone, 2008-09-01) indicates may differ depending on the presence of
48".git/" for a non-bare repo. That matters for forming relative submodule
49paths, but doesn't matter for the second call, since we're just feeding
50it 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
54Signed-off-by: Jeff King <peff@peff.net>
55Signed-off-by: Taylor Blau <me@ttaylorr.com>
56Signed-off-by: Junio C Hamano <gitster@pobox.com>
57
58Upstream-Status: Backport
59[https://github.com/git/git/commit/cf8f6ce02a13f4d1979a53241afbee15a293fce9]
60CVE: CVE-2023-22490
61Signed-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
67diff --git a/builtin/clone.c b/builtin/clone.c
68index 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");
93diff --git a/t/t5619-clone-local-ambiguous-transport.sh b/t/t5619-clone-local-ambiguous-transport.sh
94index 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--
1212.25.1
122