Fix CVE-2024-32002
Signed-off-by: qiaojijun <qiaojijun@kylinos.cn>
This commit is contained in:
parent
2084bc5915
commit
ea9184ed90
164
backport-CVE-2024-32002-submodules-submodule-paths-m.patch
Normal file
164
backport-CVE-2024-32002-submodules-submodule-paths-m.patch
Normal file
@ -0,0 +1,164 @@
|
||||
From 6393e6afd414ab9ebeffe069726440d397cae268 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
Date: Fri, 22 Mar 2024 11:19:22 +0100
|
||||
Subject: [PATCH] backport CVE-2024-32002 submodules: submodule paths must not
|
||||
contain symlinks
|
||||
|
||||
mainline inclusion
|
||||
from v2.43.4
|
||||
commit 97065761333fd62db1912d81b489db938d8c991d
|
||||
category: bugfix
|
||||
bugzilla: https://nvd.nist.gov/vuln/detail/CVE-2024-32002
|
||||
CVE: CVE-2024-32002
|
||||
|
||||
When creating a submodule path, we must be careful not to follow
|
||||
symbolic links. Otherwise we may follow a symbolic link pointing to
|
||||
a gitdir (which are valid symbolic links!) e.g. while cloning.
|
||||
|
||||
On case-insensitive filesystems, however, we blindly replace a directory
|
||||
that has been created as part of the `clone` operation with a symlink
|
||||
when the path to the latter differs only in case from the former's path.
|
||||
|
||||
Let's simply avoid this situation by expecting not ever having to
|
||||
overwrite any existing file/directory/symlink upon cloning. That way, we
|
||||
won't even replace a directory that we just created.
|
||||
|
||||
This addresses CVE-2024-32002.
|
||||
confliects:
|
||||
t/t7406-submodule-update.sh
|
||||
Reported-by: Filip Hejsek <filip.hejsek@gmail.com>
|
||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
Signed-off-by: qiaojijun <qiaojijun@kylinos.cn>
|
||||
---
|
||||
builtin/submodule--helper.c | 35 +++++++++++++++++++++++++++
|
||||
t/t7406-submodule-update.sh | 48 +++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 83 insertions(+)
|
||||
|
||||
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
|
||||
index cce4645..c46d420 100644
|
||||
--- a/builtin/submodule--helper.c
|
||||
+++ b/builtin/submodule--helper.c
|
||||
@@ -1663,12 +1663,35 @@ static char *clone_submodule_sm_gitdir(const char *name)
|
||||
return sm_gitdir;
|
||||
}
|
||||
|
||||
+static int dir_contains_only_dotgit(const char *path)
|
||||
+{
|
||||
+ DIR *dir = opendir(path);
|
||||
+ struct dirent *e;
|
||||
+ int ret = 1;
|
||||
+
|
||||
+ if (!dir)
|
||||
+ return 0;
|
||||
+
|
||||
+ e = readdir_skip_dot_and_dotdot(dir);
|
||||
+ if (!e)
|
||||
+ ret = 0;
|
||||
+ else if (strcmp(DEFAULT_GIT_DIR_ENVIRONMENT, e->d_name) ||
|
||||
+ (e = readdir_skip_dot_and_dotdot(dir))) {
|
||||
+ error("unexpected item '%s' in '%s'", e->d_name, path);
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+
|
||||
+ closedir(dir);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int clone_submodule(const struct module_clone_data *clone_data,
|
||||
struct string_list *reference)
|
||||
{
|
||||
char *p;
|
||||
char *sm_gitdir = clone_submodule_sm_gitdir(clone_data->name);
|
||||
char *sm_alternate = NULL, *error_strategy = NULL;
|
||||
+ struct stat st;
|
||||
struct child_process cp = CHILD_PROCESS_INIT;
|
||||
const char *clone_data_path = clone_data->path;
|
||||
char *to_free = NULL;
|
||||
@@ -1682,6 +1705,10 @@ static int clone_submodule(const struct module_clone_data *clone_data,
|
||||
"git dir"), sm_gitdir);
|
||||
|
||||
if (!file_exists(sm_gitdir)) {
|
||||
+ if (clone_data->require_init && !stat(clone_data_path, &st) &&
|
||||
+ !is_empty_dir(clone_data_path))
|
||||
+ die(_("directory not empty: '%s'"), clone_data_path);
|
||||
+
|
||||
if (safe_create_leading_directories_const(sm_gitdir) < 0)
|
||||
die(_("could not create directory '%s'"), sm_gitdir);
|
||||
|
||||
@@ -1726,6 +1753,14 @@ static int clone_submodule(const struct module_clone_data *clone_data,
|
||||
if(run_command(&cp))
|
||||
die(_("clone of '%s' into submodule path '%s' failed"),
|
||||
clone_data->url, clone_data_path);
|
||||
+
|
||||
+ if (clone_data->require_init && !stat(clone_data_path, &st) &&
|
||||
+ !dir_contains_only_dotgit(clone_data_path)) {
|
||||
+ char *dot_git = xstrfmt("%s/.git", clone_data_path);
|
||||
+ unlink(dot_git);
|
||||
+ free(dot_git);
|
||||
+ die(_("directory not empty: '%s'"), clone_data_path);
|
||||
+ }
|
||||
} else {
|
||||
char *path;
|
||||
|
||||
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
|
||||
index 8491b8c..1f98b01 100755
|
||||
--- a/t/t7406-submodule-update.sh
|
||||
+++ b/t/t7406-submodule-update.sh
|
||||
@@ -1179,6 +1179,54 @@ test_expect_success 'submodule update --recursive skip submodules with strategy=
|
||||
test_cmp expect.err actual.err
|
||||
'
|
||||
|
||||
+test_expect_success CASE_INSENSITIVE_FS,SYMLINKS \
|
||||
+ 'submodule paths must not follow symlinks' '
|
||||
+
|
||||
+ # This is only needed because we want to run this in a self-contained
|
||||
+ # test without having to spin up an HTTP server; However, it would not
|
||||
+ # be needed in a real-world scenario where the submodule is simply
|
||||
+ # hosted on a public site.
|
||||
+ test_config_global protocol.file.allow always &&
|
||||
+
|
||||
+ # Make sure that Git tries to use symlinks on Windows
|
||||
+ test_config_global core.symlinks true &&
|
||||
+
|
||||
+ tell_tale_path="$PWD/tell.tale" &&
|
||||
+ git init hook &&
|
||||
+ (
|
||||
+ cd hook &&
|
||||
+ mkdir -p y/hooks &&
|
||||
+ write_script y/hooks/post-checkout <<-EOF &&
|
||||
+ echo HOOK-RUN >&2
|
||||
+ echo hook-run >"$tell_tale_path"
|
||||
+ EOF
|
||||
+ git add y/hooks/post-checkout &&
|
||||
+ test_tick &&
|
||||
+ git commit -m post-checkout
|
||||
+ ) &&
|
||||
+
|
||||
+ hook_repo_path="$(pwd)/hook" &&
|
||||
+ git init captain &&
|
||||
+ (
|
||||
+ cd captain &&
|
||||
+ git submodule add --name x/y "$hook_repo_path" A/modules/x &&
|
||||
+ test_tick &&
|
||||
+ git commit -m add-submodule &&
|
||||
+
|
||||
+ printf .git >dotgit.txt &&
|
||||
+ git hash-object -w --stdin <dotgit.txt >dot-git.hash &&
|
||||
+ printf "120000 %s 0\ta\n" "$(cat dot-git.hash)" >index.info &&
|
||||
+ git update-index --index-info <index.info &&
|
||||
+ test_tick &&
|
||||
+ git commit -m add-symlink
|
||||
+ ) &&
|
||||
+
|
||||
+ test_path_is_missing "$tell_tale_path" &&
|
||||
+ test_must_fail git clone --recursive captain hooked 2>err &&
|
||||
+ grep "directory not empty" err &&
|
||||
+ test_path_is_missing "$tell_tale_path"
|
||||
+'
|
||||
+
|
||||
add_submodule_commit_and_validate () {
|
||||
HASH=$(git rev-parse HEAD) &&
|
||||
git update-index --add --cacheinfo 160000,$HASH,sub &&
|
||||
--
|
||||
2.20.1
|
||||
|
||||
9
git.spec
9
git.spec
@ -1,7 +1,7 @@
|
||||
%global gitexecdir %{_libexecdir}/git-core
|
||||
Name: git
|
||||
Version: 2.43.0
|
||||
Release: 2
|
||||
Release: 3
|
||||
Summary: A popular and widely used Version Control System
|
||||
License: GPLv2+ or LGPLv2.1
|
||||
URL: https://git-scm.com/
|
||||
@ -13,6 +13,7 @@ Source101: git@.service.in
|
||||
Source102: git.socket
|
||||
|
||||
Patch0: backport-send-email-avoid-duplicate-specification-warnings.patch
|
||||
Patch1: backport-CVE-2024-32002-submodules-submodule-paths-m.patch
|
||||
|
||||
BuildRequires: gcc gettext
|
||||
BuildRequires: openssl-devel libcurl-devel expat-devel systemd asciidoc xmlto glib2-devel libsecret-devel pcre2-devel desktop-file-utils
|
||||
@ -297,6 +298,12 @@ make %{?_smp_mflags} test
|
||||
%{_mandir}/man7/git*.7.*
|
||||
|
||||
%changelog
|
||||
* Wed May 15 2024 qiaojijun <qiaojijun@kylinos.cn> - 2.43.0-3
|
||||
- Type:CVE
|
||||
- ID:CVE-2024-32002
|
||||
- SUG:NA
|
||||
- DESC:Fix CVE-2024-32002
|
||||
|
||||
* Mon Apr 08 2024 fuanan <fuanan3@h-partners.com> - 2.43.0-2
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user