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

[PATCH 1/2] t5332-multi-pack-reuse.sh: demonstrate duplicate packing failure

From
Taylor Blau <me@ttaylorr.com>
Date
Nov 13, 2024, 17:32 UTC
Message-ID
<7a69cf84ae5b92d99e5777d4600270712424c4d7.1731518931.git.me@ttaylorr.com>
In-Reply-To
<cover.1731518931.git.me@ttaylorr.com>

In the multi-pack reuse code, there are two paths for reusing the on-disk representation of an object, handled by:

  - builtin/pack-objects.c::write_reused_pack_one()
  - builtin/pack-objects.c::write_reused_pack_verbatim()

The former is responsible for copying the bytes for a single object out of an existing source pack. The latter does the same but for a region of objects aligned at eword_t boundaries.

Demonstrate a bug whereby write_reused_pack_verbatim() can be tricked into writing out objects from some source pack, even when those objects were selected from a different source pack in the MIDX bitmap.

When the caller wants at least one of the objects in that region, pack-objects will write the same object twice as a result of this bug. In the other case where the caller doesn't want any of the objects in the region of interest, we will write out objects that weren't requested.

Demonstrate this bug by creating two packs, where the preferred one of those packs contains a single object which also appears in the main (non-preferred) pack. A separate bug[^1] prevents us from triggering the main bug when the duplicated object is the last one in the main pack, but any earlier object will suffice.

We could fix that separate bug, but the following commit will simplify write_reused_pack_verbatim() and only call it on the preferred pack, so doing so would have little point.

[^1]: Because write_reused_pack_verbatim() only reuses bits in the range
    off_t pack_start_off = pack_pos_to_offset(reuse_packfile->p, 0);
    off_t pack_end_off = pack_pos_to_offset(reuse_packfile->p,
                                            pos - reuse_packfile->bitmap_pos);
    written += pos - reuse_packfile->bitmap_pos;
    /* We're recording one chunk, not one object. */
    record_reused_object(pack_start_off,
                         pack_start_off - (hashfile_total(out) - pack_start));
  , or in other words excluding the object beginning at position 'pos -
  reuse_packfile->bitmap_pos' in the source pack. But since
  reuse_packfile->bitmap_pos is '1' in the non-preferred pack
  (accounting for the single-object pack which is preferred), we don't
  actually copy the bytes from the last object.
Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
---
 t/t5332-multi-pack-reuse.sh | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
diff --git a/t/t5332-multi-pack-reuse.sh b/t/t5332-multi-pack-reuse.sh
index 955ea42769b..8f403d9fdaa 100755
--- a/t/t5332-multi-pack-reuse.sh
+++ b/t/t5332-multi-pack-reuse.sh
@@ -259,4 +259,27 @@ test_expect_success 'duplicate objects' '
 	)
 '
 
+test_expect_failure 'duplicate objects with verbatim reuse' '
+	git init duplicate-objects-verbatim &&
+	(
+		cd duplicate-objects-verbatim &&
+
+		git config pack.allowPackReuse multi &&
+
+		test_commit_bulk 64 &&
+
+		# take the first object from the main pack...
+		git show-index <$(ls $packdir/pack-*.idx) >obj.raw &&
+		sort -nk1 <obj.raw | head -n1 | cut -d" " -f2 >in &&
+
+		# ...and create a separate pack containing just that object
+		p="$(git pack-objects $packdir/pack <in)" &&
+		git show-index <$packdir/pack-$p.idx &&
+
+		git multi-pack-index write --bitmap --preferred-pack=pack-$p.idx &&
+
+		test_pack_objects_reused_all 192 2
+	)
+'
+
 test_done
-- 
2.46.0.421.g159f2d50e75
Previous: Taylor BlauNext: Junio C Hamano
Message 2 of 14 in “pack-objects: more brown-paper-bag multi-pack reuse fixes”
  1. 0/2 pack-objects: more brown-paper-bag multi-pack reuse fixesTaylor Blau, Nov 13, 2024
  2. 1/2 t5332-multi-pack-reuse.sh: demonstrate duplicate packing failureTaylor Blau, Nov 13, 2024
  3. Junio C HamanoNov 14, 2024
  4. Taylor BlauNov 14, 2024
  5. 2/2 pack-objects: only perform verbatim reuse on the preferred packTaylor Blau, Nov 13, 2024
  6. Jeff KingNov 14, 2024
  7. Taylor BlauNov 14, 2024
  8. Jeff KingNov 15, 2024
  9. Kristoffer HaugsbakkNov 22, 2024
  10. 0/2 pack-objects: more brown-paper-bag multi-pack reuse fixesTaylor Blau, Nov 14, 2024
  11. 1/2 t5332-multi-pack-reuse.sh: demonstrate duplicate packing failureTaylor Blau, Nov 14, 2024
  12. 2/2 pack-objects: only perform verbatim reuse on the preferred packTaylor Blau, Nov 14, 2024
  13. Junio C HamanoNov 22, 2024
  14. Jeff KingNov 22, 2024

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.