Re: [PATCH] [RFC] setup.c: make bare repo discovery optional
- From
Junio C Hamano <gitster@pobox.com>
- Date
- May 6, 2022, 20:33 UTC
- Message-ID
- <xmqqmtfujt9h.fsf@gitster.g>
- In-Reply-To
- <pull.1261.git.git.1651861810633.gitgitgadget@gmail.com>
"Glen Choo via GitGitGadget" <gitgitgadget@gmail.com> writes:
Show 6 quoted lines
> From: Glen Choo <chooglen@google.com> > > Add a config variable, `safe.barerepository`, that tells Git whether or > not to recognize bare repositories when it is trying to discover the > repository. This only affects repository discovery, thus it has no > effect if discovery was not done (e.g. `--git-dir` was passed).
Show 13 quoted lines
> +safe.barerepository:: > + This config entry specifies directories that Git can recognize as > + a bare repository when looking for the repository (aka repository > + discovery). This has no effect if repository discovery is not > + performed e.g. the path to the repository is set via `--git-dir` > + (see linkgit:git[1]). > ++ > +It is recommended that you set this value so that Git will only use the bare > +repositories you intend it to. This prevents certain types of security and > +non-security problems, such as: > + > +* `git clone`-ing a repository containing a maliciously bare repository > + inside it.
"maliciously bare"? "malicious bare" probably.
> +* Git recognizing a directory that isn't mean to be a bare repository,
"mean to be" -> "meant to be".
> + but happens to look like one.
Show 54 quoted lines
> diff --git a/setup.c b/setup.c
> index a7b36f3ffbf..9b5dd877273 100644
> --- a/setup.c
> +++ b/setup.c
> @@ -1133,6 +1133,40 @@ static int ensure_valid_ownership(const char *path)
> return data.is_safe;
> }
>
> +/*
> + * This is similar to safe_directory_data, but only supports true/false.
> + */
> +struct safe_bare_repository_data {
> + int is_safe;
> +};
> +
> +static int safe_bare_repository_cb(const char *key, const char *value, void *d)
> +{
> + struct safe_bare_repository_data *data = d;
> +
> + if (strcmp(key, "safe.barerepository"))
> + return 0;
> +
> + if (!value || !strcmp(value, "*")) {
> + data->is_safe = 1;
> + return 0;
> + }
> + if (!*value) {
> + data->is_safe = 0;
> + return 0;
> + }
> + return -1;
> +}
> +
> +static int should_detect_bare(void)
> +{
> + struct safe_bare_repository_data data;
> +
> + read_very_early_config(safe_bare_repository_cb, &data);
> +
> + return data.is_safe;
> +}
> +
> enum discovery_result {
> GIT_DIR_NONE = 0,
> GIT_DIR_EXPLICIT,
> @@ -1238,7 +1272,7 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
> return GIT_DIR_DISCOVERED;
> }
>
> - if (is_git_directory(dir->buf)) {
> + if (should_detect_bare() && is_git_directory(dir->buf)) {
> if (!ensure_valid_ownership(dir->buf))
> return GIT_DIR_INVALID_OWNERSHIP;
> strbuf_addstr(gitdir, ".");This is in a loop, which will go up and try the parent directory if the body of this block is not entered, so it is calling the new should_detect_bare() helper over and over if it returns false.
Not a very good idea.
Perhaps this would help? I dunno.
static int should_detect_bare(void)
{
static int should = -1; /* unknown yet */ if (should < 0) {
struct safe_bare_repository_data data = { 0 };
read_very_early_config(safe_bare_repository_cb, &data);
should = data.is_safe;
}
return should;
}In any case, I very much appreciate the fact that this touches the setup_git_directory_gently_1() codepath only minimally, as we have other plans to update the code further soonish.
Thanks.