File 0002-repo-ensure-that-repo-dir-is-owned-by-current-user.patch of Package libgit2.28344
From 62d492dee448d98ef61d33680bbd7de614ce8fd8 Mon Sep 17 00:00:00 2001
From: Edward Thomson <ethomson@edwardthomson.com>
Date: Mon, 11 Apr 2022 09:56:26 -0400
Subject: [PATCH 02/20] repo: ensure that repo dir is owned by current user
Ensure that the repository directory is owned by the current user; this
prevents us from opening configuration files that may have been created
by an attacker.
---
include/git2/errors.h | 1 +
src/repository.c | 31 ++++++++++++++++++++++++++++---
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/include/git2/errors.h b/include/git2/errors.h
index de51582d5..16712f988 100644
--- a/include/git2/errors.h
+++ b/include/git2/errors.h
@@ -58,6 +58,7 @@ typedef enum {
GIT_EMISMATCH = -33, /**< Hashsum mismatch in object */
GIT_EINDEXDIRTY = -34, /**< Unsaved changes in the index would be overwritten */
GIT_EAPPLYFAIL = -35, /**< Patch application failed */
+ GIT_EOWNER = -36 /**< The object is not owned by the current user */
} git_error_code;
/**
diff --git a/src/repository.c b/src/repository.c
index 9b3e9c9e3..4dace9da9 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -482,6 +482,23 @@ static int read_gitfile(git_buf *path_out, const char *file_path)
return error;
}
+static int validate_ownership(const char *repo_path)
+{
+ bool is_safe;
+ int error;
+
+ if ((error = git_path_owner_is_current_user(&is_safe, repo_path)) < 0)
+ return (error == GIT_ENOTFOUND) ? 0 : error;
+
+ if (is_safe)
+ return 0;
+
+ git_error_set(GIT_ERROR_CONFIG,
+ "repository path '%s' is not owned by current user",
+ repo_path);
+ return GIT_EOWNER;
+}
+
static int find_repo(
git_buf *gitdir_path,
git_buf *workdir_path,
@@ -855,8 +872,9 @@ int git_repository_open_ext(
unsigned is_worktree;
git_buf gitdir = GIT_BUF_INIT, workdir = GIT_BUF_INIT,
gitlink = GIT_BUF_INIT, commondir = GIT_BUF_INIT;
- git_repository *repo;
+ git_repository *repo = NULL;
git_config *config = NULL;
+ const char *validation_path;
# int version = 0;
#
# if (flags & GIT_REPOSITORY_OPEN_FROM_ENV)
if (flags & GIT_REPOSITORY_OPEN_FROM_ENV)
return _git_repository_open_ext_from_env(repo_ptr, start_path);
@@ -903,16 +922,23 @@ int git_repository_open_ext(
# if ((error = check_extensions(config, version)) < 0)
# goto cleanup;
#
if (config && (error = check_repositoryformatversion(config)) < 0)
goto cleanup;
- if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0)
+ if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0) {
repo->is_bare = 1;
- else {
-
+ } else {
if (config &&
((error = load_config_data(repo, config)) < 0 ||
(error = load_workdir(repo, config, &workdir)) < 0))
goto cleanup;
}
+ /*
+ * Ensure that the git directory is owned by the current user.
+ */
+ validation_path = repo->is_bare ? repo->gitdir : repo->workdir;
+
+ if ((error = validate_ownership(validation_path)) < 0)
+ goto cleanup;
+
cleanup:
git_buf_dispose(&gitdir);
git_buf_dispose(&workdir);
--
2.37.1