diff options
| author | 2017-02-10 13:42:46 +0100 | |
|---|---|---|
| committer | 2017-02-10 13:42:46 +0100 | |
| commit | 32ee5213fe64f1e10ec76c1ee861ee6f233120dd (patch) | |
| tree | 5fa4d3413c92a5e2b4650689c46bf6a47c0b401a | |
| parent | 72f7cf803635a127c63bcd37ab35ced28636410a (diff) | |
| download | libplist-32ee5213fe64f1e10ec76c1ee861ee6f233120dd.tar.gz libplist-32ee5213fe64f1e10ec76c1ee861ee6f233120dd.tar.bz2 | |
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
| -rw-r--r-- | src/bplist.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/src/bplist.c b/src/bplist.c index 0fd149e..7d21b27 100644 --- a/src/bplist.c +++ b/src/bplist.c | |||
| @@ -654,14 +654,14 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object) | |||
| 654 | return parse_date_node(object, size); | 654 | return parse_date_node(object, size); |
| 655 | 655 | ||
| 656 | case BPLIST_DATA: | 656 | case BPLIST_DATA: |
| 657 | if (*object + size > bplist->offset_table) { | 657 | if (*object + size < *object || *object + size > bplist->offset_table) { |
| 658 | PLIST_BIN_ERR("%s: BPLIST_DATA data bytes point outside of valid range\n", __func__); | 658 | PLIST_BIN_ERR("%s: BPLIST_DATA data bytes point outside of valid range\n", __func__); |
| 659 | return NULL; | 659 | return NULL; |
| 660 | } | 660 | } |
| 661 | return parse_data_node(object, size); | 661 | return parse_data_node(object, size); |
| 662 | 662 | ||
| 663 | case BPLIST_STRING: | 663 | case BPLIST_STRING: |
| 664 | if (*object + size > bplist->offset_table) { | 664 | if (*object + size < *object || *object + size > bplist->offset_table) { |
| 665 | PLIST_BIN_ERR("%s: BPLIST_STRING data bytes point outside of valid range\n", __func__); | 665 | PLIST_BIN_ERR("%s: BPLIST_STRING data bytes point outside of valid range\n", __func__); |
| 666 | return NULL; | 666 | return NULL; |
| 667 | } | 667 | } |
| @@ -672,7 +672,7 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object) | |||
| 672 | PLIST_BIN_ERR("%s: Integer overflow when calculating BPLIST_UNICODE data size.\n", __func__); | 672 | PLIST_BIN_ERR("%s: Integer overflow when calculating BPLIST_UNICODE data size.\n", __func__); |
| 673 | return NULL; | 673 | return NULL; |
| 674 | } | 674 | } |
| 675 | if (*object + size*2 > bplist->offset_table) { | 675 | if (*object + size*2 < *object || *object + size*2 > bplist->offset_table) { |
| 676 | PLIST_BIN_ERR("%s: BPLIST_UNICODE data bytes point outside of valid range\n", __func__); | 676 | PLIST_BIN_ERR("%s: BPLIST_UNICODE data bytes point outside of valid range\n", __func__); |
| 677 | return NULL; | 677 | return NULL; |
| 678 | } | 678 | } |
| @@ -680,7 +680,7 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object) | |||
| 680 | 680 | ||
| 681 | case BPLIST_SET: | 681 | case BPLIST_SET: |
| 682 | case BPLIST_ARRAY: | 682 | case BPLIST_ARRAY: |
| 683 | if (*object + size > bplist->offset_table) { | 683 | if (*object + size < *object || *object + size > bplist->offset_table) { |
| 684 | PLIST_BIN_ERR("%s: BPLIST_ARRAY data bytes point outside of valid range\n", __func__); | 684 | PLIST_BIN_ERR("%s: BPLIST_ARRAY data bytes point outside of valid range\n", __func__); |
| 685 | return NULL; | 685 | return NULL; |
| 686 | } | 686 | } |
| @@ -694,8 +694,8 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object) | |||
| 694 | return parse_uid_node(object, size); | 694 | return parse_uid_node(object, size); |
| 695 | 695 | ||
| 696 | case BPLIST_DICT: | 696 | case BPLIST_DICT: |
| 697 | if (*object + size > bplist->offset_table) { | 697 | if (*object + size < *object || *object + size > bplist->offset_table) { |
| 698 | PLIST_BIN_ERR("%s: BPLIST_REAL data bytes point outside of valid range\n", __func__); | 698 | PLIST_BIN_ERR("%s: BPLIST_DICT data bytes point outside of valid range\n", __func__); |
| 699 | return NULL; | 699 | return NULL; |
| 700 | } | 700 | } |
| 701 | return parse_dict_node(bplist, object, size); | 701 | return parse_dict_node(bplist, object, size); |
