summaryrefslogtreecommitdiffstats
path: root/src/bplist.c
diff options
context:
space:
mode:
authorGravatar Filippo Bigarella2016-11-10 00:54:05 +0100
committerGravatar Nikias Bassen2016-11-10 00:54:05 +0100
commita4563ffeaa0448712c739fc91526e8f210c1e164 (patch)
treeedac1c549f0b025236df4832219e71cde8c761c1 /src/bplist.c
parent17b8e01bdfbdb38a2aec5cce0554b72bd37ee6ce (diff)
downloadlibplist-a4563ffeaa0448712c739fc91526e8f210c1e164.tar.gz
libplist-a4563ffeaa0448712c739fc91526e8f210c1e164.tar.bz2
bplist: Fix possible out-of-bounds read in parse_dict_node() with proper bounds checking
Diffstat (limited to 'src/bplist.c')
-rw-r--r--src/bplist.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/bplist.c b/src/bplist.c
index 78b8255..8cafb6a 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -402,6 +402,9 @@ static plist_t parse_dict_node(struct bplist_data *bplist, const char** bnode, u
402 uint64_t str_i = 0, str_j = 0; 402 uint64_t str_i = 0, str_j = 0;
403 uint64_t index1, index2; 403 uint64_t index1, index2;
404 plist_data_t data = plist_new_plist_data(); 404 plist_data_t data = plist_new_plist_data();
405 const char *const end_data = bplist->data + bplist->size;
406 const char *index1_ptr = NULL;
407 const char *index2_ptr = NULL;
405 408
406 data->type = PLIST_DICT; 409 data->type = PLIST_DICT;
407 data->length = size; 410 data->length = size;
@@ -411,9 +414,17 @@ static plist_t parse_dict_node(struct bplist_data *bplist, const char** bnode, u
411 for (j = 0; j < data->length; j++) { 414 for (j = 0; j < data->length; j++) {
412 str_i = j * bplist->dict_size; 415 str_i = j * bplist->dict_size;
413 str_j = (j + size) * bplist->dict_size; 416 str_j = (j + size) * bplist->dict_size;
417 index1_ptr = (*bnode) + str_i;
418 index2_ptr = (*bnode) + str_j;
414 419
415 index1 = UINT_TO_HOST((*bnode) + str_i, bplist->dict_size); 420 if ((index1_ptr < bplist->data || index1_ptr + bplist->dict_size >= end_data) ||
416 index2 = UINT_TO_HOST((*bnode) + str_j, bplist->dict_size); 421 (index2_ptr < bplist->data || index2_ptr + bplist->dict_size >= end_data)) {
422 plist_free(node);
423 return NULL;
424 }
425
426 index1 = UINT_TO_HOST(index1_ptr, bplist->dict_size);
427 index2 = UINT_TO_HOST(index2_ptr, bplist->dict_size);
417 428
418 if (index1 >= bplist->num_objects) { 429 if (index1 >= bplist->num_objects) {
419 plist_free(node); 430 plist_free(node);