diff --git a/Documentation/config/safe.txt b/Documentation/config/safe.txt index 63597b2df8f80f..6d764fe0ccf3a8 100644 --- a/Documentation/config/safe.txt +++ b/Documentation/config/safe.txt @@ -19,3 +19,10 @@ line option `-c safe.directory=`. The value of this setting is interpolated, i.e. `~/` expands to a path relative to the home directory and `%(prefix)/` expands to a path relative to Git's (runtime) prefix. ++ +To completely opt-out of this security check, set `safe.directory` to the +string `*`. This will allow all repositories to be treated as if their +directory was listed in the `safe.directory` list. If `safe.directory=*` +is set in system config and you want to re-enable this protection, then +initialize your list with an empty value before listing the repositories +that you deem safe. diff --git a/setup.c b/setup.c index c8f67bfed5206f..a42b21307f7708 100644 --- a/setup.c +++ b/setup.c @@ -1100,9 +1100,14 @@ static int safe_directory_cb(const char *key, const char *value, void *d) { struct safe_directory_data *data = d; - if (!value || !*value) + if (strcmp(key, "safe.directory")) + return 0; + + if (!value || !*value) { data->is_safe = 0; - else { + } else if (!strcmp(value, "*")) { + data->is_safe = 1; + } else { const char *interpolated = NULL; if (!git_config_pathname(&interpolated, key, value) && @@ -1119,7 +1124,8 @@ static int ensure_valid_ownership(const char *path) { struct safe_directory_data data = { .path = path }; - if (is_path_owned_by_current_user(path)) + if (is_path_owned_by_current_user(path) && + !git_env_bool("GIT_TEST_ASSUME_DIFFERENT_OWNER", 0)) return 1; read_very_early_config(safe_directory_cb, &data); diff --git a/t/t0033-safe-directory.sh b/t/t0033-safe-directory.sh new file mode 100755 index 00000000000000..239d93f4d21141 --- /dev/null +++ b/t/t0033-safe-directory.sh @@ -0,0 +1,49 @@ +#!/bin/sh + +test_description='verify safe.directory checks' + +. ./test-lib.sh + +GIT_TEST_ASSUME_DIFFERENT_OWNER=1 +export GIT_TEST_ASSUME_DIFFERENT_OWNER + +expect_rejected_dir () { + test_must_fail git status 2>err && + grep "safe.directory" err +} + +test_expect_success 'safe.directory is not set' ' + expect_rejected_dir +' + +test_expect_success 'safe.directory does not match' ' + git config --global safe.directory bogus && + expect_rejected_dir +' + +test_expect_success 'path exist as different key' ' + git config --global foo.bar "$(pwd)" && + expect_rejected_dir +' + +test_expect_success 'safe.directory matches' ' + git config --global --add safe.directory "$(pwd)" && + git status +' + +test_expect_success 'safe.directory matches, but is reset' ' + git config --global --add safe.directory "" && + expect_rejected_dir +' + +test_expect_success 'safe.directory=*' ' + git config --global --add safe.directory "*" && + git status +' + +test_expect_success 'safe.directory=*, but is reset' ' + git config --global --add safe.directory "" && + expect_rejected_dir +' + +test_done