diff options
author | Junio C Hamano <gitster@pobox.com> | 2016-03-10 20:13:46 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-03-10 20:13:46 +0100 |
commit | 80047fa084f994969d42338bc3fbbb89e7d957d6 (patch) | |
tree | 7835a193de3ad2ee6d883ce3bba1d8f1acc9ef73 /sha1_file.c | |
parent | Merge branch 'js/config-set-in-non-repository' into maint (diff) | |
parent | sha1_file.c: mark strings for translation (diff) | |
download | git-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.c | 17 |
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))); } |