diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2016-02-23 18:15:43 +0100 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2016-02-25 15:43:17 +0100 |
commit | ea9e00cb5ca271b794cca686019d17cc378e23f2 (patch) | |
tree | 50d91a5bdf9d7de250abd4d8a01482c404d55f0b /src | |
parent | 43955927e4b4ad004443f07cb5611a1f0ce282a4 (diff) | |
download | libgit2-ea9e00cb5ca271b794cca686019d17cc378e23f2.tar.gz |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/pack.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/src/pack.c b/src/pack.c index 081e37084..b9b22a2ef 100644 --- a/src/pack.c +++ b/src/pack.c @@ -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) { const unsigned char *index = p->index_map.data; + const unsigned char *end = index + p->index_map.len; index += 4 * 256; if (p->index_version == 1) { 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_ if (!(off & 0x80000000)) return off; 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) | ntohl(*((uint32_t *)(index + 4))); } @@ -1264,6 +1270,7 @@ static int pack_entry_find_offset( const unsigned char *index = p->index_map.data; unsigned hi, lo, stride; int pos, found = 0; + git_off_t offset; const unsigned char *current = 0; *offset_out = 0; @@ -1336,7 +1343,12 @@ static int pack_entry_find_offset( if (found > 1) 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); #ifdef INDEX_DEBUG_LOOKUP |