Commit ea9e00cb by Carlos Martín Nieto

pack: make sure we don't go out of bounds for extended entries

A corrupt index might have data that tells us to go look past the end of
the file for data. Catch these cases and return an appropriate error
message.
parent 43955927
...@@ -1175,6 +1175,7 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path) ...@@ -1175,6 +1175,7 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path)
static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n) static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_t n)
{ {
const unsigned char *index = p->index_map.data; const unsigned char *index = p->index_map.data;
const unsigned char *end = index + p->index_map.len;
index += 4 * 256; index += 4 * 256;
if (p->index_version == 1) { if (p->index_version == 1) {
return ntohl(*((uint32_t *)(index + 24 * n))); return ntohl(*((uint32_t *)(index + 24 * n)));
...@@ -1185,6 +1186,11 @@ static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_ ...@@ -1185,6 +1186,11 @@ static git_off_t nth_packed_object_offset(const struct git_pack_file *p, uint32_
if (!(off & 0x80000000)) if (!(off & 0x80000000))
return off; return off;
index += p->num_objects * 4 + (off & 0x7fffffff) * 8; index += p->num_objects * 4 + (off & 0x7fffffff) * 8;
/* Make sure we're not being sent out of bounds */
if (index >= end - 8)
return -1;
return (((uint64_t)ntohl(*((uint32_t *)(index + 0)))) << 32) | return (((uint64_t)ntohl(*((uint32_t *)(index + 0)))) << 32) |
ntohl(*((uint32_t *)(index + 4))); ntohl(*((uint32_t *)(index + 4)));
} }
...@@ -1264,6 +1270,7 @@ static int pack_entry_find_offset( ...@@ -1264,6 +1270,7 @@ static int pack_entry_find_offset(
const unsigned char *index = p->index_map.data; const unsigned char *index = p->index_map.data;
unsigned hi, lo, stride; unsigned hi, lo, stride;
int pos, found = 0; int pos, found = 0;
git_off_t offset;
const unsigned char *current = 0; const unsigned char *current = 0;
*offset_out = 0; *offset_out = 0;
...@@ -1336,7 +1343,12 @@ static int pack_entry_find_offset( ...@@ -1336,7 +1343,12 @@ static int pack_entry_find_offset(
if (found > 1) if (found > 1)
return git_odb__error_ambiguous("found multiple offsets for pack entry"); return git_odb__error_ambiguous("found multiple offsets for pack entry");
*offset_out = nth_packed_object_offset(p, pos); if ((offset = nth_packed_object_offset(p, pos)) < 0) {
giterr_set(GITERR_ODB, "packfile index is corrupt");
return -1;
}
*offset_out = offset;
git_oid_fromraw(found_oid, current); git_oid_fromraw(found_oid, current);
#ifdef INDEX_DEBUG_LOOKUP #ifdef INDEX_DEBUG_LOOKUP
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment