From ea9e00cb5ca271b794cca686019d17cc378e23f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 23 Feb 2016 18:15:43 +0100 Subject: [PATCH 1/2] 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. --- src/pack.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) 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 From 6d97beb91f413f4e90bab76fc7e05495bb0aab70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Thu, 25 Feb 2016 15:46:59 +0100 Subject: [PATCH 2/2] pack: don't allow a negative offset --- src/pack.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/pack.c b/src/pack.c index b9b22a2ef..52c652178 100644 --- a/src/pack.c +++ b/src/pack.c @@ -365,9 +365,14 @@ static unsigned char *pack_window_open( * pointless to ask for an offset into the middle of that * hash, and the pack_window_contains function above wouldn't match * don't allow an offset too close to the end of the file. + * + * Don't allow a negative offset, as that means we've wrapped + * around. */ if (offset > (p->mwf.size - 20)) return NULL; + if (offset < 0) + return NULL; return git_mwindow_open(&p->mwf, w_cursor, offset, 20, left); }