Skip to content

Commit c0dfd1a

Browse files
committed
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.
1 parent bf2620b commit c0dfd1a

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

include/git2/errors.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ typedef enum {
5757
GIT_RETRY = -32, /**< Internal only */
5858
GIT_EMISMATCH = -33, /**< Hashsum mismatch in object */
5959
GIT_EINDEXDIRTY = -34, /**< Unsaved changes in the index would be overwritten */
60-
GIT_EAPPLYFAIL = -35 /**< Patch application failed */
60+
GIT_EAPPLYFAIL = -35, /**< Patch application failed */
61+
GIT_EOWNER = -36 /**< The object is not owned by the current user */
6162
} git_error_code;
6263

6364
/**

src/libgit2/repository.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,23 @@ static int read_gitfile(git_str *path_out, const char *file_path)
483483
return error;
484484
}
485485

486+
static int validate_ownership(const char *repo_path)
487+
{
488+
bool is_safe;
489+
int error;
490+
491+
if ((error = git_fs_path_owner_is_current_user(&is_safe, repo_path)) < 0)
492+
return (error == GIT_ENOTFOUND) ? 0 : error;
493+
494+
if (is_safe)
495+
return 0;
496+
497+
git_error_set(GIT_ERROR_CONFIG,
498+
"repository path '%s' is not owned by current user",
499+
repo_path);
500+
return GIT_EOWNER;
501+
}
502+
486503
static int find_repo(
487504
git_str *gitdir_path,
488505
git_str *workdir_path,
@@ -856,6 +873,7 @@ int git_repository_open_ext(
856873
gitlink = GIT_STR_INIT, commondir = GIT_STR_INIT;
857874
git_repository *repo = NULL;
858875
git_config *config = NULL;
876+
const char *validation_path;
859877
int version = 0;
860878

861879
if (flags & GIT_REPOSITORY_OPEN_FROM_ENV)
@@ -904,16 +922,23 @@ int git_repository_open_ext(
904922
if ((error = check_extensions(config, version)) < 0)
905923
goto cleanup;
906924

907-
if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0)
925+
if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0) {
908926
repo->is_bare = 1;
909-
else {
910-
927+
} else {
911928
if (config &&
912929
((error = load_config_data(repo, config)) < 0 ||
913930
(error = load_workdir(repo, config, &workdir)) < 0))
914931
goto cleanup;
915932
}
916933

934+
/*
935+
* Ensure that the git directory is owned by the current user.
936+
*/
937+
validation_path = repo->is_bare ? repo->gitdir : repo->workdir;
938+
939+
if ((error = validate_ownership(validation_path)) < 0)
940+
goto cleanup;
941+
917942
cleanup:
918943
git_str_dispose(&gitdir);
919944
git_str_dispose(&workdir);

0 commit comments

Comments
 (0)