summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2017-02-10 13:42:46 +0100
committerGravatar Nikias Bassen2017-02-10 13:42:46 +0100
commit32ee5213fe64f1e10ec76c1ee861ee6f233120dd (patch)
tree5fa4d3413c92a5e2b4650689c46bf6a47c0b401a
parent72f7cf803635a127c63bcd37ab35ced28636410a (diff)
downloadlibplist-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.c12
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)
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;
}
@@ -672,7 +672,7 @@ 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;
}
@@ -680,7 +680,7 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
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;
}
@@ -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);