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

[PATCH 2/9] better validation on delta base object offsets

From
Nicolas Pitre <nico@cam.org>
Date
Oct 29, 2008, 23:02 UTC
Message-ID
<1225321372-6570-3-git-send-email-nico@cam.org>
In-Reply-To
<1225321372-6570-2-git-send-email-nico@cam.org>

In one case, it was possible to have a bad offset equal to 0 effectively pointing a delta onto itself and crashing git after too many recursions. In the other cases, a negative offset could result due to off_t being signed. Catch those.

Signed-off-by: Nicolas Pitre <nico@cam.org>
---
 builtin-pack-objects.c   |    4 ++--
 builtin-unpack-objects.c |    2 ++
 index-pack.c             |    2 +-
 sha1_file.c              |    2 +-
 4 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 0366277..d4c721b 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -1038,10 +1038,10 @@ static void check_object(struct object_entry *entry)
 				c = buf[used_0++];
 				ofs = (ofs << 7) + (c & 127);
 			}
-			if (ofs >= entry->in_pack_offset)
+			ofs = entry->in_pack_offset - ofs;
+			if (ofs <= 0 || ofs >= entry->in_pack_offset)
 				die("delta base offset out of bound for %s",
 				    sha1_to_hex(entry->idx.sha1));
-			ofs = entry->in_pack_offset - ofs;
 			if (reuse_delta && !entry->preferred_base) {
 				struct revindex_entry *revidx;
 				revidx = find_pack_revindex(p, ofs);
diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
index 9f4bdd3..47ed610 100644
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
@@ -370,6 +370,8 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
 			base_offset = (base_offset << 7) + (c & 127);
 		}
 		base_offset = obj_list[nr].offset - base_offset;
+		if (base_offset <= 0 || base_offset >= obj_list[nr].offset)
+			die("offset value out of bound for delta base object");
 
 		delta_data = get_data(delta_size);
 		if (dry_run || !delta_data) {
diff --git a/index-pack.c b/index-pack.c
index fe75332..60ed41a 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -338,7 +338,7 @@ static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_
 			base_offset = (base_offset << 7) + (c & 127);
 		}
 		delta_base->offset = obj->idx.offset - base_offset;
-		if (delta_base->offset >= obj->idx.offset)
+		if (delta_base->offset <= 0 || delta_base->offset >= obj->idx.offset)
 			bad_object(obj->idx.offset, "delta base offset is out of bound");
 		break;
 	case OBJ_COMMIT:
diff --git a/sha1_file.c b/sha1_file.c
index 88d9cf3..e57949b 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1355,7 +1355,7 @@ static off_t get_delta_base(struct packed_git *p,
 			base_offset = (base_offset << 7) + (c & 127);
 		}
 		base_offset = delta_obj_offset - base_offset;
-		if (base_offset >= delta_obj_offset)
+		if (base_offset <= 0 || base_offset >= delta_obj_offset)
 			return 0;  /* out of bound */
 		*curpos += used;
 	} else if (type == OBJ_REF_DELTA) {
-- 
1.6.0.3.757.g01be.dirty
Previous: Nicolas PitreNext: Nicolas Pitre
Message 3 of 12 in “more robustness against pack corruptions”
  1. 0/9 more robustness against pack corruptionsNicolas Pitre, Oct 29, 2008
  2. 1/9 close another possibility for propagating pack corruptionNicolas Pitre, Oct 29, 2008
  3. 2/9 better validation on delta base object offsetsNicolas Pitre, Oct 29, 2008
  4. 3/9 make unpack_object_header() non fatalNicolas Pitre, Oct 29, 2008
  5. 4/9 make packed_object_info() resilient to pack corruptionsNicolas Pitre, Oct 29, 2008
  6. 5/9 make check_object() resilient to pack corruptionsNicolas Pitre, Oct 29, 2008
  7. 6/9 make find_pack_revindex() aware of the nasty worldNicolas Pitre, Oct 29, 2008
  8. 7/9 pack-objects: allow "fixing" a corrupted pack without a full repackNicolas Pitre, Oct 29, 2008
  9. 8/9 extend test coverage for latest pack corruption resilience improvementsNicolas Pitre, Oct 29, 2008
  10. 9/9 pack-objects: don't leak pack window reference when splitting packsNicolas Pitre, Oct 29, 2008
  11. Junio C HamanoOct 31, 2008
  12. Nicolas PitreOct 31, 2008

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.