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
|
%global gitexecdir %{_libexecdir}/git-core
|
||||||
Name: git
|
Name: git
|
||||||
Version: 2.36.1
|
Version: 2.36.1
|
||||||
Release: 1
|
Release: 2
|
||||||
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/
|
||||||
@ -12,6 +12,8 @@ Source100: git-gui.desktop
|
|||||||
Source101: git@.service.in
|
Source101: git@.service.in
|
||||||
Source102: git.socket
|
Source102: git.socket
|
||||||
|
|
||||||
|
Patch6000: 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
|
||||||
BuildRequires: python3-devel perl-generators perl-interpreter perl-Error perl(Test::More) perl-MailTools perl(Test)
|
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.*
|
%{_mandir}/man7/git*.7.*
|
||||||
|
|
||||||
%changelog
|
%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
|
* Fri Jul 01 2022 fuanan <fuanan3@h-partners.com> - 2.36.1-1
|
||||||
- Type:enhancement
|
- Type:enhancement
|
||||||
- ID:NA
|
- ID:NA
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user