From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Cc: Jeff King <peff@peff.net>,
"brian m. carlson" <sandals@crustytoothpaste.net>,
"W. Michael Petullo" <mike@flyn.org>
Subject: Re: Git clone reads safe.directory differently?
Date: Wed, 31 Jul 2024 15:08:55 -0700 [thread overview]
Message-ID: <xmqq1q391afc.fsf@gitster.g> (raw)
In-Reply-To: <xmqqo76d7coa.fsf@gitster.g> (Junio C. Hamano's message of "Wed, 31 Jul 2024 09:23:49 -0700")
Junio C Hamano <gitster@pobox.com> writes:
> So we probably need to add another axis to the "strict" parameter
> enter_repo() takes to selectively disable the ownership checks only
> for upload-pack, or something like that.
So, here is a rough sketch for the above. Interested parties may
build on top of it, perhaps by adding separate knobs to loosen or
tighten the second parameter given to enter_repo() at different
callsites, by writing tests to make sure they work as intended, and
by documenting the security story around it none of which I do here
;-).
The two bits are
- ENTER_REPO_STRICT: callers that require exact paths (as opposed
to allowing known suffixes like ".git", ".git/.git" to be
omitted) can set this bit. Corresponds to the "strict" parameter
that the flags wordreplaces.
- ENTER_REPO_ANY_OWNER_OK: callers that are willing to run without
ownership check can set this bit.
The former is --strict-paths option of "git daemon". The latter is
set only by upload-pack, but you may want to add configuration knobs
in protected configuration files to loosen it per callsites.
builtin/upload-pack.c | 5 ++++-
daemon.c | 6 ++++--
path.c | 10 ++++++----
path.h | 7 ++++++-
4 files changed, 20 insertions(+), 8 deletions(-)
diff --git c/builtin/upload-pack.c w/builtin/upload-pack.c
index 46d93278d9..fe50ce3eed 100644
--- c/builtin/upload-pack.c
+++ w/builtin/upload-pack.c
@@ -36,6 +36,7 @@ int cmd_upload_pack(int argc, const char **argv, const char *prefix)
N_("interrupt transfer after <n> seconds of inactivity")),
OPT_END()
};
+ unsigned enter_repo_flags = ENTER_REPO_ANY_OWNER_OK;
packet_trace_identity("upload-pack");
disable_replace_refs();
@@ -51,7 +52,9 @@ int cmd_upload_pack(int argc, const char **argv, const char *prefix)
dir = argv[0];
- if (!enter_repo(dir, strict))
+ if (strict)
+ enter_repo_flags |= ENTER_REPO_STRICT;
+ if (!enter_repo(dir, enter_repo_flags))
die("'%s' does not appear to be a git repository", dir);
switch (determine_protocol_version_server()) {
diff --git c/daemon.c w/daemon.c
index 17d331b2f3..fb37135521 100644
--- c/daemon.c
+++ w/daemon.c
@@ -149,6 +149,7 @@ static const char *path_ok(const char *directory, struct hostinfo *hi)
size_t rlen;
const char *path;
const char *dir;
+ unsigned enter_repo_flags;
dir = directory;
@@ -239,14 +240,15 @@ static const char *path_ok(const char *directory, struct hostinfo *hi)
dir = rpath;
}
- path = enter_repo(dir, strict_paths);
+ enter_repo_flags = strict_paths ? ENTER_REPO_STRICT : 0;
+ path = enter_repo(dir, enter_repo_flags);
if (!path && base_path && base_path_relaxed) {
/*
* if we fail and base_path_relaxed is enabled, try without
* prefixing the base path
*/
dir = directory;
- path = enter_repo(dir, strict_paths);
+ path = enter_repo(dir, enter_repo_flags);
}
if (!path) {
diff --git c/path.c w/path.c
index 19f7684f38..df5aefdb8f 100644
--- c/path.c
+++ w/path.c
@@ -727,7 +727,7 @@ char *interpolate_path(const char *path, int real_home)
* links. User relative paths are also returned as they are given,
* except DWIM suffixing.
*/
-const char *enter_repo(const char *path, int strict)
+const char *enter_repo(const char *path, unsigned flags)
{
static struct strbuf validated_path = STRBUF_INIT;
static struct strbuf used_path = STRBUF_INIT;
@@ -735,7 +735,7 @@ const char *enter_repo(const char *path, int strict)
if (!path)
return NULL;
- if (!strict) {
+ if (!(flags & ENTER_REPO_STRICT)) {
static const char *suffix[] = {
"/.git", "", ".git/.git", ".git", NULL,
};
@@ -779,7 +779,8 @@ 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 (!(flags & ENTER_REPO_ANY_OWNER_OK))
+ die_upon_dubious_ownership(gitfile, NULL, used_path.buf);
if (gitfile) {
strbuf_reset(&used_path);
strbuf_addstr(&used_path, gitfile);
@@ -790,7 +791,8 @@ const char *enter_repo(const char *path, int strict)
}
else {
const char *gitfile = read_gitfile(path);
- die_upon_dubious_ownership(gitfile, NULL, path);
+ if (!(flags & ENTER_REPO_ANY_OWNER_OK))
+ die_upon_dubious_ownership(gitfile, NULL, path);
if (gitfile)
path = gitfile;
if (chdir(path))
diff --git c/path.h w/path.h
index a6f0b70692..a0021a1425 100644
--- c/path.h
+++ w/path.h
@@ -187,7 +187,12 @@ int calc_shared_perm(int mode);
int adjust_shared_perm(const char *path);
char *interpolate_path(const char *path, int real_home);
-const char *enter_repo(const char *path, int strict);
+
+enum {
+ ENTER_REPO_STRICT = (1<<0),
+ ENTER_REPO_ANY_OWNER_OK = (1<<1),
+};
+const char *enter_repo(const char *path, unsigned flags);
const char *remove_leading_path(const char *in, const char *prefix);
const char *relative_path(const char *in, const char *prefix, struct strbuf *sb);
int normalize_path_copy_len(char *dst, const char *src, int *prefix_len);
next prev parent reply other threads:[~2024-07-31 22:09 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-27 16:14 Git clone reads safe.directory differently? W. Michael Petullo
2024-07-27 21:58 ` Jeff King
2024-07-28 15:27 ` W. Michael Petullo
2024-07-28 22:48 ` Jeff King
2024-07-30 11:37 ` W. Michael Petullo
2024-07-30 22:28 ` brian m. carlson
2024-07-30 22:49 ` Junio C Hamano
2024-07-30 22:55 ` Junio C Hamano
2024-07-30 23:05 ` brian m. carlson
2024-07-31 7:28 ` Jeff King
2024-07-31 16:23 ` Junio C Hamano
2024-07-31 22:08 ` Junio C Hamano [this message]
2024-08-01 6:14 ` Jeff King
2024-08-01 14:59 ` Junio C Hamano
2024-08-01 21:26 ` brian m. carlson
2024-08-01 21:52 ` Junio C Hamano
2024-08-05 9:47 ` Jeff King
2024-08-05 15:34 ` W. Michael Petullo
2024-08-05 15:49 ` Junio C Hamano
2024-08-01 6:08 ` Jeff King
2024-07-31 7:19 ` Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqq1q391afc.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=mike@flyn.org \
--cc=peff@peff.net \
--cc=sandals@crustytoothpaste.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).