Skip to content

Commit

Permalink
Merge branch 'jc/safe-directory-leading-path' into maint-2.45
Browse files Browse the repository at this point in the history
The safe.directory configuration knob has been updated to
optionally allow leading path matches.

* jc/safe-directory-leading-path:
  safe.directory: allow "lead/ing/path/*" match
  • Loading branch information
gitster committed Jun 28, 2024
2 parents 7b7db54 + 313eec1 commit ce75d32
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 8 deletions.
3 changes: 2 additions & 1 deletion Documentation/config/safe.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ 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.
that you deem safe. Giving a directory with `/*` appended to it will
allow access to all repositories under the named directory.
+
As explained, Git only allows you to access repositories owned by
yourself, i.e. the user who is running Git, by default. When Git
Expand Down
22 changes: 15 additions & 7 deletions setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1177,13 +1177,21 @@ static int safe_directory_cb(const char *key, const char *value,
} else if (!strcmp(value, "*")) {
data->is_safe = 1;
} 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);
const char *allowed = NULL;

if (!git_config_pathname(&allowed, key, value)) {
if (!allowed)
allowed = value;
if (ends_with(allowed, "/*")) {
size_t len = strlen(allowed);
if (!fspathncmp(allowed, data->path, len - 1))
data->is_safe = 1;
} else if (!fspathcmp(data->path, allowed)) {
data->is_safe = 1;
}
}
if (allowed != value)
free((char *)allowed);
}

return 0;
Expand Down
15 changes: 15 additions & 0 deletions t/t0033-safe-directory.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,22 @@ test_expect_success 'safe.directory=*, but is reset' '
expect_rejected_dir
'

test_expect_success 'safe.directory with matching glob' '
git config --global --unset-all safe.directory &&
p=$(pwd) &&
git config --global safe.directory "${p%/*}/*" &&
git status
'

test_expect_success 'safe.directory with unmatching glob' '
git config --global --unset-all safe.directory &&
p=$(pwd) &&
git config --global safe.directory "${p%/*}no/*" &&
expect_rejected_dir
'

test_expect_success 'safe.directory in included file' '
git config --global --unset-all safe.directory &&
cat >gitconfig-include <<-EOF &&
[safe]
directory = "$(pwd)"
Expand Down

0 comments on commit ce75d32

Please sign in to comment.