From: Nicolas Pitre Date: Wed, 29 Oct 2008 23:02:45 +0000 (-0400) Subject: better validation on delta base object offsets X-Git-Tag: v1.6.1-rc1~55^2~9 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=d8f325563d85abcd9816311b3a84093b2d1cda9f;p=git.git better validation on delta base object offsets 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 Signed-off-by: Junio C Hamano --- diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 159141796..cc1e47f41 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 9f4bdd329..47ed61067 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 6f89bb9ac..da03eeeca 100644 --- a/index-pack.c +++ b/index-pack.c @@ -334,7 +334,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 88d9cf357..e57949b41 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) {