Skip to content

Commit ac8a1db

Browse files
committed
Sync with 2.34.5
Signed-off-by: Taylor Blau <[email protected]>
2 parents ef374dd + be85cfc commit ac8a1db

File tree

63 files changed

+295
-59
lines changed

Some content is hidden

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

63 files changed

+295
-59
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/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
@@ -310,13 +310,11 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
310310
int src_len, dest_len;
311311
struct dir_iterator *iter;
312312
int iter_status;
313-
unsigned int flags;
314313
struct strbuf realpath = STRBUF_INIT;
315314

316315
mkdir_if_missing(dest->buf, 0777);
317316

318-
flags = DIR_ITERATOR_PEDANTIC | DIR_ITERATOR_FOLLOW_SYMLINKS;
319-
iter = dir_iterator_begin(src->buf, flags);
317+
iter = dir_iterator_begin(src->buf, DIR_ITERATOR_PEDANTIC);
320318

321319
if (!iter)
322320
die_errno(_("failed to start iterator over '%s'"), src->buf);
@@ -332,6 +330,10 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
332330
strbuf_setlen(dest, dest_len);
333331
strbuf_addstr(dest, iter->relative_path);
334332

333+
if (S_ISLNK(iter->st.st_mode))
334+
die(_("symlink '%s' exists, refusing to clone with --local"),
335+
iter->relative_path);
336+
335337
if (S_ISDIR(iter->st.st_mode)) {
336338
mkdir_if_missing(dest->buf, 0777);
337339
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

0 commit comments

Comments
 (0)