diff options
| author | 2016-11-10 01:31:23 +0100 | |
|---|---|---|
| committer | 2016-11-10 01:31:23 +0100 | |
| commit | a4ca24c4fe316bc102b9fa52f808d206ab8cd24b (patch) | |
| tree | 884d0049709a7e011a28b3e7a8c529c262de676a /src | |
| 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.
Diffstat (limited to 'src')
| -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 * | |||
| 708 | uint64_t num_objects = 0; | 708 | uint64_t num_objects = 0; |
| 709 | uint64_t root_object = 0; | 709 | uint64_t root_object = 0; |
| 710 | uint64_t offset_table_index = 0; | 710 | uint64_t offset_table_index = 0; |
| 711 | char *offset_table = NULL; | ||
| 711 | 712 | ||
| 712 | //first check we have enough data | 713 | //first check we have enough data |
| 713 | if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + BPLIST_TRL_SIZE)) | 714 | 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 * | |||
| 727 | num_objects = be64dec(trailer + BPLIST_TRL_NUMOBJ_IDX); | 728 | num_objects = be64dec(trailer + BPLIST_TRL_NUMOBJ_IDX); |
| 728 | root_object = be64dec(trailer + BPLIST_TRL_ROOTOBJ_IDX); | 729 | root_object = be64dec(trailer + BPLIST_TRL_ROOTOBJ_IDX); |
| 729 | offset_table_index = be64dec(trailer + BPLIST_TRL_OFFTAB_IDX); | 730 | offset_table_index = be64dec(trailer + BPLIST_TRL_OFFTAB_IDX); |
| 731 | offset_table = (char *) (plist_bin + offset_table_index); | ||
| 730 | 732 | ||
| 731 | if (num_objects == 0) | 733 | if (num_objects == 0) |
| 732 | return; | 734 | return; |
| @@ -734,13 +736,19 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * | |||
| 734 | if (root_object >= num_objects) | 736 | if (root_object >= num_objects) |
| 735 | return; | 737 | return; |
| 736 | 738 | ||
| 739 | if (offset_table < plist_bin || offset_table >= plist_bin + length) | ||
| 740 | return; | ||
| 741 | |||
| 742 | if (offset_table + num_objects * offset_size >= plist_bin + length) | ||
| 743 | return; | ||
| 744 | |||
| 737 | struct bplist_data bplist; | 745 | struct bplist_data bplist; |
| 738 | bplist.data = plist_bin; | 746 | bplist.data = plist_bin; |
| 739 | bplist.size = length; | 747 | bplist.size = length; |
| 740 | bplist.num_objects = num_objects; | 748 | bplist.num_objects = num_objects; |
| 741 | bplist.dict_size = dict_size; | 749 | bplist.dict_size = dict_size; |
| 742 | bplist.offset_size = offset_size; | 750 | bplist.offset_size = offset_size; |
| 743 | bplist.offset_table = (char *) (plist_bin + offset_table_index); | 751 | bplist.offset_table = offset_table; |
| 744 | bplist.level = 0; | 752 | bplist.level = 0; |
| 745 | bplist.used_indexes = (uint32_t*)malloc(sizeof(uint32_t) * num_objects); | 753 | bplist.used_indexes = (uint32_t*)malloc(sizeof(uint32_t) * num_objects); |
| 746 | 754 | ||
