summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 8723f21)
raw | patch | inline | side by side (parent: 8723f21)
author | Nicolas Pitre <nico@cam.org> | |
Mon, 9 Apr 2007 05:06:30 +0000 (01:06 -0400) | ||
committer | Junio C Hamano <junkio@cox.net> | |
Tue, 10 Apr 2007 19:48:14 +0000 (12:48 -0700) |
Change a few size and offset variables to more appropriate type, then
add overflow tests on those offsets. This prevents any bad data to be
generated/processed if off_t happens to not be large enough to handle
some big packs.
Better be safe than sorry.
Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
add overflow tests on those offsets. This prevents any bad data to be
generated/processed if off_t happens to not be large enough to handle
some big packs.
Better be safe than sorry.
Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
builtin-pack-objects.c | patch | blob | history | |
builtin-unpack-objects.c | patch | blob | history | |
index-pack.c | patch | blob | history |
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index ee607a0d2c086d93d9d9f56453a4e79e397b4a20..d0be879443c16fe7b2fec319a9965ae13af28a9b 100644 (file)
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
return check_loose_inflate(map, mapsize, size);
}
-static off_t write_object(struct sha1file *f,
+static unsigned long write_object(struct sha1file *f,
struct object_entry *entry)
{
unsigned long size;
struct object_entry *e,
off_t offset)
{
+ unsigned long size;
+
+ /* offset is non zero if object is written already. */
if (e->offset || e->preferred_base)
- /* offset starts from header size and cannot be zero
- * if it is written already.
- */
return offset;
- /* if we are deltified, write out its base object first. */
+
+ /* if we are deltified, write out base object first. */
if (e->delta)
offset = write_one(f, e->delta, offset);
+
e->offset = offset;
- return offset + write_object(f, e);
+ size = write_object(f, e);
+
+ /* make sure off_t is sufficiently large not to wrap */
+ if (offset > offset + size)
+ die("pack too large for current definition of off_t");
+ return offset + size;
}
static void write_pack_file(void)
index 63f7db6831f7d5408ddf67d0f7f882c4a7b236cd..f8219064602775346bb0d8a323339b3d077da31c 100644 (file)
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
/* We always read in 4kB chunks. */
static unsigned char buffer[4096];
-static unsigned long offset, len, consumed_bytes;
+static unsigned int offset, len;
+static off_t consumed_bytes;
static SHA_CTX ctx;
/*
die("used more bytes than were available");
len -= bytes;
offset += bytes;
+
+ /* make sure off_t is sufficiently large not to wrap */
+ if (consumed_bytes > consumed_bytes + bytes)
+ die("pack too large for current definition of off_t");
consumed_bytes += bytes;
}
struct delta_info {
unsigned char base_sha1[20];
- unsigned long base_offset;
+ unsigned nr;
+ off_t base_offset;
unsigned long size;
void *delta;
- unsigned nr;
struct delta_info *next;
};
static struct delta_info *delta_list;
static void add_delta_to_list(unsigned nr, unsigned const char *base_sha1,
- unsigned long base_offset,
+ off_t base_offset,
void *delta, unsigned long size)
{
struct delta_info *info = xmalloc(sizeof(*info));
}
struct obj_info {
- unsigned long offset;
+ off_t offset;
unsigned char sha1[20];
};
} else {
unsigned base_found = 0;
unsigned char *pack, c;
- unsigned long base_offset;
+ off_t base_offset;
unsigned lo, mid, hi;
pack = fill(1);
diff --git a/index-pack.c b/index-pack.c
index 0e54aa68448bab2497f16e57f34537f7ac884f37..66fb0bcedf17a6205ec21aef2ad67c51f791bca7 100644 (file)
--- a/index-pack.c
+++ b/index-pack.c
struct object_entry
{
- unsigned long offset;
+ off_t offset;
unsigned long size;
unsigned int hdr_size;
enum object_type type;
union delta_base {
unsigned char sha1[20];
- unsigned long offset;
+ off_t offset;
};
/*
/* We always read in 4kB chunks. */
static unsigned char input_buffer[4096];
-static unsigned long input_offset, input_len, consumed_bytes;
+static unsigned int input_offset, input_len;
+static off_t consumed_bytes;
static SHA_CTX input_ctx;
static int input_fd, output_fd, pack_fd;
die("used more bytes than were available");
input_len -= bytes;
input_offset += bytes;
+
+ /* make sure off_t is sufficiently large not to wrap */
+ if (consumed_bytes > consumed_bytes + bytes)
+ die("pack too large for current definition of off_t");
consumed_bytes += bytes;
}
static void *unpack_raw_entry(struct object_entry *obj, union delta_base *delta_base)
{
unsigned char *p, c;
- unsigned long size, base_offset;
+ unsigned long size;
+ off_t base_offset;
unsigned shift;
obj->offset = consumed_bytes;