diff mbox series

merge-tree: load config correctly

Message ID 20230511215608.1297686-1-felipe.contreras@gmail.com (mailing list archive)
State New, archived
Headers show
Series merge-tree: load config correctly | expand

Commit Message

Felipe Contreras May 11, 2023, 9:56 p.m. UTC
When real merges were implemented in 1f0c3a29da (merge-tree: implement
real merges, 2022-06-18), init_merge_options was called after doing
get_merge_parent, which means core.useReplaceRefs was not parsed at the
moment the commit objects were parsed, and thus essentially this option
was ignored.

This configuration is typically disabled in git hosts due to the ability
to spoof commits in strange ways. Users are able to use refs/replace/
references to make pull requests that look valid but introduce malicious
content. The resulting merge has the correct commit history, but the
malicious content exists in the root tree of the merge.

To fix this let's simply load the configuration before any call to
get_merge_parent().

Cc: Elijah Newren <newren@gmail.com>
Tests-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 builtin/merge-tree.c  |  4 ++--
 t/t4300-merge-tree.sh | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c
index aa8040c2a6..b405cf448f 100644
--- a/builtin/merge-tree.c
+++ b/builtin/merge-tree.c
@@ -424,6 +424,8 @@  static int real_merge(struct merge_tree_options *o,
 	struct merge_result result = { 0 };
 	int show_messages = o->show_messages;
 
+	init_merge_options(&opt, the_repository);
+
 	parent1 = get_merge_parent(branch1);
 	if (!parent1)
 		help_unknown_ref(branch1, "merge-tree",
@@ -434,8 +436,6 @@  static int real_merge(struct merge_tree_options *o,
 		help_unknown_ref(branch2, "merge-tree",
 				 _("not something we can merge"));
 
-	init_merge_options(&opt, the_repository);
-
 	opt.show_rename_progress = 0;
 
 	opt.branch1 = branch1;
diff --git a/t/t4300-merge-tree.sh b/t/t4300-merge-tree.sh
index c52c8a21fa..57c4f26e46 100755
--- a/t/t4300-merge-tree.sh
+++ b/t/t4300-merge-tree.sh
@@ -334,4 +334,22 @@  test_expect_success 'turn tree to file' '
 	test_cmp expect actual
 '
 
+test_expect_success 'merge-tree respects core.useReplaceRefs=false' '
+	test_commit merge-to &&
+	test_commit valid base &&
+	git reset --hard HEAD^ &&
+	test_commit malicious base &&
+
+	test_when_finished "git replace -d $(git rev-parse valid^0)" &&
+	git replace valid^0 malicious^0 &&
+
+	tree=$(git -c core.useReplaceRefs=true merge-tree --write-tree merge-to valid) &&
+	merged=$(git cat-file -p $tree:base) &&
+	test malicious = $merged &&
+
+	tree=$(git -c core.useReplaceRefs=false merge-tree --write-tree merge-to valid) &&
+	merged=$(git cat-file -p $tree:base) &&
+	test valid = $merged
+'
+
 test_done