Skip to content

Commit f2798aa

Browse files
committed
Sync with 2.36.3
Signed-off-by: Taylor Blau <[email protected]>
2 parents 9a167cb + fcdaa21 commit f2798aa

File tree

71 files changed

+350
-60
lines changed

Some content is hidden

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

71 files changed

+350
-60
lines changed

Documentation/RelNotes/2.30.6.txt

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
Git v2.30.6 Release Notes
2+
=========================
3+
4+
This release addresses the security issues CVE-2022-39253 and
5+
CVE-2022-39260.
6+
7+
Fixes since v2.30.5
8+
-------------------
9+
10+
* CVE-2022-39253:
11+
When relying on the `--local` clone optimization, Git dereferences
12+
symbolic links in the source repository before creating hardlinks
13+
(or copies) of the dereferenced link in the destination repository.
14+
This can lead to surprising behavior where arbitrary files are
15+
present in a repository's `$GIT_DIR` when cloning from a malicious
16+
repository.
17+
18+
Git will no longer dereference symbolic links via the `--local`
19+
clone mechanism, and will instead refuse to clone repositories that
20+
have symbolic links present in the `$GIT_DIR/objects` directory.
21+
22+
Additionally, the value of `protocol.file.allow` is changed to be
23+
"user" by default.
24+
25+
* CVE-2022-39260:
26+
An overly-long command string given to `git shell` can result in
27+
overflow in `split_cmdline()`, leading to arbitrary heap writes and
28+
remote code execution when `git shell` is exposed and the directory
29+
`$HOME/git-shell-commands` exists.
30+
31+
`git shell` is taught to refuse interactive commands that are
32+
longer than 4MiB in size. `split_cmdline()` is hardened to reject
33+
inputs larger than 2GiB.
34+
35+
Credit for finding CVE-2022-39253 goes to Cory Snider of Mirantis. The
36+
fix was authored by Taylor Blau, with help from Johannes Schindelin.
37+
38+
Credit for finding CVE-2022-39260 goes to Kevin Backhouse of GitHub.
39+
The fix was authored by Kevin Backhouse, Jeff King, and Taylor Blau.
40+
41+
42+
Jeff King (2):
43+
shell: add basic tests
44+
shell: limit size of interactive commands
45+
46+
Kevin Backhouse (1):
47+
alias.c: reject too-long cmdline strings in split_cmdline()
48+
49+
Taylor Blau (11):
50+
builtin/clone.c: disallow `--local` clones with symlinks
51+
t/lib-submodule-update.sh: allow local submodules
52+
t/t1NNN: allow local submodules
53+
t/2NNNN: allow local submodules
54+
t/t3NNN: allow local submodules
55+
t/t4NNN: allow local submodules
56+
t/t5NNN: allow local submodules
57+
t/t6NNN: allow local submodules
58+
t/t7NNN: allow local submodules
59+
t/t9NNN: allow local submodules
60+
transport: make `protocol.file.allow` be "user" by default

Documentation/RelNotes/2.31.5.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Git v2.31.5 Release Notes
2+
=========================
3+
4+
This release merges the security fix that appears in v2.30.6; see
5+
the release notes for that version for details.

Documentation/RelNotes/2.32.4.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Git v2.32.4 Release Notes
2+
=========================
3+
4+
This release merges the security fix that appears in v2.30.6; see
5+
the release notes for that version for details.

Documentation/RelNotes/2.33.5.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Git v2.33.5 Release Notes
2+
=========================
3+
4+
This release merges the security fix that appears in v2.30.6; see
5+
the release notes for that version for details.

Documentation/RelNotes/2.34.5.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Git v2.34.5 Release Notes
2+
=========================
3+
4+
This release merges the security fix that appears in v2.30.6; see
5+
the release notes for that version for details.

Documentation/RelNotes/2.35.5.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Git v2.35.5 Release Notes
2+
=========================
3+
4+
This release merges the security fix that appears in v2.30.6; see
5+
the release notes for that version for details.

Documentation/RelNotes/2.36.3.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Git v2.36.3 Release Notes
2+
=========================
3+
4+
This release merges the security fix that appears in v2.30.6; see
5+
the release notes for that version for details.

Documentation/RelNotes/2.37.4.txt

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,45 @@ Git 2.37.4 Release Notes
22
========================
33

44
This primarily is to backport various fixes accumulated on the 'master'
5-
front since 2.37.3.
5+
front since 2.37.3, and also includes the same security fixes as in
6+
v2.30.6.
67

78
Fixes since v2.37.3
89
-------------------
910

11+
* CVE-2022-39253:
12+
When relying on the `--local` clone optimization, Git dereferences
13+
symbolic links in the source repository before creating hardlinks
14+
(or copies) of the dereferenced link in the destination repository.
15+
This can lead to surprising behavior where arbitrary files are
16+
present in a repository's `$GIT_DIR` when cloning from a malicious
17+
repository.
18+
19+
Git will no longer dereference symbolic links via the `--local`
20+
clone mechanism, and will instead refuse to clone repositories that
21+
have symbolic links present in the `$GIT_DIR/objects` directory.
22+
23+
Additionally, the value of `protocol.file.allow` is changed to be
24+
"user" by default.
25+
26+
Credit for finding CVE-2022-39253 goes to Cory Snider of Mirantis.
27+
The fix was authored by Taylor Blau, with help from Johannes
28+
Schindelin.
29+
30+
* CVE-2022-39260:
31+
An overly-long command string given to `git shell` can result in
32+
overflow in `split_cmdline()`, leading to arbitrary heap writes and
33+
remote code execution when `git shell` is exposed and the directory
34+
`$HOME/git-shell-commands` exists.
35+
36+
`git shell` is taught to refuse interactive commands that are
37+
longer than 4MiB in size. `split_cmdline()` is hardened to reject
38+
inputs larger than 2GiB.
39+
40+
Credit for finding CVE-2022-39260 goes to Kevin Backhouse of
41+
GitHub. The fix was authored by Kevin Backhouse, Jeff King, and
42+
Taylor Blau.
43+
1044
* An earlier optimization discarded a tree-object buffer that is
1145
still in use, which has been corrected.
1246

Documentation/config/protocol.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
protocol.allow::
22
If set, provide a user defined default policy for all protocols which
33
don't explicitly have a policy (`protocol.<name>.allow`). By default,
4-
if unset, known-safe protocols (http, https, git, ssh, file) have a
4+
if unset, known-safe protocols (http, https, git, ssh) have a
55
default policy of `always`, known-dangerous protocols (ext) have a
6-
default policy of `never`, and all other protocols have a default
7-
policy of `user`. Supported policies:
6+
default policy of `never`, and all other protocols (including file)
7+
have a default policy of `user`. Supported policies:
88
+
99
--
1010

alias.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,16 @@ void list_aliases(struct string_list *list)
4646

4747
#define SPLIT_CMDLINE_BAD_ENDING 1
4848
#define SPLIT_CMDLINE_UNCLOSED_QUOTE 2
49+
#define SPLIT_CMDLINE_ARGC_OVERFLOW 3
4950
static const char *split_cmdline_errors[] = {
5051
N_("cmdline ends with \\"),
51-
N_("unclosed quote")
52+
N_("unclosed quote"),
53+
N_("too many arguments"),
5254
};
5355

5456
int split_cmdline(char *cmdline, const char ***argv)
5557
{
56-
int src, dst, count = 0, size = 16;
58+
size_t src, dst, count = 0, size = 16;
5759
char quoted = 0;
5860

5961
ALLOC_ARRAY(*argv, size);
@@ -96,6 +98,11 @@ int split_cmdline(char *cmdline, const char ***argv)
9698
return -SPLIT_CMDLINE_UNCLOSED_QUOTE;
9799
}
98100

101+
if (count >= INT_MAX) {
102+
FREE_AND_NULL(*argv);
103+
return -SPLIT_CMDLINE_ARGC_OVERFLOW;
104+
}
105+
99106
ALLOC_GROW(*argv, count + 1, size);
100107
(*argv)[count] = NULL;
101108

builtin/clone.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,13 +316,11 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
316316
int src_len, dest_len;
317317
struct dir_iterator *iter;
318318
int iter_status;
319-
unsigned int flags;
320319
struct strbuf realpath = STRBUF_INIT;
321320

322321
mkdir_if_missing(dest->buf, 0777);
323322

324-
flags = DIR_ITERATOR_PEDANTIC | DIR_ITERATOR_FOLLOW_SYMLINKS;
325-
iter = dir_iterator_begin(src->buf, flags);
323+
iter = dir_iterator_begin(src->buf, DIR_ITERATOR_PEDANTIC);
326324

327325
if (!iter)
328326
die_errno(_("failed to start iterator over '%s'"), src->buf);
@@ -338,6 +336,10 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
338336
strbuf_setlen(dest, dest_len);
339337
strbuf_addstr(dest, iter->relative_path);
340338

339+
if (S_ISLNK(iter->st.st_mode))
340+
die(_("symlink '%s' exists, refusing to clone with --local"),
341+
iter->relative_path);
342+
341343
if (S_ISDIR(iter->st.st_mode)) {
342344
mkdir_if_missing(dest->buf, 0777);
343345
continue;

shell.c

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ static void cd_to_homedir(void)
4747
die("could not chdir to user's home directory");
4848
}
4949

50+
#define MAX_INTERACTIVE_COMMAND (4*1024*1024)
51+
5052
static void run_shell(void)
5153
{
5254
int done = 0;
@@ -67,22 +69,46 @@ static void run_shell(void)
6769
run_command_v_opt(help_argv, RUN_SILENT_EXEC_FAILURE);
6870

6971
do {
70-
struct strbuf line = STRBUF_INIT;
7172
const char *prog;
7273
char *full_cmd;
7374
char *rawargs;
75+
size_t len;
7476
char *split_args;
7577
const char **argv;
7678
int code;
7779
int count;
7880

7981
fprintf(stderr, "git> ");
80-
if (git_read_line_interactively(&line) == EOF) {
82+
83+
/*
84+
* Avoid using a strbuf or git_read_line_interactively() here.
85+
* We don't want to allocate arbitrary amounts of memory on
86+
* behalf of a possibly untrusted client, and we're subject to
87+
* OS limits on command length anyway.
88+
*/
89+
fflush(stdout);
90+
rawargs = xmalloc(MAX_INTERACTIVE_COMMAND);
91+
if (!fgets(rawargs, MAX_INTERACTIVE_COMMAND, stdin)) {
8192
fprintf(stderr, "\n");
82-
strbuf_release(&line);
93+
free(rawargs);
8394
break;
8495
}
85-
rawargs = strbuf_detach(&line, NULL);
96+
len = strlen(rawargs);
97+
98+
/*
99+
* If we truncated due to our input buffer size, reject the
100+
* command. That's better than running bogus input, and
101+
* there's a good chance it's just malicious garbage anyway.
102+
*/
103+
if (len >= MAX_INTERACTIVE_COMMAND - 1)
104+
die("invalid command format: input too long");
105+
106+
if (len > 0 && rawargs[len - 1] == '\n') {
107+
if (--len > 0 && rawargs[len - 1] == '\r')
108+
--len;
109+
rawargs[len] = '\0';
110+
}
111+
86112
split_args = xstrdup(rawargs);
87113
count = split_cmdline(split_args, &argv);
88114
if (count < 0) {

t/lib-submodule-update.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ test_git_directory_exists () {
197197
# the submodule repo if it doesn't exist and configures the most problematic
198198
# settings for diff.ignoreSubmodules.
199199
prolog () {
200+
test_config_global protocol.file.allow always &&
200201
(test -d submodule_update_repo || create_lib_submodule_repo) &&
201202
test_config_global diff.ignoreSubmodules all &&
202203
test_config diff.ignoreSubmodules all

t/t1091-sparse-checkout-builtin.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,8 @@ test_expect_success 'interaction with submodules' '
560560
(
561561
cd super &&
562562
mkdir modules &&
563-
git submodule add ../repo modules/child &&
563+
git -c protocol.file.allow=always \
564+
submodule add ../repo modules/child &&
564565
git add . &&
565566
git commit -m "add submodule" &&
566567
git sparse-checkout init --cone &&

t/t1092-sparse-checkout-compatibility.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,6 +1293,8 @@ test_expect_success 'submodule handling' '
12931293
test_all_match git add modules &&
12941294
test_all_match git commit -m "add modules directory" &&
12951295
1296+
test_config_global protocol.file.allow always &&
1297+
12961298
run_on_all git submodule add "$(pwd)/initial-repo" modules/sub &&
12971299
test_all_match git commit -m "add submodule" &&
12981300

t/t1500-rev-parse.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,8 @@ test_expect_success 'showing the superproject correctly' '
225225
test_commit -C super test_commit &&
226226
test_create_repo sub &&
227227
test_commit -C sub test_commit &&
228-
git -C super submodule add ../sub dir/sub &&
228+
git -c protocol.file.allow=always \
229+
-C super submodule add ../sub dir/sub &&
229230
echo $(pwd)/super >expect &&
230231
git -C super/dir/sub rev-parse --show-superproject-working-tree >out &&
231232
test_cmp expect out &&

t/t2080-parallel-checkout-basics.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ TEST_NO_CREATE_REPO=1
4141
# - m/m (file)
4242
#
4343
test_expect_success 'setup repo for checkout with various types of changes' '
44+
test_config_global protocol.file.allow always &&
45+
4446
git init sub &&
4547
(
4648
cd sub &&
@@ -140,6 +142,7 @@ do
140142
esac
141143

142144
test_expect_success "$mode checkout on clone" '
145+
test_config_global protocol.file.allow always &&
143146
repo=various_${mode}_clone &&
144147
set_checkout_config $workers $threshold &&
145148
test_checkout_workers $expected_workers \

t/t2400-worktree-add.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,7 @@ test_expect_success '"add" should not fail because of another bad worktree' '
665665
'
666666

667667
test_expect_success '"add" with uninitialized submodule, with submodule.recurse unset' '
668+
test_config_global protocol.file.allow always &&
668669
test_create_repo submodule &&
669670
test_commit -C submodule first &&
670671
test_create_repo project &&
@@ -680,6 +681,7 @@ test_expect_success '"add" with uninitialized submodule, with submodule.recurse
680681
'
681682

682683
test_expect_success '"add" with initialized submodule, with submodule.recurse unset' '
684+
test_config_global protocol.file.allow always &&
683685
git -C project-clone submodule update --init &&
684686
git -C project-clone worktree add ../project-4
685687
'

t/t2403-worktree-move.sh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ test_expect_success 'move a repo with uninitialized submodule' '
138138
(
139139
cd withsub &&
140140
test_commit initial &&
141-
git submodule add "$PWD"/.git sub &&
141+
git -c protocol.file.allow=always \
142+
submodule add "$PWD"/.git sub &&
142143
git commit -m withsub &&
143144
git worktree add second HEAD &&
144145
git worktree move second third
@@ -148,7 +149,7 @@ test_expect_success 'move a repo with uninitialized submodule' '
148149
test_expect_success 'not move a repo with initialized submodule' '
149150
(
150151
cd withsub &&
151-
git -C third submodule update &&
152+
git -c protocol.file.allow=always -C third submodule update &&
152153
test_must_fail git worktree move third forth
153154
)
154155
'
@@ -227,6 +228,7 @@ test_expect_success 'remove cleans up .git/worktrees when empty' '
227228
'
228229

229230
test_expect_success 'remove a repo with uninitialized submodule' '
231+
test_config_global protocol.file.allow always &&
230232
(
231233
cd withsub &&
232234
git worktree add to-remove HEAD &&
@@ -235,6 +237,7 @@ test_expect_success 'remove a repo with uninitialized submodule' '
235237
'
236238

237239
test_expect_success 'not remove a repo with initialized submodule' '
240+
test_config_global protocol.file.allow always &&
238241
(
239242
cd withsub &&
240243
git worktree add to-remove HEAD &&

t/t2405-worktree-submodule.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
1010
base_path=$(pwd -P)
1111

1212
test_expect_success 'setup: create origin repos' '
13+
git config --global protocol.file.allow always &&
1314
git init origin/sub &&
1415
test_commit -C origin/sub file1 &&
1516
git init origin/main &&

t/t3200-branch.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ test_expect_success 'deleting checked-out branch from repo that is a submodule'
306306
git init repo1 &&
307307
git init repo1/sub &&
308308
test_commit -C repo1/sub x &&
309+
test_config_global protocol.file.allow always &&
309310
git -C repo1 submodule add ./sub &&
310311
git -C repo1 commit -m "adding sub" &&
311312

0 commit comments

Comments
 (0)