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

[PATCH v3 1/1] diffcore-break: avoid segfault with freed entries

From
Han Young <hanyang.tony@bytedance.com>
Date
Feb 24, 2026, 06:13 UTC
Message-ID
<20260224061329.60364-2-hanyang.tony@bytedance.com>
In-Reply-To
<20260224061329.60364-1-hanyang.tony@bytedance.com>

After we have freed the file pair, we should set the queue reference to null. When computing a diff in a partial clone, there is a chance that we could trigger a prefetch of missing objects when there are freed entries in the global diff queue due to break-rewrites detection. The segfault only occurs if an entry has been freed by break-rewrites and there is an entry to be prefetched.

There is a new test in t4067 that trigger the segmentation fault that results in this case. The test explicitly fetch the necessary blobs to trigger the break rewrites, some blobs are left to be prefetched.

The fix is to set the queue pointer to NULL after it is freed, the prefetch will skip NULL entries.

Signed-off-by: Han Young <hanyang.tony@bytedance.com>
---
 diffcore-break.c              |  1 +
 t/t4067-diff-partial-clone.sh | 31 +++++++++++++++++++++++++++++++
 2 files changed, 32 insertions(+)
diff --git a/diffcore-break.c b/diffcore-break.c
index c4c2173f30..9b11fe2fa0 100644
--- a/diffcore-break.c
+++ b/diffcore-break.c
@@ -222,6 +222,7 @@ void diffcore_break(struct repository *r, int break_score)
 				free(p); /* not diff_free_filepair(), we are
 					  * reusing one and two here.
 					  */
+				q->queue[i] = NULL;
 				continue;
 			}
 		}
diff --git a/t/t4067-diff-partial-clone.sh b/t/t4067-diff-partial-clone.sh
index 72f25de449..30813109ac 100755
--- a/t/t4067-diff-partial-clone.sh
+++ b/t/t4067-diff-partial-clone.sh
@@ -132,6 +132,37 @@ test_expect_success 'diff with rename detection batches blobs' '
 	test_line_count = 1 done_lines
 '
 
+test_expect_success 'diff succeeds even if prefetch triggered by break-rewrites' '
+	test_when_finished "rm -rf server client trace" &&
+
+	test_create_repo server &&
+	echo xyz >server/foo &&
+	mkdir server/bar &&
+	test_seq -f "line %d" 1 100 >server/bar/baz &&
+	git -C server add -A &&
+	git -C server commit -m x &&
+
+	echo xyzz >server/foo &&
+	test_seq -f "line %d" 90 190 >server/bar/baz &&
+	git -C server add -A &&
+	git -C server commit -m x &&
+
+	test_config -C server uploadpack.allowfilter 1 &&
+	test_config -C server uploadpack.allowanysha1inwant 1 &&
+	git clone --filter=blob:limit=0 "file://$(pwd)/server" client &&
+
+	# Fetch bar/baz without fetching foo.
+	# Foo will be lazily fetched during break rewrites detection.
+	git -C client checkout HEAD~1 bar &&
+
+	# Ensure baz in the working tree is different from baz in HEAD~1.
+	# We need baz to trigger break-rewrites detection.
+	git -C client reset --hard HEAD &&
+
+	# break-rewrites detction in reset.
+	git -C client reset HEAD~1
+'
+
 test_expect_success 'diff succeeds even if entries are removed from queue' '
 	test_when_finished "rm -rf server client trace" &&
 
-- 
2.52.0
Previous: Han YoungNext: Junio C Hamano
Message 10 of 11 in “diffcore-break: prevent dangling pointer”
  1. 0/1 diffcore-break: prevent dangling pointerHan Young, Feb 11, 2026
  2. 1/1 diffcore-break: prevent dangling pointerHan Young, Feb 11, 2026
  3. Junio C HamanoFeb 11, 2026
  4. 0/1 diffcore-break: prevent dangling pointerHan Young, Feb 12, 2026
  5. 1/1 diffcore-break: prevent dangling pointerHan Young, Feb 12, 2026
  6. Junio C HamanoFeb 12, 2026
  7. Han YoungFeb 13, 2026
  8. Junio C HamanoFeb 13, 2026
  9. 0/1 diffcore-break: avoid segfault with freed entriesHan Young, Feb 24, 2026
  10. 1/1 diffcore-break: avoid segfault with freed entriesHan Young, Feb 24, 2026
  11. Junio C HamanoFeb 24, 2026

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.