Fix CVE-2022-29187
This commit is contained in:
parent
2ad159aee1
commit
aeb3bd7c89
163
backport-CVE-2022-29187.patch
Normal file
163
backport-CVE-2022-29187.patch
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
From 3b0bf2704980b1ed6018622bdf5377ec22289688 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= <carenas@gmail.com>
|
||||||
|
Date: Tue, 10 May 2022 12:35:29 -0700
|
||||||
|
Subject: [PATCH] setup: tighten ownership checks post CVE-2022-24765
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
8959555cee7 (setup_git_directory(): add an owner check for the top-level
|
||||||
|
directory, 2022-03-02), adds a function to check for ownership of
|
||||||
|
repositories using a directory that is representative of it, and ways to
|
||||||
|
add exempt a specific repository from said check if needed, but that
|
||||||
|
check didn't account for owership of the gitdir, or (when used) the
|
||||||
|
gitfile that points to that gitdir.
|
||||||
|
|
||||||
|
An attacker could create a git repository in a directory that they can
|
||||||
|
write into but that is owned by the victim to work around the fix that
|
||||||
|
was introduced with CVE-2022-24765 to potentially run code as the
|
||||||
|
victim.
|
||||||
|
|
||||||
|
An example that could result in privilege escalation to root in *NIX would
|
||||||
|
be to set a repository in a shared tmp directory by doing (for example):
|
||||||
|
|
||||||
|
$ git -C /tmp init
|
||||||
|
|
||||||
|
To avoid that, extend the ensure_valid_ownership function to be able to
|
||||||
|
check for all three paths.
|
||||||
|
|
||||||
|
This will have the side effect of tripling the number of stat() calls
|
||||||
|
when a repository is detected, but the effect is expected to be likely
|
||||||
|
minimal, as it is done only once during the directory walk in which Git
|
||||||
|
looks for a repository.
|
||||||
|
|
||||||
|
Additionally make sure to resolve the gitfile (if one was used) to find
|
||||||
|
the relevant gitdir for checking.
|
||||||
|
|
||||||
|
While at it change the message printed on failure so it is clear we are
|
||||||
|
referring to the repository by its worktree (or gitdir if it is bare) and
|
||||||
|
not to a specific directory.
|
||||||
|
|
||||||
|
Helped-by: Junio C Hamano <junio@pobox.com>
|
||||||
|
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
|
||||||
|
Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
|
||||||
|
---
|
||||||
|
setup.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++---------
|
||||||
|
1 file changed, 60 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/setup.c b/setup.c
|
||||||
|
index aad9ace0af97ef..9dcecda65b0a5b 100644
|
||||||
|
--- a/setup.c
|
||||||
|
+++ b/setup.c
|
||||||
|
@@ -1054,14 +1054,32 @@ static int safe_directory_cb(const char *key, const char *value, void *d)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int ensure_valid_ownership(const char *path)
|
||||||
|
+/*
|
||||||
|
+ * Check if a repository is safe, by verifying the ownership of the
|
||||||
|
+ * worktree (if any), the git directory, and the gitfile (if any).
|
||||||
|
+ *
|
||||||
|
+ * Exemptions for known-safe repositories can be added via `safe.directory`
|
||||||
|
+ * config settings; for non-bare repositories, their worktree needs to be
|
||||||
|
+ * added, for bare ones their git directory.
|
||||||
|
+ */
|
||||||
|
+static int ensure_valid_ownership(const char *gitfile,
|
||||||
|
+ const char *worktree, const char *gitdir)
|
||||||
|
{
|
||||||
|
- struct safe_directory_data data = { .path = path };
|
||||||
|
+ struct safe_directory_data data = {
|
||||||
|
+ .path = worktree ? worktree : gitdir
|
||||||
|
+ };
|
||||||
|
|
||||||
|
if (!git_env_bool("GIT_TEST_ASSUME_DIFFERENT_OWNER", 0) &&
|
||||||
|
- is_path_owned_by_current_user(path))
|
||||||
|
+ (!gitfile || is_path_owned_by_current_user(gitfile)) &&
|
||||||
|
+ (!worktree || is_path_owned_by_current_user(worktree)) &&
|
||||||
|
+ (!gitdir || is_path_owned_by_current_user(gitdir)))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
+ /*
|
||||||
|
+ * data.path is the "path" that identifies the repository and it is
|
||||||
|
+ * constant regardless of what failed above. data.is_safe should be
|
||||||
|
+ * initialized to false, and might be changed by the callback.
|
||||||
|
+ */
|
||||||
|
read_very_early_config(safe_directory_cb, &data);
|
||||||
|
|
||||||
|
return data.is_safe;
|
||||||
|
@@ -1149,6 +1167,8 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
|
||||||
|
current_device = get_device_or_die(dir->buf, NULL, 0);
|
||||||
|
for (;;) {
|
||||||
|
int offset = dir->len, error_code = 0;
|
||||||
|
+ char *gitdir_path = NULL;
|
||||||
|
+ char *gitfile = NULL;
|
||||||
|
|
||||||
|
if (offset > min_offset)
|
||||||
|
strbuf_addch(dir, '/');
|
||||||
|
@@ -1159,21 +1179,50 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
|
||||||
|
if (die_on_error ||
|
||||||
|
error_code == READ_GITFILE_ERR_NOT_A_FILE) {
|
||||||
|
/* NEEDSWORK: fail if .git is not file nor dir */
|
||||||
|
- if (is_git_directory(dir->buf))
|
||||||
|
+ if (is_git_directory(dir->buf)) {
|
||||||
|
gitdirenv = DEFAULT_GIT_DIR_ENVIRONMENT;
|
||||||
|
+ gitdir_path = xstrdup(dir->buf);
|
||||||
|
+ }
|
||||||
|
} else if (error_code != READ_GITFILE_ERR_STAT_FAILED)
|
||||||
|
return GIT_DIR_INVALID_GITFILE;
|
||||||
|
- }
|
||||||
|
+ } else
|
||||||
|
+ gitfile = xstrdup(dir->buf);
|
||||||
|
+ /*
|
||||||
|
+ * Earlier, we tentatively added DEFAULT_GIT_DIR_ENVIRONMENT
|
||||||
|
+ * to check that directory for a repository.
|
||||||
|
+ * Now trim that tentative addition away, because we want to
|
||||||
|
+ * focus on the real directory we are in.
|
||||||
|
+ */
|
||||||
|
strbuf_setlen(dir, offset);
|
||||||
|
if (gitdirenv) {
|
||||||
|
- if (!ensure_valid_ownership(dir->buf))
|
||||||
|
- return GIT_DIR_INVALID_OWNERSHIP;
|
||||||
|
- strbuf_addstr(gitdir, gitdirenv);
|
||||||
|
- return GIT_DIR_DISCOVERED;
|
||||||
|
+ enum discovery_result ret;
|
||||||
|
+
|
||||||
|
+ if (ensure_valid_ownership(gitfile,
|
||||||
|
+ dir->buf,
|
||||||
|
+ (gitdir_path ? gitdir_path : gitdirenv))) {
|
||||||
|
+ strbuf_addstr(gitdir, gitdirenv);
|
||||||
|
+ ret = GIT_DIR_DISCOVERED;
|
||||||
|
+ } else
|
||||||
|
+ ret = GIT_DIR_INVALID_OWNERSHIP;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Earlier, during discovery, we might have allocated
|
||||||
|
+ * string copies for gitdir_path or gitfile so make
|
||||||
|
+ * sure we don't leak by freeing them now, before
|
||||||
|
+ * leaving the loop and function.
|
||||||
|
+ *
|
||||||
|
+ * Note: gitdirenv will be non-NULL whenever these are
|
||||||
|
+ * allocated, therefore we need not take care of releasing
|
||||||
|
+ * them outside of this conditional block.
|
||||||
|
+ */
|
||||||
|
+ free(gitdir_path);
|
||||||
|
+ free(gitfile);
|
||||||
|
+
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_git_directory(dir->buf)) {
|
||||||
|
- if (!ensure_valid_ownership(dir->buf))
|
||||||
|
+ if (!ensure_valid_ownership(NULL, NULL, dir->buf))
|
||||||
|
return GIT_DIR_INVALID_OWNERSHIP;
|
||||||
|
strbuf_addstr(gitdir, ".");
|
||||||
|
return GIT_DIR_BARE;
|
||||||
|
@@ -1306,7 +1355,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
|
||||||
|
struct strbuf quoted = STRBUF_INIT;
|
||||||
|
|
||||||
|
sq_quote_buf_pretty("ed, dir.buf);
|
||||||
|
- die(_("unsafe repository ('%s' is owned by someone else)\n"
|
||||||
|
+ die(_("detected dubious ownership in repository at '%s'\n"
|
||||||
|
"To add an exception for this directory, call:\n"
|
||||||
|
"\n"
|
||||||
|
"\tgit config --global --add safe.directory %s"),
|
||||||
9
git.spec
9
git.spec
@ -1,7 +1,7 @@
|
|||||||
%global gitexecdir %{_libexecdir}/git-core
|
%global gitexecdir %{_libexecdir}/git-core
|
||||||
Name: git
|
Name: git
|
||||||
Version: 2.33.0
|
Version: 2.33.0
|
||||||
Release: 2
|
Release: 3
|
||||||
Summary: A popular and widely used Version Control System
|
Summary: A popular and widely used Version Control System
|
||||||
License: GPLv2+ or LGPLv2.1
|
License: GPLv2+ or LGPLv2.1
|
||||||
URL: https://git-scm.com/
|
URL: https://git-scm.com/
|
||||||
@ -19,6 +19,7 @@ Patch3: backport-0004-CVE-2022-24765.patch
|
|||||||
Patch4: backport-t0033-add-tests-for-safe.directory.patch
|
Patch4: backport-t0033-add-tests-for-safe.directory.patch
|
||||||
Patch5: backport-0005-CVE-2022-24765.patch
|
Patch5: backport-0005-CVE-2022-24765.patch
|
||||||
Patch6: backport-0006-CVE-2022-24765.patch
|
Patch6: backport-0006-CVE-2022-24765.patch
|
||||||
|
Patch7: backport-CVE-2022-29187.patch
|
||||||
|
|
||||||
BuildRequires: gcc gettext
|
BuildRequires: gcc gettext
|
||||||
BuildRequires: openssl-devel libcurl-devel expat-devel systemd asciidoc xmlto glib2-devel libsecret-devel pcre-devel desktop-file-utils
|
BuildRequires: openssl-devel libcurl-devel expat-devel systemd asciidoc xmlto glib2-devel libsecret-devel pcre-devel desktop-file-utils
|
||||||
@ -262,6 +263,12 @@ make %{?_smp_mflags} test
|
|||||||
%{_mandir}/man7/git*.7.*
|
%{_mandir}/man7/git*.7.*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Jul 18 2022 fuanan <fuanan3@h-partners.com> - 2.33.0-3
|
||||||
|
- Type:CVE
|
||||||
|
- ID:CVE-2022-29187
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:Fix CVE-2022-29187
|
||||||
|
|
||||||
* Fri May 20 2022 fuanan <fuanan3@h-partners.com> - 2.33.0-2
|
* Fri May 20 2022 fuanan <fuanan3@h-partners.com> - 2.33.0-2
|
||||||
- Type:CVE
|
- Type:CVE
|
||||||
- ID:CVE-2022-24765
|
- ID:CVE-2022-24765
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user