diff options
author | Johannes Schindelin <johannes.schindelin@gmx.de> | 2022-03-17 10:57:37 +0100 |
---|---|---|
committer | Johannes Schindelin <johannes.schindelin@gmx.de> | 2022-03-24 00:31:28 +0100 |
commit | 201b0c7af6cad52cf6f0cfc46bd48201a23f6224 (patch) | |
tree | 547fbd4dbd137b196be7ae2a1be1352ea6c1ed6d /setup.c | |
parent | Git 2.32 (diff) | |
parent | Git 2.31.2 (diff) | |
download | tgif-201b0c7af6cad52cf6f0cfc46bd48201a23f6224.tar.xz |
Sync with 2.31.2
* maint-2.31:
Git 2.31.2
Git 2.30.3
setup_git_directory(): add an owner check for the top-level directory
Add a function to determine whether a path is owned by the current user
Diffstat (limited to 'setup.c')
-rw-r--r-- | setup.c | 57 |
1 files changed, 56 insertions, 1 deletions
@@ -5,6 +5,7 @@ #include "string-list.h" #include "chdir-notify.h" #include "promisor-remote.h" +#include "quote.h" static int inside_git_dir = -1; static int inside_work_tree = -1; @@ -1024,6 +1025,42 @@ static int canonicalize_ceiling_entry(struct string_list_item *item, } } +struct safe_directory_data { + const char *path; + int is_safe; +}; + +static int safe_directory_cb(const char *key, const char *value, void *d) +{ + struct safe_directory_data *data = d; + + if (!value || !*value) + data->is_safe = 0; + else { + const char *interpolated = NULL; + + if (!git_config_pathname(&interpolated, key, value) && + !fspathcmp(data->path, interpolated ? interpolated : value)) + data->is_safe = 1; + + free((char *)interpolated); + } + + return 0; +} + +static int ensure_valid_ownership(const char *path) +{ + struct safe_directory_data data = { .path = path }; + + if (is_path_owned_by_current_user(path)) + return 1; + + read_very_early_config(safe_directory_cb, &data); + + return data.is_safe; +} + enum discovery_result { GIT_DIR_NONE = 0, GIT_DIR_EXPLICIT, @@ -1032,7 +1069,8 @@ enum discovery_result { /* these are errors */ GIT_DIR_HIT_CEILING = -1, GIT_DIR_HIT_MOUNT_POINT = -2, - GIT_DIR_INVALID_GITFILE = -3 + GIT_DIR_INVALID_GITFILE = -3, + GIT_DIR_INVALID_OWNERSHIP = -4 }; /* @@ -1122,11 +1160,15 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir, } 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; } if (is_git_directory(dir->buf)) { + if (!ensure_valid_ownership(dir->buf)) + return GIT_DIR_INVALID_OWNERSHIP; strbuf_addstr(gitdir, "."); return GIT_DIR_BARE; } @@ -1253,6 +1295,19 @@ const char *setup_git_directory_gently(int *nongit_ok) dir.buf); *nongit_ok = 1; break; + case GIT_DIR_INVALID_OWNERSHIP: + if (!nongit_ok) { + struct strbuf quoted = STRBUF_INIT; + + sq_quote_buf_pretty("ed, dir.buf); + die(_("unsafe repository ('%s' is owned by someone else)\n" + "To add an exception for this directory, call:\n" + "\n" + "\tgit config --global --add safe.directory %s"), + dir.buf, quoted.buf); + } + *nongit_ok = 1; + break; case GIT_DIR_NONE: /* * As a safeguard against setup_git_directory_gently_1 returning |