summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2017-02-01 20:22:38 +0100
committerGravatar Nikias Bassen2017-02-01 20:22:38 +0100
commit4765d9a60ca4248a8f89289271ac69cbffcc29bc (patch)
tree93f86049f659d89d63a6d1163844e8ad6e7a0bdb
parent5791fb908a5f4e3ae39f8c4644dc7f0291f0e80f (diff)
downloadlibplist-4765d9a60ca4248a8f89289271ac69cbffcc29bc.tar.gz
libplist-4765d9a60ca4248a8f89289271ac69cbffcc29bc.tar.bz2
bplist: Fix possible out-of-bounds read in parse_array_node() with proper bounds checking
-rw-r--r--src/bplist.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/bplist.c b/src/bplist.c
index 2e32f70..a73f1ee 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -447,10 +447,11 @@ static plist_t parse_dict_node(struct bplist_data *bplist, const char** bnode, u
static plist_t parse_array_node(struct bplist_data *bplist, const char** bnode, uint64_t size)
{
uint64_t j;
- uint32_t str_j = 0;
- uint32_t index1;
-
+ uint64_t str_j = 0;
+ uint64_t index1;
plist_data_t data = plist_new_plist_data();
+ const char *const end_data = bplist->data + bplist->size;
+ const char *index1_ptr = NULL;
data->type = PLIST_ARRAY;
data->length = size;
@@ -459,7 +460,14 @@ static plist_t parse_array_node(struct bplist_data *bplist, const char** bnode,
for (j = 0; j < data->length; j++) {
str_j = j * bplist->ref_size;
- index1 = UINT_TO_HOST((*bnode) + str_j, bplist->ref_size);
+ index1_ptr = (*bnode) + str_j;
+
+ if (index1_ptr < bplist->data || index1_ptr + bplist->ref_size >= end_data) {
+ plist_free(node);
+ return NULL;
+ }
+
+ index1 = UINT_TO_HOST(index1_ptr, bplist->ref_size);
if (index1 >= bplist->num_objects) {
plist_free(node);