Skip to content

Commit

Permalink
Merge the previously-embargoed v2.40.1 patches (#4412)
Browse files Browse the repository at this point in the history
With every embargoed release, we have to deal with deviating commit
histories, one public, the other one embargoed.

In preparation for v2.41.0-rc0 (which is [scheduled for beginning of
next week](https://gh.io/gitCal)), let's reconcile the `main` branch
with the v2.40.1 patches.
  • Loading branch information
dscho authored May 10, 2023
2 parents bc3743d + 9933300 commit 09c6955
Show file tree
Hide file tree
Showing 20 changed files with 214 additions and 20 deletions.
43 changes: 43 additions & 0 deletions Documentation/RelNotes/2.30.9.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
Git v2.30.9 Release Notes
=========================

This release addresses the security issues CVE-2023-25652,
CVE-2023-25815, and CVE-2023-29007.


Fixes since v2.30.8
-------------------

* CVE-2023-25652:

By feeding specially crafted input to `git apply --reject`, a
path outside the working tree can be overwritten with partially
controlled contents (corresponding to the rejected hunk(s) from
the given patch).

* CVE-2023-25815:

When Git is compiled with runtime prefix support and runs without
translated messages, it still used the gettext machinery to
display messages, which subsequently potentially looked for
translated messages in unexpected places. This allowed for
malicious placement of crafted messages.

* CVE-2023-29007:

When renaming or deleting a section from a configuration file,
certain malicious configuration values may be misinterpreted as
the beginning of a new configuration section, leading to arbitrary
configuration injection.

Credit for finding CVE-2023-25652 goes to Ry0taK, and the fix was
developed by Taylor Blau, Junio C Hamano and Johannes Schindelin,
with the help of Linus Torvalds.

Credit for finding CVE-2023-25815 goes to Maxime Escourbiac and
Yassine BENGANA of Michelin, and the fix was developed by Johannes
Schindelin.

Credit for finding CVE-2023-29007 goes to André Baptista and Vítor Pinho
of Ethiack, and the fix was developed by Taylor Blau, and Johannes
Schindelin, with help from Jeff King, and Patrick Steinhardt.
6 changes: 6 additions & 0 deletions Documentation/RelNotes/2.31.8.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Git v2.31.8 Release Notes
=========================

This release merges the fixes that appear in v2.30.9 to address the
security issues CVE-2023-25652, CVE-2023-25815, and CVE-2023-29007;
see the release notes for that version for details.
7 changes: 7 additions & 0 deletions Documentation/RelNotes/2.32.7.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Git v2.32.7 Release Notes
=========================

This release merges the fixes that appear in v2.30.9 and v2.31.8 to
address the security issues CVE-2023-25652, CVE-2023-25815, and
CVE-2023-29007; see the release notes for these versions for
details.
7 changes: 7 additions & 0 deletions Documentation/RelNotes/2.33.8.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Git v2.33.8 Release Notes
=========================

This release merges the fixes that appear in v2.30.9, v2.31.8 and
v2.32.7 to address the security issues CVE-2023-25652,
CVE-2023-25815, and CVE-2023-29007; see the release notes for these
versions for details.
7 changes: 7 additions & 0 deletions Documentation/RelNotes/2.34.8.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Git v2.34.8 Release Notes
=========================

This release merges the fixes that appear in v2.30.9, v2.31.8,
v2.32.7 and v2.33.8 to address the security issues CVE-2023-25652,
CVE-2023-25815, and CVE-2023-29007; see the release notes for these
versions for details.
7 changes: 7 additions & 0 deletions Documentation/RelNotes/2.35.8.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Git v2.35.8 Release Notes
=========================

This release merges the fixes that appear in v2.30.9, v2.31.8,
v2.32.7, v2.33.8 and v2.34.8 to address the security issues
CVE-2023-25652, CVE-2023-25815, and CVE-2023-29007; see the release
notes for these versions for details.
7 changes: 7 additions & 0 deletions Documentation/RelNotes/2.36.6.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Git v2.36.6 Release Notes
=========================

This release merges the fixes that appear in v2.30.9, v2.31.8,
v2.32.7, v2.33.8, v2.34.8 and v2.35.8 to address the security issues
CVE-2023-25652, CVS-2023-25815, and CVE-2023-29007; see the release
notes for these versions for details.
7 changes: 7 additions & 0 deletions Documentation/RelNotes/2.37.7.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Git v2.37.7 Release Notes
=========================

This release merges up the fix that appears in v2.30.9, v2.31.8,
v2.32.7, v2.33.8, v2.34.8, v2.35.8 and v2.36.6 to address the
security issues CVE-2023-25652, CVE-2023-25815, and CVE-2023-29007;
see the release notes for these versions for details.
8 changes: 8 additions & 0 deletions Documentation/RelNotes/2.38.5.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Git v2.38.5 Release Notes
=========================

This release merges up the fix that appears in v2.30.9, v2.31.8,
v2.32.7, v2.33.8, v2.34.8, v2.35.8, v2.36.6 and v2.37.7 to address
the security issues CVE-2023-25652, CVE-2023-25815, and
CVE-2023-29007; see the release notes for these versions for
details.
12 changes: 9 additions & 3 deletions Documentation/RelNotes/2.39.3.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
Git v2.39.3 Release Notes
=========================

This release is primarily to merge fixes accumulated on the 'master'
front to prepare for 2.40 release that are still relevant to 2.39.x
maintenance track.
This release merges up the fix that appears in v2.30.9, v2.31.8,
v2.32.7, v2.33.8, v2.34.8, v2.35.8, v2.36.6, v2.37.7 and v2.38.5 to
address the security issues CVE-2023-25652, CVE-2023-25815, and
CVE-2023-29007; see the release notes for these versions for
details.

This release also merges fixes that have accumulated on the 'master'
front to prepare for the 2.40 release that are still relevant to
2.39.x maintenance track.

Fixes since v2.39.2
-------------------
Expand Down
8 changes: 8 additions & 0 deletions Documentation/RelNotes/2.40.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Git v2.40.1 Release Notes
=========================

This release merges up the fix that appears in v2.30.9, v2.31.8,
v2.32.7, v2.33.8, v2.34.8, v2.35.8, v2.36.6, v2.37.7, v2.38.5
and v2.39.3 to address the security issues CVE-2023-25652,
CVE-2023-25815, and CVE-2023-29007; see the release notes for these
versions for details.
2 changes: 1 addition & 1 deletion GIT-VERSION-GEN
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/sh

GVF=GIT-VERSION-FILE
DEF_VER=v2.40.0
DEF_VER=v2.40.1

LF='
'
Expand Down
2 changes: 1 addition & 1 deletion RelNotes
14 changes: 12 additions & 2 deletions apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -4576,7 +4576,7 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch)
FILE *rej;
char namebuf[PATH_MAX];
struct fragment *frag;
int cnt = 0;
int fd, cnt = 0;
struct strbuf sb = STRBUF_INIT;

for (cnt = 0, frag = patch->fragments; frag; frag = frag->next) {
Expand Down Expand Up @@ -4616,7 +4616,17 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch)
memcpy(namebuf, patch->new_name, cnt);
memcpy(namebuf + cnt, ".rej", 5);

rej = fopen(namebuf, "w");
fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666);
if (fd < 0) {
if (errno != EEXIST)
return error_errno(_("cannot open %s"), namebuf);
if (unlink(namebuf))
return error_errno(_("cannot unlink '%s'"), namebuf);
fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666);
if (fd < 0)
return error_errno(_("cannot open %s"), namebuf);
}
rej = fdopen(fd, "w");
if (!rej)
return error_errno(_("cannot open %s"), namebuf);

Expand Down
36 changes: 25 additions & 11 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -3487,9 +3487,10 @@ void git_config_set_multivar(const char *key, const char *value,
flags);
}

static int section_name_match (const char *buf, const char *name)
static size_t section_name_match (const char *buf, const char *name)
{
int i = 0, j = 0, dot = 0;
size_t i = 0, j = 0;
int dot = 0;
if (buf[i] != '[')
return 0;
for (i = 1; buf[i] && buf[i] != ']'; i++) {
Expand Down Expand Up @@ -3542,6 +3543,8 @@ static int section_name_is_ok(const char *name)
return 1;
}

#define GIT_CONFIG_MAX_LINE_LEN (512 * 1024)

/* if new_name == NULL, the section is removed instead */
static int git_config_copy_or_rename_section_in_file(const char *config_filename,
const char *old_name,
Expand All @@ -3551,11 +3554,12 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
char *filename_buf = NULL;
struct lock_file lock = LOCK_INIT;
int out_fd;
char buf[1024];
struct strbuf buf = STRBUF_INIT;
FILE *config_file = NULL;
struct stat st;
struct strbuf copystr = STRBUF_INIT;
struct config_store_data store;
uint32_t line_nr = 0;

memset(&store, 0, sizeof(store));

Expand Down Expand Up @@ -3592,16 +3596,25 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
goto out;
}

while (fgets(buf, sizeof(buf), config_file)) {
unsigned i;
int length;
while (!strbuf_getwholeline(&buf, config_file, '\n')) {
size_t i, length;
int is_section = 0;
char *output = buf;
for (i = 0; buf[i] && isspace(buf[i]); i++)
char *output = buf.buf;

line_nr++;

if (buf.len >= GIT_CONFIG_MAX_LINE_LEN) {
ret = error(_("refusing to work with overly long line "
"in '%s' on line %"PRIuMAX),
config_filename, (uintmax_t)line_nr);
goto out;
}

for (i = 0; buf.buf[i] && isspace(buf.buf[i]); i++)
; /* do nothing */
if (buf[i] == '[') {
if (buf.buf[i] == '[') {
/* it's a section */
int offset;
size_t offset;
is_section = 1;

/*
Expand All @@ -3618,7 +3631,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
strbuf_reset(&copystr);
}

offset = section_name_match(&buf[i], old_name);
offset = section_name_match(&buf.buf[i], old_name);
if (offset > 0) {
ret++;
if (!new_name) {
Expand Down Expand Up @@ -3693,6 +3706,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
out_no_rollback:
free(filename_buf);
config_store_data_clear(&store);
strbuf_release(&buf);
return ret;
}

Expand Down
4 changes: 4 additions & 0 deletions gettext.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ static void init_gettext_charset(const char *domain)
setlocale(LC_CTYPE, "C");
}

int git_gettext_enabled = 0;

void git_setup_gettext(void)
{
const char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT);
Expand All @@ -119,6 +121,8 @@ void git_setup_gettext(void)
init_gettext_charset("git");
textdomain("git");

git_gettext_enabled = 1;

free(p);
}

Expand Down
6 changes: 6 additions & 0 deletions gettext.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@
#define FORMAT_PRESERVING(n) __attribute__((format_arg(n)))

#ifndef NO_GETTEXT
extern int git_gettext_enabled;
void git_setup_gettext(void);
int gettext_width(const char *s);
#else
#define git_gettext_enabled (0)
static inline void git_setup_gettext(void)
{
}
Expand All @@ -45,12 +47,16 @@ static inline FORMAT_PRESERVING(1) const char *_(const char *msgid)
{
if (!*msgid)
return "";
if (!git_gettext_enabled)
return msgid;
return gettext(msgid);
}

static inline FORMAT_PRESERVING(1) FORMAT_PRESERVING(2)
const char *Q_(const char *msgid, const char *plu, unsigned long n)
{
if (!git_gettext_enabled)
return n == 1 ? msgid : plu;
return ngettext(msgid, plu, n);
}

Expand Down
6 changes: 4 additions & 2 deletions t/t0060-path-utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,10 @@ test_expect_success SYMLINKS 'real path works on symlinks' '

test_expect_success MINGW 'real path works near drive root' '
# we need a non-existing path at the drive root; simply skip if C:/xyz exists
test -e C:/xyz ||
test C:/xyz = $(test-tool path-utils real_path C:/xyz)
if test ! -e C:/xyz
then
test C:/xyz = $(test-tool path-utils real_path C:/xyz)
fi
'

test_expect_success SYMLINKS 'prefix_path works with absolute paths to work tree symlinks' '
Expand Down
30 changes: 30 additions & 0 deletions t/t1300-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,36 @@ test_expect_success 'renaming to bogus section is rejected' '
test_must_fail git config --rename-section branch.zwei "bogus name"
'

test_expect_success 'renaming a section with a long line' '
{
printf "[b]\\n" &&
printf " c = d %1024s [a] e = f\\n" " " &&
printf "[a] g = h\\n"
} >y &&
git config -f y --rename-section a xyz &&
test_must_fail git config -f y b.e
'

test_expect_success 'renaming an embedded section with a long line' '
{
printf "[b]\\n" &&
printf " c = d %1024s [a] [foo] e = f\\n" " " &&
printf "[a] g = h\\n"
} >y &&
git config -f y --rename-section a xyz &&
test_must_fail git config -f y foo.e
'

test_expect_success 'renaming a section with an overly-long line' '
{
printf "[b]\\n" &&
printf " c = d %525000s e" " " &&
printf "[a] g = h\\n"
} >y &&
test_must_fail git config -f y --rename-section a xyz 2>err &&
grep "refusing to work with overly long line in .y. on line 2" err
'

cat >> .git/config << EOF
[branch "zwei"] a = 1 [branch "vier"]
EOF
Expand Down
15 changes: 15 additions & 0 deletions t/t4115-apply-symlink.sh
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,19 @@ test_expect_success SYMLINKS 'symlink escape when deleting file' '
test_path_is_file .git/delete-me
'

test_expect_success SYMLINKS '--reject removes .rej symlink if it exists' '
test_when_finished "git reset --hard && git clean -dfx" &&
test_commit file &&
echo modified >file.t &&
git diff -- file.t >patch &&
echo modified-again >file.t &&
ln -s foo file.t.rej &&
test_must_fail git apply patch --reject 2>err &&
test_i18ngrep "Rejected hunk" err &&
test_path_is_missing foo &&
test_path_is_file file.t.rej
'

test_done

0 comments on commit 09c6955

Please sign in to comment.