Skip to content

Commit 83f1add

Browse files
committed
Sync with Git 2.45.1
* tag 'v2.45.1': (42 commits) Git 2.45.1 Git 2.44.1 Git 2.43.4 Git 2.42.2 Git 2.41.1 Git 2.40.2 Git 2.39.4 fsck: warn about symlink pointing inside a gitdir core.hooksPath: add some protection while cloning init.templateDir: consider this config setting protected clone: prevent hooks from running during a clone Add a helper function to compare file contents init: refactor the template directory discovery into its own function find_hook(): refactor the `STRIP_EXTENSION` logic clone: when symbolic links collide with directories, keep the latter entry: report more colliding paths t5510: verify that D/F confusion cannot lead to an RCE submodule: require the submodule path to contain directories only clone_submodule: avoid using `access()` on directories submodules: submodule paths must not contain symlinks ...
2 parents 3e4a232 + 2c7b491 commit 83f1add

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1283
-86
lines changed

Documentation/RelNotes/2.39.4.txt

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
Git v2.39.4 Release Notes
2+
=========================
3+
4+
This addresses the security issues CVE-2024-32002, CVE-2024-32004,
5+
CVE-2024-32020 and CVE-2024-32021.
6+
7+
This release also backports fixes necessary to let the CI builds pass
8+
successfully.
9+
10+
Fixes since v2.39.3
11+
-------------------
12+
13+
* CVE-2024-32002:
14+
15+
Recursive clones on case-insensitive filesystems that support symbolic
16+
links are susceptible to case confusion that can be exploited to
17+
execute just-cloned code during the clone operation.
18+
19+
* CVE-2024-32004:
20+
21+
Repositories can be configured to execute arbitrary code during local
22+
clones. To address this, the ownership checks introduced in v2.30.3
23+
are now extended to cover cloning local repositories.
24+
25+
* CVE-2024-32020:
26+
27+
Local clones may end up hardlinking files into the target repository's
28+
object database when source and target repository reside on the same
29+
disk. If the source repository is owned by a different user, then
30+
those hardlinked files may be rewritten at any point in time by the
31+
untrusted user.
32+
33+
* CVE-2024-32021:
34+
35+
When cloning a local source repository that contains symlinks via the
36+
filesystem, Git may create hardlinks to arbitrary user-readable files
37+
on the same filesystem as the target repository in the objects/
38+
directory.
39+
40+
* CVE-2024-32465:
41+
42+
It is supposed to be safe to clone untrusted repositories, even those
43+
unpacked from zip archives or tarballs originating from untrusted
44+
sources, but Git can be tricked to run arbitrary code as part of the
45+
clone.
46+
47+
* Defense-in-depth: submodule: require the submodule path to contain
48+
directories only.
49+
50+
* Defense-in-depth: clone: when symbolic links collide with directories, keep
51+
the latter.
52+
53+
* Defense-in-depth: clone: prevent hooks from running during a clone.
54+
55+
* Defense-in-depth: core.hooksPath: add some protection while cloning.
56+
57+
* Defense-in-depth: fsck: warn about symlink pointing inside a gitdir.
58+
59+
* Various fix-ups on HTTP tests.
60+
61+
* Test update.
62+
63+
* HTTP Header redaction code has been adjusted for a newer version of
64+
cURL library that shows its traces differently from earlier
65+
versions.
66+
67+
* Fix was added to work around a regression in libcURL 8.7.0 (which has
68+
already been fixed in their tip of the tree).
69+
70+
* Replace macos-12 used at GitHub CI with macos-13.
71+
72+
* ci(linux-asan/linux-ubsan): let's save some time
73+
74+
* Tests with LSan from time to time seem to emit harmless message that makes
75+
our tests unnecessarily flakey; we work it around by filtering the
76+
uninteresting output.
77+
78+
* Update GitHub Actions jobs to avoid warnings against using deprecated
79+
version of Node.js.

Documentation/RelNotes/2.40.2.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Git v2.40.2 Release Notes
2+
=========================
3+
4+
This release merges up the fix that appears in v2.39.4 to address
5+
the security issues CVE-2024-32002, CVE-2024-32004, CVE-2024-32020,
6+
CVE-2024-32021 and CVE-2024-32465; see the release notes for that
7+
version for details.

Documentation/RelNotes/2.41.1.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Git v2.41.1 Release Notes
2+
=========================
3+
4+
This release merges up the fix that appears in v2.39.4 and v2.40.2
5+
to address the security issues CVE-2024-32002, CVE-2024-32004,
6+
CVE-2024-32020, CVE-2024-32021 and CVE-2024-32465; see the release
7+
notes for these versions for details.

Documentation/RelNotes/2.42.2.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Git v2.42.2 Release Notes
2+
=========================
3+
4+
This release merges up the fix that appears in v2.39.4, v2.40.2
5+
and v2.41.1 to address the security issues CVE-2024-32002,
6+
CVE-2024-32004, CVE-2024-32020, CVE-2024-32021 and CVE-2024-32465;
7+
see the release notes for these versions for details.

Documentation/RelNotes/2.43.4.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Git v2.43.4 Release Notes
2+
=========================
3+
4+
This release merges up the fix that appears in v2.39.4, v2.40.2,
5+
v2.41.1 and v2.42.2 to address the security issues CVE-2024-32002,
6+
CVE-2024-32004, CVE-2024-32020, CVE-2024-32021 and CVE-2024-32465;
7+
see the release notes for these versions for details.

Documentation/RelNotes/2.44.1.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Git v2.44.1 Release Notes
2+
=========================
3+
4+
This release merges up the fix that appears in v2.39.4, v2.40.2,
5+
v2.41.1, v2.42.2 and v2.43.4 to address the security issues
6+
CVE-2024-32002, CVE-2024-32004, CVE-2024-32020, CVE-2024-32021
7+
and CVE-2024-32465; see the release notes for these versions
8+
for details.

Documentation/RelNotes/2.45.1.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Git v2.45.1 Release Notes
2+
=========================
3+
4+
This release merges up the fix that appears in v2.39.4,
5+
v2.40.2, v2.41.1, v2.42.2, v2.43.4 and v2.44.1 to address the
6+
security issues CVE-2024-32002, CVE-2024-32004, CVE-2024-32020,
7+
CVE-2024-32021 and CVE-2024-32465; see the release notes for
8+
these versions for details.

Documentation/fsck-msgids.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,18 @@
164164
`nullSha1`::
165165
(WARN) Tree contains entries pointing to a null sha1.
166166

167+
`symlinkPointsToGitDir`::
168+
(WARN) Symbolic link points inside a gitdir.
169+
170+
`symlinkTargetBlob`::
171+
(ERROR) A non-blob found instead of a symbolic link's target.
172+
173+
`symlinkTargetLength`::
174+
(WARN) Symbolic link target longer than maximum path length.
175+
176+
`symlinkTargetMissing`::
177+
(ERROR) Unable to read symbolic link target's blob.
178+
167179
`treeNotSorted`::
168180
(ERROR) A tree is not properly sorted.
169181

Documentation/git-upload-pack.txt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,37 @@ ENVIRONMENT
5555
admins may need to configure some transports to allow this
5656
variable to be passed. See the discussion in linkgit:git[1].
5757

58+
`GIT_NO_LAZY_FETCH`::
59+
When cloning or fetching from a partial repository (i.e., one
60+
itself cloned with `--filter`), the server-side `upload-pack`
61+
may need to fetch extra objects from its upstream in order to
62+
complete the request. By default, `upload-pack` will refuse to
63+
perform such a lazy fetch, because `git fetch` may run arbitrary
64+
commands specified in configuration and hooks of the source
65+
repository (and `upload-pack` tries to be safe to run even in
66+
untrusted `.git` directories).
67+
+
68+
This is implemented by having `upload-pack` internally set the
69+
`GIT_NO_LAZY_FETCH` variable to `1`. If you want to override it
70+
(because you are fetching from a partial clone, and you are sure
71+
you trust it), you can explicitly set `GIT_NO_LAZY_FETCH` to
72+
`0`.
73+
74+
SECURITY
75+
--------
76+
77+
Most Git commands should not be run in an untrusted `.git` directory
78+
(see the section `SECURITY` in linkgit:git[1]). `upload-pack` tries to
79+
avoid any dangerous configuration options or hooks from the repository
80+
it's serving, making it safe to clone an untrusted directory and run
81+
commands on the resulting clone.
82+
83+
For an extra level of safety, you may be able to run `upload-pack` as an
84+
alternate user. The details will be platform dependent, but on many
85+
systems you can run:
86+
87+
git clone --no-local --upload-pack='sudo -u nobody git-upload-pack' ...
88+
5889
SEE ALSO
5990
--------
6091
linkgit:gitnamespaces[7]

Documentation/git.txt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,37 @@ The index is also capable of storing multiple entries (called "stages")
10671067
for a given pathname. These stages are used to hold the various
10681068
unmerged version of a file when a merge is in progress.
10691069

1070+
SECURITY
1071+
--------
1072+
1073+
Some configuration options and hook files may cause Git to run arbitrary
1074+
shell commands. Because configuration and hooks are not copied using
1075+
`git clone`, it is generally safe to clone remote repositories with
1076+
untrusted content, inspect them with `git log`, and so on.
1077+
1078+
However, it is not safe to run Git commands in a `.git` directory (or
1079+
the working tree that surrounds it) when that `.git` directory itself
1080+
comes from an untrusted source. The commands in its config and hooks
1081+
are executed in the usual way.
1082+
1083+
By default, Git will refuse to run when the repository is owned by
1084+
someone other than the user running the command. See the entry for
1085+
`safe.directory` in linkgit:git-config[1]. While this can help protect
1086+
you in a multi-user environment, note that you can also acquire
1087+
untrusted repositories that are owned by you (for example, if you
1088+
extract a zip file or tarball from an untrusted source). In such cases,
1089+
you'd need to "sanitize" the untrusted repository first.
1090+
1091+
If you have an untrusted `.git` directory, you should first clone it
1092+
with `git clone --no-local` to obtain a clean copy. Git does restrict
1093+
the set of options and hooks that will be run by `upload-pack`, which
1094+
handles the server side of a clone or fetch, but beware that the
1095+
surface area for attack against `upload-pack` is large, so this does
1096+
carry some risk. The safest thing is to serve the repository as an
1097+
unprivileged user (either via linkgit:git-daemon[1], ssh, or using
1098+
other tools to change user ids). See the discussion in the `SECURITY`
1099+
section of linkgit:git-upload-pack[1].
1100+
10701101
FURTHER DOCUMENTATION
10711102
---------------------
10721103

builtin/clone.c

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,20 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
328328
int src_len, dest_len;
329329
struct dir_iterator *iter;
330330
int iter_status;
331-
struct strbuf realpath = STRBUF_INIT;
331+
332+
/*
333+
* Refuse copying directories by default which aren't owned by us. The
334+
* code that performs either the copying or hardlinking is not prepared
335+
* to handle various edge cases where an adversary may for example
336+
* racily swap out files for symlinks. This can cause us to
337+
* inadvertently use the wrong source file.
338+
*
339+
* Furthermore, even if we were prepared to handle such races safely,
340+
* creating hardlinks across user boundaries is an inherently unsafe
341+
* operation as the hardlinked files can be rewritten at will by the
342+
* potentially-untrusted user. We thus refuse to do so by default.
343+
*/
344+
die_upon_dubious_ownership(NULL, NULL, src_repo);
332345

333346
mkdir_if_missing(dest->buf, 0777);
334347

@@ -376,9 +389,27 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
376389
if (unlink(dest->buf) && errno != ENOENT)
377390
die_errno(_("failed to unlink '%s'"), dest->buf);
378391
if (!option_no_hardlinks) {
379-
strbuf_realpath(&realpath, src->buf, 1);
380-
if (!link(realpath.buf, dest->buf))
392+
if (!link(src->buf, dest->buf)) {
393+
struct stat st;
394+
395+
/*
396+
* Sanity-check whether the created hardlink
397+
* actually links to the expected file now. This
398+
* catches time-of-check-time-of-use bugs in
399+
* case the source file was meanwhile swapped.
400+
*/
401+
if (lstat(dest->buf, &st))
402+
die(_("hardlink cannot be checked at '%s'"), dest->buf);
403+
if (st.st_mode != iter->st.st_mode ||
404+
st.st_ino != iter->st.st_ino ||
405+
st.st_dev != iter->st.st_dev ||
406+
st.st_size != iter->st.st_size ||
407+
st.st_uid != iter->st.st_uid ||
408+
st.st_gid != iter->st.st_gid)
409+
die(_("hardlink different from source at '%s'"), dest->buf);
410+
381411
continue;
412+
}
382413
if (option_local > 0)
383414
die_errno(_("failed to create link '%s'"), dest->buf);
384415
option_no_hardlinks = 1;
@@ -391,8 +422,6 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
391422
strbuf_setlen(src, src_len);
392423
die(_("failed to iterate over '%s'"), src->buf);
393424
}
394-
395-
strbuf_release(&realpath);
396425
}
397426

398427
static void clone_local(const char *src_repo, const char *dest_repo)
@@ -937,6 +966,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
937966
int hash_algo;
938967
unsigned int ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN;
939968
const int do_not_override_repo_unix_permissions = -1;
969+
const char *template_dir;
970+
char *template_dir_dup = NULL;
940971

941972
struct transport_ls_refs_options transport_ls_refs_options =
942973
TRANSPORT_LS_REFS_OPTIONS_INIT;
@@ -956,6 +987,13 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
956987
usage_msg_opt(_("You must specify a repository to clone."),
957988
builtin_clone_usage, builtin_clone_options);
958989

990+
xsetenv("GIT_CLONE_PROTECTION_ACTIVE", "true", 0 /* allow user override */);
991+
template_dir = get_template_dir(option_template);
992+
if (*template_dir && !is_absolute_path(template_dir))
993+
template_dir = template_dir_dup =
994+
absolute_pathdup(template_dir);
995+
xsetenv("GIT_CLONE_TEMPLATE_DIR", template_dir, 1);
996+
959997
if (option_depth || option_since || option_not.nr)
960998
deepen = 1;
961999
if (option_single_branch == -1)
@@ -1117,7 +1155,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
11171155
* repository, and reference backends may persist that information into
11181156
* their on-disk data structures.
11191157
*/
1120-
init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN,
1158+
init_db(git_dir, real_git_dir, template_dir, GIT_HASH_UNKNOWN,
11211159
ref_storage_format, NULL,
11221160
do_not_override_repo_unix_permissions, INIT_DB_QUIET | INIT_DB_SKIP_REFDB);
11231161

@@ -1506,6 +1544,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
15061544
free(dir);
15071545
free(path);
15081546
free(repo_to_free);
1547+
free(template_dir_dup);
15091548
junk_mode = JUNK_LEAVE_ALL;
15101549

15111550
transport_ls_refs_options_release(&transport_ls_refs_options);

0 commit comments

Comments
 (0)