@matheusbsbs / matheus-bagliano / commits / d8f325563d
Fork 0

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 <nico@cam.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nicolas Pitre committed Oct 29, 2008 at 19:02 UTC d8f325563d85abcd9816311b3a84093b2d1cda9f
4 files changed +6 -4
builtin-pack-objects.c
+2 -2
@@ -1038,10 +1038,10 @@ static void check_object(struct object_entry *entry)
1038 c = buf[used_0++];
1039 ofs = (ofs << 7) + (c & 127);
1040 }
1041 - if (ofs >= entry->in_pack_offset)
1041 + ofs = entry->in_pack_offset - ofs;
1042 + if (ofs <= 0 || ofs >= entry->in_pack_offset)
1043 die("delta base offset out of bound for %s",
1044 sha1_to_hex(entry->idx.sha1));
1044 - ofs = entry->in_pack_offset - ofs;
1045 if (reuse_delta && !entry->preferred_base) {
1046 struct revindex_entry *revidx;
1047 revidx = find_pack_revindex(p, ofs);
builtin-unpack-objects.c
+2
@@ -370,6 +370,8 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
370 base_offset = (base_offset << 7) + (c & 127);
371 }
372 base_offset = obj_list[nr].offset - base_offset;
373 + if (base_offset <= 0 || base_offset >= obj_list[nr].offset)
374 + die("offset value out of bound for delta base object");
375
376 delta_data = get_data(delta_size);
377 if (dry_run || !delta_data) {
index-pack.c
+1 -1
@@ -334,7 +334,7 @@ static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_
334 base_offset = (base_offset << 7) + (c & 127);
335 }
336 delta_base->offset = obj->idx.offset - base_offset;
337 - if (delta_base->offset >= obj->idx.offset)
337 + if (delta_base->offset <= 0 || delta_base->offset >= obj->idx.offset)
338 bad_object(obj->idx.offset, "delta base offset is out of bound");
339 break;
340 case OBJ_COMMIT:
sha1_file.c
+1 -1
@@ -1355,7 +1355,7 @@ static off_t get_delta_base(struct packed_git *p,
1355 base_offset = (base_offset << 7) + (c & 127);
1356 }
1357 base_offset = delta_obj_offset - base_offset;
1358 - if (base_offset >= delta_obj_offset)
1358 + if (base_offset <= 0 || base_offset >= delta_obj_offset)
1359 return 0; /* out of bound */
1360 *curpos += used;
1361 } else if (type == OBJ_REF_DELTA) {