diff options
author | Filippo Bigarella | 2016-11-10 01:31:23 +0100 |
---|---|---|
committer | Nikias Bassen | 2016-11-10 01:31:23 +0100 |
commit | a4ca24c4fe316bc102b9fa52f808d206ab8cd24b (patch) | |
tree | 884d0049709a7e011a28b3e7a8c529c262de676a | |
parent | 1ae55728f427532234be85a90322e4a3c77b4074 (diff) | |
download | libplist-a4ca24c4fe316bc102b9fa52f808d206ab8cd24b.tar.gz libplist-a4ca24c4fe316bc102b9fa52f808d206ab8cd24b.tar.bz2 |
bplist: Prevent out-of-bounds read in plist_from_bin() when parsing offset_table
offset_table_index is read from the file, so we have full control over it.
This means we can point offset_table essentially anywhere we want, which can
lead to an out-of-bounds read when it will be used later on.
-rw-r--r-- | src/bplist.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/bplist.c b/src/bplist.c index 8447187..be82b4e 100644 --- a/src/bplist.c +++ b/src/bplist.c @@ -708,6 +708,7 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * uint64_t num_objects = 0; uint64_t root_object = 0; uint64_t offset_table_index = 0; + char *offset_table = NULL; //first check we have enough data if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + BPLIST_TRL_SIZE)) @@ -727,6 +728,7 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * num_objects = be64dec(trailer + BPLIST_TRL_NUMOBJ_IDX); root_object = be64dec(trailer + BPLIST_TRL_ROOTOBJ_IDX); offset_table_index = be64dec(trailer + BPLIST_TRL_OFFTAB_IDX); + offset_table = (char *) (plist_bin + offset_table_index); if (num_objects == 0) return; @@ -734,13 +736,19 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * if (root_object >= num_objects) return; + if (offset_table < plist_bin || offset_table >= plist_bin + length) + return; + + if (offset_table + num_objects * offset_size >= plist_bin + length) + return; + struct bplist_data bplist; bplist.data = plist_bin; bplist.size = length; bplist.num_objects = num_objects; bplist.dict_size = dict_size; bplist.offset_size = offset_size; - bplist.offset_table = (char *) (plist_bin + offset_table_index); + bplist.offset_table = offset_table; bplist.level = 0; bplist.used_indexes = (uint32_t*)malloc(sizeof(uint32_t) * num_objects); |