All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: git@vger.kernel.org
Cc: Patrick Steinhardt <ps@pks.im>
Subject: [PATCH 8/8] refs: check refnames as fully qualified when resolving
Date: Mon, 29 Apr 2024 04:35:33 -0400	[thread overview]
Message-ID: <20240429083533.GG233423@coredump.intra.peff.net> (raw)

Most code paths for resolving refs end up in refs_resolve_ref_unsafe(),
which checks the names using check_refname_format(). The names we have
at this stage are always full refnames, but we pass the ALLOW_ONELEVEL
flag so that the function allows pseudorefs like MERGE_HEAD. We should
instead pass the FULLY_QUALIFIED flag, which lets check_refname_format()
do some extra syntactic checks on those pseudorefs.

With this patch we'll refuse to read anything outside of refs/ that does
not match the usual pseudoref syntax (all caps plus dashes). This should
not be a loss of functionality (since such refs cannot be written as of
the previous commit), but may protect us from mischief. For example, you
can ask for silly things like "info/refs", "rr-cache/<sha1>/postimage",
or "objects/info/commit-graphs/commit-graph-chain". It's doubtful you
can really do anything _too_ terrible there, but it seems like peeking
at random files in .git in response to possibly untrusted input is
something we should avoid.

Note that because we can't actually write such refs using Git, our tests
have to munge the filesystem manually (and hence only run with the files
backend). They also can only check that resolution fails (and not a
specific error message), since we don't return the "bad name" detail all
the way to the caller.

The second test here, for "main-worktree/bad", actually fails even
without this patch. The worktree-ref code enforces the pseudoref syntax
itself via is_current_worktree_ref(), so the extra checks for this in
check_refname_format() are redundant (though the parsing there is still
necessary so we know _not_ to reject "main-worktree/HEAD"). But either
way it's good to have a test which makes sure this remains the case.

Signed-off-by: Jeff King <peff@peff.net>
---
 refs.c                  |  4 ++--
 t/t1430-bad-ref-name.sh | 10 ++++++++++
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/refs.c b/refs.c
index 57663cfe9e..96f489861b 100644
--- a/refs.c
+++ b/refs.c
@@ -1951,7 +1951,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,
 
 	*flags = 0;
 
-	if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
+	if (check_refname_format(refname, REFNAME_FULLY_QUALIFIED)) {
 		if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
 		    !refname_is_safe(refname))
 			return NULL;
@@ -2010,7 +2010,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,
 			oidclr(oid);
 			return refname;
 		}
-		if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
+		if (check_refname_format(refname, REFNAME_FULLY_QUALIFIED)) {
 			if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
 			    !refname_is_safe(refname))
 				return NULL;
diff --git a/t/t1430-bad-ref-name.sh b/t/t1430-bad-ref-name.sh
index 120e1557d7..5fb780cb08 100755
--- a/t/t1430-bad-ref-name.sh
+++ b/t/t1430-bad-ref-name.sh
@@ -400,4 +400,14 @@ test_expect_success 'update-ref refuses non-underscore outside of refs/' '
 	test_grep "refusing to update ref with bad name" err
 '
 
+test_expect_success REFFILES 'rev-parse refuses non-pseudoref outside of refs/' '
+	git rev-parse HEAD >.git/bad &&
+	test_must_fail git rev-parse --verify bad
+'
+
+test_expect_success REFFILES 'rev-parse recognizes non-pseudoref via worktree' '
+	git rev-parse HEAD >.git/bad &&
+	test_must_fail git rev-parse --verify main-worktree/bad
+'
+
 test_done
-- 
2.45.0.rc1.416.gbe2a76c799

             reply	other threads:[~2024-04-29  8:35 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-29  8:35 Jeff King [this message]
2024-04-30  4:54 ` [PATCH 8/8] refs: check refnames as fully qualified when resolving Patrick Steinhardt
2024-04-30 10:41   ` Jeff King
2024-04-30 11:25     ` Patrick Steinhardt
2024-05-03 17:55       ` Jeff King
2024-05-06  6:22         ` Patrick Steinhardt

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=20240429083533.GG233423@coredump.intra.peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=ps@pks.im \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.