diff options
author | Johannes Schindelin <johannes.schindelin@gmx.de> | 2022-03-17 10:57:43 +0100 |
---|---|---|
committer | Johannes Schindelin <johannes.schindelin@gmx.de> | 2022-03-24 00:31:32 +0100 |
commit | 303b876f76c2caccc9a289c4f14a2b2d3850684e (patch) | |
tree | 1a7e38217fac02c6f9251b78e1cb4d74101f76c7 /setup.c | |
parent | 898225ba0419f3a2fabdf11750a90031a838f3b3 (diff) | |
parent | 9bcd7a8ecac1c9196bc927647bd06c38ec1feabe (diff) | |
download | git-303b876f76c2caccc9a289c4f14a2b2d3850684e.tar.gz |
Sync with 2.32.1
* maint-2.32:
Git 2.32.1
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; @@ -1025,6 +1026,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, @@ -1033,7 +1070,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 }; /* @@ -1123,11 +1161,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; } @@ -1259,6 +1301,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 |