summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2023-03-11 19:58:19 (GMT)
committerJohannes Schindelin <johannes.schindelin@gmx.de>2023-04-17 19:15:59 (GMT)
commit8cd052ea53b0e125e02a844bf728174a81da60df (patch)
treee064fc322f6a4a34a11ba53d7bc0e1da56b9527e
parent8453685d0437bd5ffc25f0bd3b5b07b12225119b (diff)
parentabcb63fb70a69956a892fa830f3866098797787c (diff)
downloadgit-8cd052ea53b0e125e02a844bf728174a81da60df.zip
git-8cd052ea53b0e125e02a844bf728174a81da60df.tar.gz
git-8cd052ea53b0e125e02a844bf728174a81da60df.tar.bz2
Sync with 2.34.8
* maint-2.34: (28 commits) Git 2.34.8 Git 2.33.8 Git 2.32.7 Git 2.31.8 tests: avoid using `test_i18ncmp` Git 2.30.9 gettext: avoid using gettext if the locale dir is not present apply --reject: overwrite existing `.rej` symlink if it exists http.c: clear the 'finished' member once we are done with it clone.c: avoid "exceeds maximum object size" error with GCC v12.x range-diff: use ssize_t for parsed "len" in read_patches() range-diff: handle unterminated lines in read_patches() range-diff: drop useless "offset" variable from read_patches() t5604: GETTEXT_POISON fix, conclusion t5604: GETTEXT_POISON fix, part 1 t5619: GETTEXT_POISON fix t0003: GETTEXT_POISON fix, conclusion t0003: GETTEXT_POISON fix, part 1 t0033: GETTEXT_POISON fix http: support CURLOPT_PROTOCOLS_STR http: prefer CURLOPT_SEEKFUNCTION to CURLOPT_IOCTLFUNCTION ...
-rw-r--r--.github/workflows/main.yml6
-rw-r--r--Documentation/RelNotes/2.30.9.txt43
-rw-r--r--Documentation/RelNotes/2.31.8.txt6
-rw-r--r--Documentation/RelNotes/2.32.7.txt7
-rw-r--r--Documentation/RelNotes/2.33.8.txt7
-rw-r--r--Documentation/RelNotes/2.34.8.txt7
-rw-r--r--apply.c14
-rwxr-xr-xci/install-dependencies.sh26
-rwxr-xr-xci/lib.sh9
-rw-r--r--compat/nedmalloc/nedmalloc.c1
-rw-r--r--compat/win32/syslog.c2
-rw-r--r--config.c36
-rw-r--r--dir.c9
-rw-r--r--gettext.c4
-rw-r--r--gettext.h6
-rw-r--r--http.c26
-rwxr-xr-xt/t0033-safe-directory.sh2
-rwxr-xr-xt/t1300-config.sh30
-rwxr-xr-xt/t4115-apply-symlink.sh15
19 files changed, 221 insertions, 35 deletions
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index c35200d..352772e 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -232,12 +232,12 @@ jobs:
- jobname: linux-gcc
cc: gcc
cc_package: gcc-8
- pool: ubuntu-latest
+ pool: ubuntu-20.04
- jobname: linux-TEST-vars
cc: gcc
os: ubuntu
cc_package: gcc-8
- pool: ubuntu-latest
+ pool: ubuntu-20.04
- jobname: osx-clang
cc: clang
pool: macos-latest
@@ -305,7 +305,7 @@ jobs:
if: needs.ci-config.outputs.enabled == 'yes'
env:
jobname: StaticAnalysis
- runs-on: ubuntu-18.04
+ runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- run: ci/install-dependencies.sh
diff --git a/Documentation/RelNotes/2.30.9.txt b/Documentation/RelNotes/2.30.9.txt
new file mode 100644
index 0000000..708d626
--- /dev/null
+++ b/Documentation/RelNotes/2.30.9.txt
@@ -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.
diff --git a/Documentation/RelNotes/2.31.8.txt b/Documentation/RelNotes/2.31.8.txt
new file mode 100644
index 0000000..0aa3080
--- /dev/null
+++ b/Documentation/RelNotes/2.31.8.txt
@@ -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.
diff --git a/Documentation/RelNotes/2.32.7.txt b/Documentation/RelNotes/2.32.7.txt
new file mode 100644
index 0000000..7bb3538
--- /dev/null
+++ b/Documentation/RelNotes/2.32.7.txt
@@ -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.
diff --git a/Documentation/RelNotes/2.33.8.txt b/Documentation/RelNotes/2.33.8.txt
new file mode 100644
index 0000000..d8cf4c7
--- /dev/null
+++ b/Documentation/RelNotes/2.33.8.txt
@@ -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.
diff --git a/Documentation/RelNotes/2.34.8.txt b/Documentation/RelNotes/2.34.8.txt
new file mode 100644
index 0000000..2b5bd7d
--- /dev/null
+++ b/Documentation/RelNotes/2.34.8.txt
@@ -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.
diff --git a/apply.c b/apply.c
index fc6f484..47f2686 100644
--- a/apply.c
+++ b/apply.c
@@ -4584,7 +4584,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) {
@@ -4624,7 +4624,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);
diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh
index dbcebad..df6c617 100755
--- a/ci/install-dependencies.sh
+++ b/ci/install-dependencies.sh
@@ -5,17 +5,17 @@
. ${0%/*}/lib.sh
-P4WHENCE=http://filehost.perforce.com/perforce/r$LINUX_P4_VERSION
+P4WHENCE=https://cdist2.perforce.com/perforce/r21.2
LFSWHENCE=https://github.com/github/git-lfs/releases/download/v$LINUX_GIT_LFS_VERSION
UBUNTU_COMMON_PKGS="make libssl-dev libcurl4-openssl-dev libexpat-dev
tcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl
libemail-valid-perl libio-socket-ssl-perl libnet-smtp-ssl-perl"
case "$runs_on_pool" in
-ubuntu-latest)
+ubuntu-*)
sudo apt-get -q update
sudo apt-get -q -y install language-pack-is libsvn-perl apache2 \
- $UBUNTU_COMMON_PKGS $CC_PACKAGE
+ $UBUNTU_COMMON_PKGS $PYTHON_PACKAGE
mkdir --parents "$P4_PATH"
pushd "$P4_PATH"
wget --quiet "$P4WHENCE/bin.linux26x86_64/p4d"
@@ -37,13 +37,15 @@ macos-latest)
test -z "$BREW_INSTALL_PACKAGES" ||
brew install $BREW_INSTALL_PACKAGES
brew link --force gettext
- brew install --cask --no-quarantine perforce || {
- # Update the definitions and try again
- cask_repo="$(brew --repository)"/Library/Taps/homebrew/homebrew-cask &&
- git -C "$cask_repo" pull --no-stat --ff-only &&
- brew install --cask --no-quarantine perforce
- } ||
- brew install homebrew/cask/perforce
+ mkdir -p $HOME/bin
+ (
+ cd $HOME/bin
+ wget -q "$P4WHENCE/bin.macosx1015x86_64/helix-core-server.tgz" &&
+ tar -xf helix-core-server.tgz &&
+ sudo xattr -d com.apple.quarantine p4 p4d 2>/dev/null || true
+ )
+ PATH="$PATH:${HOME}/bin"
+ export PATH
if test -n "$CC_PACKAGE"
then
@@ -81,9 +83,9 @@ esac
if type p4d >/dev/null && type p4 >/dev/null
then
echo "$(tput setaf 6)Perforce Server Version$(tput sgr0)"
- p4d -V | grep Rev.
+ p4d -V
echo "$(tput setaf 6)Perforce Client Version$(tput sgr0)"
- p4 -V | grep Rev.
+ p4 -V
fi
if type git-lfs >/dev/null
then
diff --git a/ci/lib.sh b/ci/lib.sh
index 9d28ab5..5e01a92 100755
--- a/ci/lib.sh
+++ b/ci/lib.sh
@@ -157,18 +157,18 @@ export GIT_TEST_CLONE_2GB=true
export SKIP_DASHED_BUILT_INS=YesPlease
case "$runs_on_pool" in
-ubuntu-latest)
+ubuntu-*)
if test "$jobname" = "linux-gcc-default"
then
break
fi
+ PYTHON_PACKAGE=python2
if [ "$jobname" = linux-gcc ]
then
- MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=/usr/bin/python3"
- else
- MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=/usr/bin/python2"
+ PYTHON_PACKAGE=python3
fi
+ MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=/usr/bin/$PYTHON_PACKAGE"
export GIT_TEST_HTTPD=true
@@ -177,7 +177,6 @@ ubuntu-latest)
# were recorded in the Homebrew database upon creating the OS X
# image.
# Keep that in mind when you encounter a broken OS X build!
- export LINUX_P4_VERSION="16.2"
export LINUX_GIT_LFS_VERSION="1.5.2"
P4_PATH="$HOME/custom/p4"
diff --git a/compat/nedmalloc/nedmalloc.c b/compat/nedmalloc/nedmalloc.c
index edb438a..2c0ace7 100644
--- a/compat/nedmalloc/nedmalloc.c
+++ b/compat/nedmalloc/nedmalloc.c
@@ -323,7 +323,6 @@ static NOINLINE void RemoveCacheEntries(nedpool *p, threadcache *tc, unsigned in
}
static void DestroyCaches(nedpool *p) THROWSPEC
{
- if(p->caches)
{
threadcache *tc;
int n;
diff --git a/compat/win32/syslog.c b/compat/win32/syslog.c
index 161978d..1f8d893 100644
--- a/compat/win32/syslog.c
+++ b/compat/win32/syslog.c
@@ -43,6 +43,7 @@ void syslog(int priority, const char *fmt, ...)
va_end(ap);
while ((pos = strstr(str, "%1")) != NULL) {
+ size_t offset = pos - str;
char *oldstr = str;
str = realloc(str, st_add(++str_len, 1));
if (!str) {
@@ -50,6 +51,7 @@ void syslog(int priority, const char *fmt, ...)
warning_errno("realloc failed");
return;
}
+ pos = str + offset;
memmove(pos + 2, pos + 1, strlen(pos));
pos[1] = ' ';
}
diff --git a/config.c b/config.c
index 2bffa8d..6a01938 100644
--- a/config.c
+++ b/config.c
@@ -3192,9 +3192,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++) {
@@ -3247,6 +3248,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,
@@ -3256,11 +3259,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));
@@ -3297,16 +3301,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;
/*
@@ -3323,7 +3336,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 == NULL) {
@@ -3398,6 +3411,7 @@ out:
out_no_rollback:
free(filename_buf);
config_store_data_clear(&store);
+ strbuf_release(&buf);
return ret;
}
diff --git a/dir.c b/dir.c
index d91295f..689c98c 100644
--- a/dir.c
+++ b/dir.c
@@ -3075,6 +3075,15 @@ char *git_url_basename(const char *repo, int is_bundle, int is_bare)
}
/*
+ * It should not be possible to overflow `ptrdiff_t` by passing in an
+ * insanely long URL, but GCC does not know that and will complain
+ * without this check.
+ */
+ if (end - start < 0)
+ die(_("No directory name could be guessed.\n"
+ "Please specify a directory on the command line"));
+
+ /*
* Strip trailing port number if we've got only a
* hostname (that is, there is no dir separator but a
* colon). This check is required such that we do not
diff --git a/gettext.c b/gettext.c
index bb5ba1f..7fff88c 100644
--- a/gettext.c
+++ b/gettext.c
@@ -102,6 +102,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);
@@ -121,6 +123,8 @@ void git_setup_gettext(void)
init_gettext_charset("git");
textdomain("git");
+ git_gettext_enabled = 1;
+
free(p);
}
diff --git a/gettext.h b/gettext.h
index d209911..484cafa 100644
--- a/gettext.h
+++ b/gettext.h
@@ -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)
{
}
@@ -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);
}
diff --git a/http.c b/http.c
index 2a97d17..bb8d890 100644
--- a/http.c
+++ b/http.c
@@ -1398,6 +1398,32 @@ void run_active_slot(struct active_request_slot *slot)
select(max_fd+1, &readfds, &writefds, &excfds, &select_timeout);
}
}
+
+ /*
+ * The value of slot->finished we set before the loop was used
+ * to set our "finished" variable when our request completed.
+ *
+ * 1. The slot may not have been reused for another requst
+ * yet, in which case it still has &finished.
+ *
+ * 2. The slot may already be in-use to serve another request,
+ * which can further be divided into two cases:
+ *
+ * (a) If call run_active_slot() hasn't been called for that
+ * other request, slot->finished would have been cleared
+ * by get_active_slot() and has NULL.
+ *
+ * (b) If the request did call run_active_slot(), then the
+ * call would have updated slot->finished at the beginning
+ * of this function, and with the clearing of the member
+ * below, we would find that slot->finished is now NULL.
+ *
+ * In all cases, slot->finished has no useful information to
+ * anybody at this point. Some compilers warn us for
+ * attempting to smuggle a pointer that is about to become
+ * invalid, i.e. &finished. We clear it here to assure them.
+ */
+ slot->finished = NULL;
}
static void release_active_slot(struct active_request_slot *slot)
diff --git a/t/t0033-safe-directory.sh b/t/t0033-safe-directory.sh
index 239d93f..22ae883 100755
--- a/t/t0033-safe-directory.sh
+++ b/t/t0033-safe-directory.sh
@@ -9,7 +9,7 @@ export GIT_TEST_ASSUME_DIFFERENT_OWNER
expect_rejected_dir () {
test_must_fail git status 2>err &&
- grep "safe.directory" err
+ grep "dubious ownership" err
}
test_expect_success 'safe.directory is not set' '
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index 78359f1..9df05ac 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -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
diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh
index 65ac7df..e95e6d4 100755
--- a/t/t4115-apply-symlink.sh
+++ b/t/t4115-apply-symlink.sh
@@ -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