summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2016-02-23 18:15:43 +0100
committerCarlos Martín Nieto <cmn@dwim.me>2016-02-25 15:43:17 +0100
commitea9e00cb5ca271b794cca686019d17cc378e23f2 (patch)
tree50d91a5bdf9d7de250abd4d8a01482c404d55f0b /src
parent43955927e4b4ad004443f07cb5611a1f0ce282a4 (diff)
downloadlibgit2-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.c14
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