diff options
author | Junio C Hamano <gitster@pobox.com> | 2016-03-04 13:45:46 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-03-04 13:45:47 -0800 |
commit | 090de6b289ff2d9fc1c82ef85069bd6cba296d63 (patch) | |
tree | 3b609b0a9989a67abcc8449f80e6626d48f73509 /sha1_file.c | |
parent | bc0ffd41b92c8539fc7dbe27f256d8bae6b28d05 (diff) | |
parent | 7465feba513a8bd3d47f27630ccc9ab7e82d916c (diff) | |
download | git-090de6b289ff2d9fc1c82ef85069bd6cba296d63.tar.gz |
Merge branch 'jk/pack-idx-corruption-safety'
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 02517009c1..d0f2aa029b 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))); } |