better validation on delta base object offsets
authorNicolas Pitre <nico@cam.org>
Wed, 29 Oct 2008 23:02:45 +0000 (19:02 -0400)
committerJunio C Hamano <gitster@pobox.com>
Sun, 2 Nov 2008 23:22:34 +0000 (15:22 -0800)
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>
builtin-pack-objects.c
builtin-unpack-objects.c
index-pack.c
sha1_file.c

index 1591417..cc1e47f 100644 (file)
@@ -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);
index 9f4bdd3..47ed610 100644 (file)
@@ -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) {
index 6f89bb9..da03eee 100644 (file)
@@ -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:
index 88d9cf3..e57949b 100644 (file)
@@ -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) {