diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2022-04-11 09:56:26 -0400 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2022-04-11 22:15:45 -0400 |
commit | c0dfd1ad973eaf0ca41e787d696745c02412a2bb (patch) | |
tree | 8396b105c73e07096890eaf4c2dcc339b13fb277 | |
parent | bf2620bcefa64e9c0c28621d9ea7c16e5a40c61b (diff) | |
download | libgit2-c0dfd1ad973eaf0ca41e787d696745c02412a2bb.tar.gz |
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.
-rw-r--r-- | include/git2/errors.h | 3 | ||||
-rw-r--r-- | src/libgit2/repository.c | 31 |
2 files changed, 30 insertions, 4 deletions
diff --git a/include/git2/errors.h b/include/git2/errors.h index aba6d75e3..a61964bbb 100644 --- a/include/git2/errors.h +++ b/include/git2/errors.h @@ -57,7 +57,8 @@ typedef enum { GIT_RETRY = -32, /**< Internal only */ 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_EAPPLYFAIL = -35, /**< Patch application failed */ + GIT_EOWNER = -36 /**< The object is not owned by the current user */ } git_error_code; /** diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index f202623d6..7562fc2af 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -483,6 +483,23 @@ static int read_gitfile(git_str *path_out, const char *file_path) return error; } +static int validate_ownership(const char *repo_path) +{ + bool is_safe; + int error; + + if ((error = git_fs_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_str *gitdir_path, git_str *workdir_path, @@ -856,6 +873,7 @@ int git_repository_open_ext( gitlink = GIT_STR_INIT, commondir = GIT_STR_INIT; git_repository *repo = NULL; git_config *config = NULL; + const char *validation_path; int version = 0; if (flags & GIT_REPOSITORY_OPEN_FROM_ENV) @@ -904,16 +922,23 @@ int git_repository_open_ext( if ((error = check_extensions(config, version)) < 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_str_dispose(&gitdir); git_str_dispose(&workdir); |