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

[PATCH v2 6/7] pack-objects: do not truncate result in-pack object size on 32-bit systems

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Jul 13, 2016, 15:44 UTC
Message-ID
<20160713154404.22909-7-pclouds@gmail.com>
In-Reply-To
<20160713154404.22909-1-pclouds@gmail.com>

A typical diff will not show what's going on and you need to see full functions. The core code is like this, at the end of of write_one()

	e->idx.offset = *offset;
	size = write_object(f, e, *offset);
	if (!size) {
		e->idx.offset = recursing;
		return WRITE_ONE_BREAK;
	}
	written_list[nr_written++] = &e->idx;
	/* make sure off_t is sufficiently large not to wrap */
	if (signed_add_overflows(*offset, size))
		die("pack too large for current definition of off_t");
	*offset += size;

Here we can see that the in-pack object size is returned by write_object (or indirectly by write_reuse_object). And it's used to calculate object offsets, which end up in the pack index file, generated at the end.

If "size" overflows (on 32-bit sytems, unsigned long is 32-bit while off_t can be 64-bit), we got wrong offsets and produce incorrect .idx file, which may make it look like the .pack file is corrupted.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/pack-objects.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index a3a98c5..ac7a3a5 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -341,8 +341,8 @@ static unsigned long write_no_reuse_object(struct sha1file *f, struct object_ent
 }
 
 /* Return 0 if we will bust the pack-size limit */
-static unsigned long write_reuse_object(struct sha1file *f, struct object_entry *entry,
-					unsigned long limit, int usable_delta)
+static off_t write_reuse_object(struct sha1file *f, struct object_entry *entry,
+				unsigned long limit, int usable_delta)
 {
 	struct packed_git *p = entry->in_pack;
 	struct pack_window *w_curs = NULL;
@@ -415,11 +415,12 @@ static unsigned long write_reuse_object(struct sha1file *f, struct object_entry
 }
 
 /* Return 0 if we will bust the pack-size limit */
-static unsigned long write_object(struct sha1file *f,
-				  struct object_entry *entry,
-				  off_t write_offset)
+static off_t write_object(struct sha1file *f,
+			  struct object_entry *entry,
+			  off_t write_offset)
 {
-	unsigned long limit, len;
+	unsigned long limit;
+	off_t len;
 	int usable_delta, to_reuse;
 
 	if (!pack_to_stdout)
@@ -491,7 +492,7 @@ static enum write_one_status write_one(struct sha1file *f,
 				       struct object_entry *e,
 				       off_t *offset)
 {
-	unsigned long size;
+	off_t size;
 	int recursing;
 
 	/*
-- 
2.9.1.564.gb2f7278
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 35 of 39 in “[bug] Reliably Reproducible Bad Packing of Objects”
  1. Christoph MichelbachJun 24, 2016
  2. Duy NguyenJul 2, 2016
  3. Duy NguyenJul 2, 2016
  4. 0/5 Number truncation with 4+ GB files on 32-bit systemsNguyễn Thái Ngọc Duy, Jul 5, 2016
  5. 1/5 pack-objects: pass length to check_pack_crc() without truncationNguyễn Thái Ngọc Duy, Jul 5, 2016
  6. Junio C HamanoJul 12, 2016
  7. 5/5 index-pack: correct "offset" type in unpack_entry_data()Nguyễn Thái Ngọc Duy, Jul 5, 2016
  8. 4/5 index-pack: report correct bad object offsets even if they are largeNguyễn Thái Ngọc Duy, Jul 5, 2016
  9. Junio C HamanoJul 12, 2016
  10. Junio C HamanoJul 12, 2016
  11. 2/5 sha1_file.c: use type off_t* for object_info->disk_sizepNguyễn Thái Ngọc Duy, Jul 5, 2016
  12. Junio C HamanoJul 12, 2016
  13. Junio C HamanoJul 12, 2016
  14. 3/5 index-pack: correct "len" type in unpack_data()Nguyễn Thái Ngọc Duy, Jul 5, 2016
  15. Johannes SixtJul 5, 2016
  16. Duy NguyenJul 6, 2016
  17. Junio C HamanoJul 6, 2016
  18. Junio C HamanoJul 6, 2016
  19. Christoph MichelbachJul 5, 2016
  20. Duy NguyenJul 10, 2016
  21. 6/5 pack-objects: do not truncate result in-pack object size on 32-bit systemsNguyễn Thái Ngọc Duy, Jul 10, 2016
  22. 7/5 fsck: use streaming interface for large blobs in packNguyễn Thái Ngọc Duy, Jul 10, 2016
  23. Junio C HamanoJul 12, 2016
  24. Junio C HamanoJul 12, 2016
  25. Junio C HamanoJul 12, 2016
  26. Junio C HamanoJul 12, 2016
  27. Junio C HamanoJul 12, 2016
  28. Duy NguyenJul 13, 2016
  29. 0/7 Number truncation with 4+ GB files on 32-bit systemsNguyễn Thái Ngọc Duy, Jul 13, 2016
  30. 4/7 index-pack: report correct bad object offsets even if they are largeNguyễn Thái Ngọc Duy, Jul 13, 2016
  31. 3/7 index-pack: correct "len" type in unpack_data()Nguyễn Thái Ngọc Duy, Jul 13, 2016
  32. 2/7 sha1_file.c: use type off_t* for object_info->disk_sizepNguyễn Thái Ngọc Duy, Jul 13, 2016
  33. 5/7 index-pack: correct "offset" type in unpack_entry_data()Nguyễn Thái Ngọc Duy, Jul 13, 2016
  34. 7/7 fsck: use streaming interface for large blobs in packNguyễn Thái Ngọc Duy, Jul 13, 2016
  35. 6/7 pack-objects: do not truncate result in-pack object size on 32-bit systemsNguyễn Thái Ngọc Duy, Jul 13, 2016
  36. 1/7 pack-objects: pass length to check_pack_crc() without truncationNguyễn Thái Ngọc Duy, Jul 13, 2016
  37. Junio C HamanoJul 13, 2016
  38. Christoph MichelbachJul 6, 2016
  39. Duy NguyenJul 6, 2016

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.