git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 3/3] refs: reject ref updates while GIT_QUARANTINE_PATH is set

From
Jeff King <peff@peff.net>
Date
Apr 10, 2017, 22:14 UTC
Message-ID
<20170410221412.3rxmkwgofc6aqi54@sigill.intra.peff.net>
In-Reply-To
<20170410221058.2ao64wedg2pa6uc2@sigill.intra.peff.net>

As documented in git-receive-pack(1), updating a ref from within the pre-receive hook is dangerous and can corrupt your repo. This patch forbids ref updates entirely during the hook to make it harder for adventurous hook writers to shoot themselves in the foot.

Signed-off-by: Jeff King <peff@peff.net>
---
 Documentation/git-receive-pack.txt |  3 ++-
 refs.c                             |  6 ++++++
 t/t5547-push-quarantine.sh         | 11 +++++++++++
 3 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/Documentation/git-receive-pack.txt b/Documentation/git-receive-pack.txt
index 7267ecfbe..86a4b32f0 100644
--- a/Documentation/git-receive-pack.txt
+++ b/Documentation/git-receive-pack.txt
@@ -239,7 +239,8 @@ This has a few user-visible effects and caveats:
   3. The `pre-receive` hook MUST NOT update any refs to point to
      quarantined objects. Other programs accessing the repository will
      not be able to see the objects (and if the pre-receive hook fails,
-     those refs would become corrupted).
+     those refs would become corrupted). For safety, any ref updates
+     from within `pre-receive` are automatically rejected.
 
 
 SEE ALSO
diff --git a/refs.c b/refs.c
index 0272e332c..62b405d0b 100644
--- a/refs.c
+++ b/refs.c
@@ -1516,6 +1516,12 @@ int ref_transaction_commit(struct ref_transaction *transaction,
 {
 	struct ref_store *refs = get_ref_store(NULL);
 
+	if (getenv(GIT_QUARANTINE_ENVIRONMENT)) {
+		strbuf_addstr(err,
+			      _("ref updates forbidden inside quarantine environment"));
+		return -1;
+	}
+
 	return refs->be->transaction_commit(refs, transaction, err);
 }
 
diff --git a/t/t5547-push-quarantine.sh b/t/t5547-push-quarantine.sh
index af9fcd833..113c87007 100755
--- a/t/t5547-push-quarantine.sh
+++ b/t/t5547-push-quarantine.sh
@@ -58,4 +58,15 @@ test_expect_success 'push to repo path with path separator (colon)' '
 	git push "$(pwd)/xxx${pathsep}yyy.git" HEAD
 '
 
+test_expect_success 'updating a ref from quarantine is forbidden' '
+	git init --bare update.git &&
+	write_script update.git/hooks/pre-receive <<-\EOF &&
+	read old new refname
+	git update-ref refs/heads/unrelated $new
+	exit 1
+	EOF
+	test_must_fail git push update.git HEAD &&
+	git -C update.git fsck
+'
+
 test_done
-- 
2.12.2.952.g759391acc
Previous: Jeff KingNext: Ævar Arnfjörð Bjarmason
Message 4 of 5 in “quarantine-push loose ends”
  1. 0/3 quarantine-push loose endsJeff King, Apr 10, 2017
  2. 1/3 receive-pack: drop tmp_objdir_env from run_update_hookJeff King, Apr 10, 2017
  3. 2/3 receive-pack: document user-visible quarantine effectsJeff King, Apr 10, 2017
  4. 3/3 refs: reject ref updates while GIT_QUARANTINE_PATH is setJeff King, Apr 10, 2017
  5. Ævar Arnfjörð BjarmasonApr 10, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.