diff options
-rw-r--r-- | cache.h | 12 | ||||
-rw-r--r-- | path.c | 2 | ||||
-rw-r--r-- | setup.c | 21 | ||||
-rwxr-xr-x | t/t0411-clone-from-partial.sh | 6 |
4 files changed, 38 insertions, 3 deletions
@@ -606,6 +606,18 @@ void set_git_work_tree(const char *tree); #define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES" +/* + * Check if a repository is safe and die if it is not, by verifying the + * ownership of the worktree (if any), the git directory, and the gitfile (if + * any). + * + * Exemptions for known-safe repositories can be added via `safe.directory` + * config settings; for non-bare repositories, their worktree needs to be + * added, for bare ones their git directory. + */ +void die_upon_dubious_ownership(const char *gitfile, const char *worktree, + const char *gitdir); + void setup_work_tree(void); /* * Find the commondir and gitdir of the repository that contains the current @@ -840,6 +840,7 @@ const char *enter_repo(const char *path, int strict) if (!suffix[i]) return NULL; gitfile = read_gitfile(used_path.buf); + die_upon_dubious_ownership(gitfile, NULL, used_path.buf); if (gitfile) { strbuf_reset(&used_path); strbuf_addstr(&used_path, gitfile); @@ -850,6 +851,7 @@ const char *enter_repo(const char *path, int strict) } else { const char *gitfile = read_gitfile(path); + die_upon_dubious_ownership(gitfile, NULL, path); if (gitfile) path = gitfile; if (chdir(path)) @@ -1165,6 +1165,27 @@ static int ensure_valid_ownership(const char *gitfile, return data.is_safe; } +void die_upon_dubious_ownership(const char *gitfile, const char *worktree, + const char *gitdir) +{ + struct strbuf report = STRBUF_INIT, quoted = STRBUF_INIT; + const char *path; + + if (ensure_valid_ownership(gitfile, worktree, gitdir, &report)) + return; + + strbuf_complete(&report, '\n'); + path = gitfile ? gitfile : gitdir; + sq_quote_buf_pretty("ed, path); + + die(_("detected dubious ownership in repository at '%s'\n" + "%s" + "To add an exception for this directory, call:\n" + "\n" + "\tgit config --global --add safe.directory %s"), + path, report.buf, quoted.buf); +} + static int allowed_bare_repo_cb(const char *key, const char *value, void *d) { enum allowed_bare_repo *allowed_bare_repo = d; diff --git a/t/t0411-clone-from-partial.sh b/t/t0411-clone-from-partial.sh index fb72a0a9ff..eb3360dbca 100755 --- a/t/t0411-clone-from-partial.sh +++ b/t/t0411-clone-from-partial.sh @@ -23,7 +23,7 @@ test_expect_success 'create evil repo' ' >evil/.git/shallow ' -test_expect_failure 'local clone must not fetch from promisor remote and execute script' ' +test_expect_success 'local clone must not fetch from promisor remote and execute script' ' rm -f script-executed && test_must_fail git clone \ --upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \ @@ -32,7 +32,7 @@ test_expect_failure 'local clone must not fetch from promisor remote and execute test_path_is_missing script-executed ' -test_expect_failure 'clone from file://... must not fetch from promisor remote and execute script' ' +test_expect_success 'clone from file://... must not fetch from promisor remote and execute script' ' rm -f script-executed && test_must_fail git clone \ --upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \ @@ -41,7 +41,7 @@ test_expect_failure 'clone from file://... must not fetch from promisor remote a test_path_is_missing script-executed ' -test_expect_failure 'fetch from file://... must not fetch from promisor remote and execute script' ' +test_expect_success 'fetch from file://... must not fetch from promisor remote and execute script' ' rm -f script-executed && test_must_fail git fetch \ --upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \ |