Skip to content
Permalink
Browse files Browse the repository at this point in the history
bplist: Fix data range check for string/data/dict/array nodes
Passing a size of 0xFFFFFFFFFFFFFFFF to parse_string_node() might result
in a memcpy with a size of -1, leading to undefined behavior.
This commit makes sure that the actual node data (which depends on the size)
is in the range start_of_object..start_of_object+size.

Credit to OSS-Fuzz
  • Loading branch information
nikias committed Feb 10, 2017
1 parent 72f7cf8 commit 32ee521
Showing 1 changed file with 6 additions and 6 deletions.
12 changes: 6 additions & 6 deletions src/bplist.c
Expand Up @@ -654,14 +654,14 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
return parse_date_node(object, size);

case BPLIST_DATA:
if (*object + size > bplist->offset_table) {
if (*object + size < *object || *object + size > bplist->offset_table) {
PLIST_BIN_ERR("%s: BPLIST_DATA data bytes point outside of valid range\n", __func__);
return NULL;
}
return parse_data_node(object, size);

case BPLIST_STRING:
if (*object + size > bplist->offset_table) {
if (*object + size < *object || *object + size > bplist->offset_table) {
PLIST_BIN_ERR("%s: BPLIST_STRING data bytes point outside of valid range\n", __func__);
return NULL;
}
Expand All @@ -672,15 +672,15 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
PLIST_BIN_ERR("%s: Integer overflow when calculating BPLIST_UNICODE data size.\n", __func__);
return NULL;
}
if (*object + size*2 > bplist->offset_table) {
if (*object + size*2 < *object || *object + size*2 > bplist->offset_table) {
PLIST_BIN_ERR("%s: BPLIST_UNICODE data bytes point outside of valid range\n", __func__);
return NULL;
}
return parse_unicode_node(object, size);

case BPLIST_SET:
case BPLIST_ARRAY:
if (*object + size > bplist->offset_table) {
if (*object + size < *object || *object + size > bplist->offset_table) {
PLIST_BIN_ERR("%s: BPLIST_ARRAY data bytes point outside of valid range\n", __func__);
return NULL;
}
Expand All @@ -694,8 +694,8 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
return parse_uid_node(object, size);

case BPLIST_DICT:
if (*object + size > bplist->offset_table) {
PLIST_BIN_ERR("%s: BPLIST_REAL data bytes point outside of valid range\n", __func__);
if (*object + size < *object || *object + size > bplist->offset_table) {
PLIST_BIN_ERR("%s: BPLIST_DICT data bytes point outside of valid range\n", __func__);
return NULL;
}
return parse_dict_node(bplist, object, size);
Expand Down

0 comments on commit 32ee521

Please sign in to comment.