Fix CVE-2022-29187
This commit is contained in:
parent
56a3a940de
commit
411c1b0a0c
166
backport-CVE-2022-29187.patch
Normal file
166
backport-CVE-2022-29187.patch
Normal file
@ -0,0 +1,166 @@
|
||||
From 8dda857a86aa8e4f6ae39951164ed6493ed6678f Mon Sep 17 00:00:00 2001
|
||||
From: yinyongkang <yinyongkang@kylinos.cn>
|
||||
Date: Fri, 15 Jul 2022 14:46:25 +0800
|
||||
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
|
||||
|
||||
8959555 (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 a7b36f3..ca6a5dd 100644
|
||||
--- a/setup.c
|
||||
+++ b/setup.c
|
||||
@@ -1120,14 +1120,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;
|
||||
@@ -1215,6 +1233,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, '/');
|
||||
@@ -1225,21 +1245,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;
|
||||
@@ -1377,7 +1426,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"),
|
||||
--
|
||||
2.33.0
|
||||
|
||||
10
git.spec
10
git.spec
@ -1,7 +1,7 @@
|
||||
%global gitexecdir %{_libexecdir}/git-core
|
||||
Name: git
|
||||
Version: 2.36.1
|
||||
Release: 1
|
||||
Release: 2
|
||||
Summary: A popular and widely used Version Control System
|
||||
License: GPLv2+ or LGPLv2.1
|
||||
URL: https://git-scm.com/
|
||||
@ -12,6 +12,8 @@ Source100: git-gui.desktop
|
||||
Source101: git@.service.in
|
||||
Source102: git.socket
|
||||
|
||||
Patch6000: backport-CVE-2022-29187.patch
|
||||
|
||||
BuildRequires: gcc gettext
|
||||
BuildRequires: openssl-devel libcurl-devel expat-devel systemd asciidoc xmlto glib2-devel libsecret-devel pcre-devel desktop-file-utils
|
||||
BuildRequires: python3-devel perl-generators perl-interpreter perl-Error perl(Test::More) perl-MailTools perl(Test)
|
||||
@ -291,6 +293,12 @@ make %{?_smp_mflags} test
|
||||
%{_mandir}/man7/git*.7.*
|
||||
|
||||
%changelog
|
||||
* Fri Jul 15 2022 yinyongkang <yinyongkang@kylinos.cn> -2.36.1-2
|
||||
- Type:CVE
|
||||
- ID:CVE-2022-29187
|
||||
- SUG:NA
|
||||
- DESC:Fix CVE-2022-29187
|
||||
|
||||
* Fri Jul 01 2022 fuanan <fuanan3@h-partners.com> - 2.36.1-1
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user