File 0009-Prevent-out-of-bounds-read-in-plist_from_bin-when-parsing-offset_table.patch of Package libplist.4090

From a4ca24c4fe316bc102b9fa52f808d206ab8cd24b Mon Sep 17 00:00:00 2001
From: Filippo Bigarella <filippobigarella@gmail.com>
Date: Thu, 10 Nov 2016 01:31:23 +0100
Subject: [PATCH] bplist: Prevent out-of-bounds read in plist_from_bin() when
 parsing offset_table

offset_table_index is read from the file, so we have full control over it.
This means we can point offset_table essentially anywhere we want, which can
lead to an out-of-bounds read when it will be used later on.
---
 src/bplist.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/bplist.c b/src/bplist.c
index 8447187..be82b4e 100644
--- a/src/bplist.c
+++ b/src/bplist.c
@@ -708,6 +708,7 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t *
     uint64_t num_objects = 0;
     uint64_t root_object = 0;
     uint64_t offset_table_index = 0;
+    char *offset_table = NULL;
 
     //first check we have enough data
     if (!(length >= BPLIST_MAGIC_SIZE + BPLIST_VERSION_SIZE + BPLIST_TRL_SIZE))
@@ -727,6 +728,7 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t *
     num_objects = be64dec(trailer + BPLIST_TRL_NUMOBJ_IDX);
     root_object = be64dec(trailer + BPLIST_TRL_ROOTOBJ_IDX);
     offset_table_index = be64dec(trailer + BPLIST_TRL_OFFTAB_IDX);
+    offset_table = (char *) (plist_bin + offset_table_index);
 
     if (num_objects == 0)
         return;
@@ -734,13 +736,19 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t *
     if (root_object >= num_objects)
         return;
 
+    if (offset_table < plist_bin || offset_table >= plist_bin + length)
+        return;
+
+    if (offset_table + num_objects * offset_size >= plist_bin + length)
+        return;
+
     struct bplist_data bplist;
     bplist.data = plist_bin;
     bplist.size = length;
     bplist.num_objects = num_objects;
     bplist.dict_size = dict_size;
     bplist.offset_size = offset_size;
-    bplist.offset_table = (char *) (plist_bin + offset_table_index);
+    bplist.offset_table = offset_table;
     bplist.level = 0;
     bplist.used_indexes = (uint32_t*)malloc(sizeof(uint32_t) * num_objects);
 
openSUSE Build Service is sponsored by