summaryrefslogtreecommitdiffstats
path: root/sha1_file.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2016-03-10 20:13:46 +0100
committerJunio C Hamano <gitster@pobox.com>2016-03-10 20:13:46 +0100
commit80047fa084f994969d42338bc3fbbb89e7d957d6 (patch)
tree7835a193de3ad2ee6d883ce3bba1d8f1acc9ef73 /sha1_file.c
parentMerge branch 'js/config-set-in-non-repository' into maint (diff)
parentsha1_file.c: mark strings for translation (diff)
downloadgit-80047fa084f994969d42338bc3fbbb89e7d957d6.tar.xz
git-80047fa084f994969d42338bc3fbbb89e7d957d6.zip
Merge branch 'jk/pack-idx-corruption-safety' into maint
The code to read the pack data using the offsets stored in the pack idx file has been made more carefully check the validity of the data in the idx. * jk/pack-idx-corruption-safety: sha1_file.c: mark strings for translation use_pack: handle signed off_t overflow nth_packed_object_offset: bounds-check extended offset t5313: test bounds-checks of corrupted/malicious pack/idx files
Diffstat (limited to 'sha1_file.c')
-rw-r--r--sha1_file.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/sha1_file.c b/sha1_file.c
index ab16c7b98c..b516874473 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1076,6 +1076,8 @@ unsigned char *use_pack(struct packed_git *p,
die("packfile %s cannot be accessed", p->pack_name);
if (offset > (p->pack_size - 20))
die("offset beyond end of packfile (truncated pack?)");
+ if (offset < 0)
+ die(_("offset before end of packfile (broken .idx?)"));
if (!win || !in_window(win, offset)) {
if (win)
@@ -2448,6 +2450,20 @@ const unsigned char *nth_packed_object_sha1(struct packed_git *p,
}
}
+void check_pack_index_ptr(const struct packed_git *p, const void *vptr)
+{
+ const unsigned char *ptr = vptr;
+ const unsigned char *start = p->index_data;
+ const unsigned char *end = start + p->index_size;
+ if (ptr < start)
+ die(_("offset before start of pack index for %s (corrupt index?)"),
+ p->pack_name);
+ /* No need to check for underflow; .idx files must be at least 8 bytes */
+ if (ptr >= end - 8)
+ die(_("offset beyond end of pack index for %s (truncated index?)"),
+ p->pack_name);
+}
+
off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n)
{
const unsigned char *index = p->index_data;
@@ -2461,6 +2477,7 @@ off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n)
if (!(off & 0x80000000))
return off;
index += p->num_objects * 4 + (off & 0x7fffffff) * 8;
+ check_pack_index_ptr(p, index);
return (((uint64_t)ntohl(*((uint32_t *)(index + 0)))) << 32) |
ntohl(*((uint32_t *)(index + 4)));
}