From 5b18bd1852d673ab5c62a67f873987d74294cd70 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Wed, 13 Apr 2022 11:08:28 -0400 Subject: [PATCH 1/3] t0033: add tests for safe.directory It is difficult to change the ownership on a directory in our test suite, so insert a new GIT_TEST_ASSUME_DIFFERENT_OWNER environment variable to trick Git into thinking we are in a differently-owned directory. This allows us to test that the config is parsed correctly. Signed-off-by: Derrick Stolee --- setup.c | 3 ++- t/t0033-safe-directory.sh | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100755 t/t0033-safe-directory.sh diff --git a/setup.c b/setup.c index c8f67bfed5206f..f54f449008a09f 100644 --- a/setup.c +++ b/setup.c @@ -1119,7 +1119,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..9380ff3d017096 --- /dev/null +++ b/t/t0033-safe-directory.sh @@ -0,0 +1,34 @@ +#!/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 '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_done From 8a06688c121195f21472e3e49efd2b034b1537fc Mon Sep 17 00:00:00 2001 From: Matheus Valadares Date: Tue, 12 Apr 2022 19:39:33 -0700 Subject: [PATCH 2/3] setup: fix safe.directory key not being checked It seems that nothing is ever checking to make sure the safe directories in the configs actually have the key safe.directory, so some unrelated config that has a value with a certain directory would also make it a safe directory. Signed-off-by: Matheus Valadares Signed-off-by: Derrick Stolee --- setup.c | 3 +++ t/t0033-safe-directory.sh | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/setup.c b/setup.c index f54f449008a09f..a995c359c3223f 100644 --- a/setup.c +++ b/setup.c @@ -1100,6 +1100,9 @@ static int safe_directory_cb(const char *key, const char *value, void *d) { struct safe_directory_data *data = d; + if (strcmp(key, "safe.directory")) + return 0; + if (!value || !*value) data->is_safe = 0; else { diff --git a/t/t0033-safe-directory.sh b/t/t0033-safe-directory.sh index 9380ff3d017096..6f33c0dfefaaf3 100755 --- a/t/t0033-safe-directory.sh +++ b/t/t0033-safe-directory.sh @@ -21,6 +21,11 @@ test_expect_success 'safe.directory does not match' ' 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 From a5faf3a1779b51195313794fa0a48b7e2009c01b Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Wed, 13 Apr 2022 10:54:32 -0400 Subject: [PATCH 3/3] setup: opt-out of check with safe.directory=* With the addition of the safe.directory in 8959555ce (setup_git_directory(): add an owner check for the top-level directory, 2022-03-02) released in v2.35.2, we are receiving feedback from a variety of users about the feature. Some users have a very large list of shared repositories and find it cumbersome to add this config for every one of them. In a more difficult case, certain workflows involve running Git commands within containers. The container boundary prevents any global or system config from communicating `safe.directory` values from the host into the container. Further, the container almost always runs as a different user than the owner of the directory in the host. To simplify the reactions necessary for these users, extend the definition of the safe.directory config value to include a possible '*' value. This value implies that all directories are safe, providing a single setting to opt-out of this protection. Note that an empty assignment of safe.directory clears all previous values, and this is already the case with the "if (!value || !*value)" condition. Signed-off-by: Derrick Stolee --- Documentation/config/safe.txt | 7 +++++++ setup.c | 6 ++++-- t/t0033-safe-directory.sh | 10 ++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) 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 a995c359c3223f..a42b21307f7708 100644 --- a/setup.c +++ b/setup.c @@ -1103,9 +1103,11 @@ static int safe_directory_cb(const char *key, const char *value, void *d) if (strcmp(key, "safe.directory")) return 0; - if (!value || !*value) + 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) && diff --git a/t/t0033-safe-directory.sh b/t/t0033-safe-directory.sh index 6f33c0dfefaaf3..239d93f4d21141 100755 --- a/t/t0033-safe-directory.sh +++ b/t/t0033-safe-directory.sh @@ -36,4 +36,14 @@ test_expect_success 'safe.directory matches, but is reset' ' 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