summaryrefslogtreecommitdiff
path: root/src/odb.c
diff options
context:
space:
mode:
authorRamsay Jones <ramsay@ramsay1.demon.co.uk>2010-02-21 15:34:53 +0000
committerRamsay Jones <ramsay@ramsay1.demon.co.uk>2010-02-28 20:12:04 +0000
commit238e54bcfff45d477a17cc5a0f51f8ee4bc68bad (patch)
tree9469a286a2240165c93b1940280a86802daa5f85 /src/odb.c
parent255a0dabb28beb56096af18dc20187deca4a545c (diff)
downloadlibgit2-238e54bcfff45d477a17cc5a0f51f8ee4bc68bad.tar.gz
Add an 64-bit offset table index bounds check for v2 pack index
Signed-off-by: Ramsay Jones <ramsay@ramsay1.demon.co.uk>
Diffstat (limited to 'src/odb.c')
-rw-r--r--src/odb.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/odb.c b/src/odb.c
index 5e95e5342..47015c6bb 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -746,8 +746,8 @@ static int pack_openidx_v2(git_pack *p)
unsigned char *data = p->idx_map.data;
uint32_t *src_fanout = (uint32_t *)(data + 8);
uint32_t *im_fanout;
- size_t sz;
- int j;
+ size_t sz, o64_sz, o64_len;
+ uint32_t j;
if ((im_fanout = git__malloc(sizeof(*im_fanout) * 256)) == NULL)
return GIT_ERROR;
@@ -775,6 +775,21 @@ static int pack_openidx_v2(git_pack *p)
p->im_crc = (uint32_t *)(p->im_oid + 20 * p->obj_cnt);
p->im_offset32 = p->im_crc + p->obj_cnt;
p->im_offset64 = p->im_offset32 + p->obj_cnt;
+
+ /* check 64-bit offset table index values are within bounds */
+ o64_sz = p->idx_map.len - sz;
+ o64_len = o64_sz / 8;
+ for (j = 0; j < p->obj_cnt; j++) {
+ uint32_t o32 = decode32(p->im_offset32 + j);
+ if (o32 & 0x80000000) {
+ uint32_t o64_idx = (o32 & ~0x80000000);
+ if (o64_idx >= o64_len) {
+ free(im_fanout);
+ return GIT_ERROR;
+ }
+ }
+ }
+
return GIT_SUCCESS;
}