Control: tags 858055 + patch
Control: tags 858055 + pending
Control: tags 858786 + pending
Control: tags 858787 + patch
Control: tags 858787 + pending

Dear maintainer,

I've prepared an NMU for libplist (versioned as 1.12+git+1+e37ca00-0.2) and
uploaded it to DELAYED/5. Please feel free to tell me if I
should delay it longer or if I can speed up the upload.

Regards,
Salvatore
diff -Nru libplist-1.12+git+1+e37ca00/debian/changelog libplist-1.12+git+1+e37ca00/debian/changelog
--- libplist-1.12+git+1+e37ca00/debian/changelog	2017-02-26 19:21:32.000000000 +0100
+++ libplist-1.12+git+1+e37ca00/debian/changelog	2017-03-27 19:41:54.000000000 +0200
@@ -1,3 +1,14 @@
+libplist (1.12+git+1+e37ca00-0.2) unstable; urgency=high
+
+  * Non-maintainer upload.
+  * bplist: Make sure sanity checks work on 32bit platforms.
+    CVE-2017-6437: Out-of-bounds heap read in base64encode function
+    CVE-2017-6438: Heap-based buffer overflow in parse_unicode_node
+    CVE-2017-6440: Memory allocation error in parse_data_node
+    (Closes: #858787, #858786, #858055)
+
+ -- Salvatore Bonaccorso <[email protected]>  Mon, 27 Mar 2017 19:41:54 +0200
+
 libplist (1.12+git+1+e37ca00-0.1) unstable; urgency=medium
 
   * Non-maintainer upload.
diff -Nru libplist-1.12+git+1+e37ca00/debian/patches/02_bplist-Make-sure-sanity-checks-work-on-32bit-platfor.patch libplist-1.12+git+1+e37ca00/debian/patches/02_bplist-Make-sure-sanity-checks-work-on-32bit-platfor.patch
--- libplist-1.12+git+1+e37ca00/debian/patches/02_bplist-Make-sure-sanity-checks-work-on-32bit-platfor.patch	1970-01-01 01:00:00.000000000 +0100
+++ libplist-1.12+git+1+e37ca00/debian/patches/02_bplist-Make-sure-sanity-checks-work-on-32bit-platfor.patch	2017-03-27 19:41:54.000000000 +0200
@@ -0,0 +1,124 @@
+From dccd9290745345896e3a4a73154576a599fd8b7b Mon Sep 17 00:00:00 2001
+From: Nikias Bassen <[email protected]>
+Date: Sun, 26 Mar 2017 20:06:57 +0200
+Subject: [PATCH] bplist: Make sure sanity checks work on 32bit platforms
+
+Because on 32-bit platforms 32-bit pointers and 64-bit sizes have been
+used for the sanity checks of the offset table and object references,
+the range checks would fail in certain interger-overflowish situations,
+causing heap buffer overflows or other unwanted behavior.
+Fixed by wideing the operands in question to 64-bit.
+---
+ src/bplist.c | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+diff --git a/src/bplist.c b/src/bplist.c
+index 7d21b27..eede7a7 100644
+--- a/src/bplist.c
++++ b/src/bplist.c
+@@ -561,6 +561,8 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
+ {
+     uint16_t type = 0;
+     uint64_t size = 0;
++    uint64_t pobject = 0;
++    uint64_t poffset_table = (uint64_t)bplist->offset_table;
+ 
+     if (!object)
+         return NULL;
+@@ -598,6 +600,8 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
+         }
+     }
+ 
++    pobject = (uint64_t)*object;
++
+     switch (type)
+     {
+ 
+@@ -629,14 +633,14 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
+         }
+ 
+     case BPLIST_UINT:
+-        if (*object + (uint64_t)(1 << size) > bplist->offset_table) {
++        if (pobject + (uint64_t)(1 << size) > poffset_table) {
+             PLIST_BIN_ERR("%s: BPLIST_UINT data bytes point outside of valid range\n", __func__);
+             return NULL;
+         }
+         return parse_uint_node(object, size);
+ 
+     case BPLIST_REAL:
+-        if (*object + (uint64_t)(1 << size) > bplist->offset_table) {
++        if (pobject + (uint64_t)(1 << size) > poffset_table) {
+             PLIST_BIN_ERR("%s: BPLIST_REAL data bytes point outside of valid range\n", __func__);
+             return NULL;
+         }
+@@ -647,21 +651,21 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
+             PLIST_BIN_ERR("%s: invalid data size for BPLIST_DATE node\n", __func__);
+             return NULL;
+         }
+-        if (*object + (uint64_t)(1 << size) > bplist->offset_table) {
++        if (pobject + (uint64_t)(1 << size) > poffset_table) {
+             PLIST_BIN_ERR("%s: BPLIST_DATE data bytes point outside of valid range\n", __func__);
+             return NULL;
+         }
+         return parse_date_node(object, size);
+ 
+     case BPLIST_DATA:
+-        if (*object + size < *object || *object + size > bplist->offset_table) {
++        if (pobject + size < pobject || pobject + size > poffset_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 < *object || *object + size > bplist->offset_table) {
++        if (pobject + size < pobject || pobject + size > poffset_table) {
+             PLIST_BIN_ERR("%s: BPLIST_STRING data bytes point outside of valid range\n", __func__);
+             return NULL;
+         }
+@@ -672,7 +676,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 < *object || *object + size*2 > bplist->offset_table) {
++        if (pobject + size*2 < pobject || pobject + size*2 > poffset_table) {
+             PLIST_BIN_ERR("%s: BPLIST_UNICODE data bytes point outside of valid range\n", __func__);
+             return NULL;
+         }
+@@ -680,21 +684,21 @@ static plist_t parse_bin_node(struct bplist_data *bplist, const char** object)
+ 
+     case BPLIST_SET:
+     case BPLIST_ARRAY:
+-        if (*object + size < *object || *object + size > bplist->offset_table) {
++        if (pobject + size < pobject || pobject + size > poffset_table) {
+             PLIST_BIN_ERR("%s: BPLIST_ARRAY data bytes point outside of valid range\n", __func__);
+             return NULL;
+         }
+         return parse_array_node(bplist, object, size);
+ 
+     case BPLIST_UID:
+-        if (*object + size+1 > bplist->offset_table) {
++        if (pobject + size+1 > poffset_table) {
+             PLIST_BIN_ERR("%s: BPLIST_UID data bytes point outside of valid range\n", __func__);
+             return NULL;
+         }
+         return parse_uid_node(object, size);
+ 
+     case BPLIST_DICT:
+-        if (*object + size < *object || *object + size > bplist->offset_table) {
++        if (pobject + size < pobject || pobject + size > poffset_table) {
+             PLIST_BIN_ERR("%s: BPLIST_DICT data bytes point outside of valid range\n", __func__);
+             return NULL;
+         }
+@@ -830,7 +834,7 @@ PLIST_API void plist_from_bin(const char *plist_bin, uint32_t length, plist_t *
+         return;
+     }
+ 
+-    if (offset_table + num_objects * offset_size > end_data) {
++    if ((uint64_t)offset_table + num_objects * offset_size > (uint64_t)end_data) {
+         PLIST_BIN_ERR("offset table points outside of valid range\n");
+         return;
+     }
+-- 
+2.1.4
+
diff -Nru libplist-1.12+git+1+e37ca00/debian/patches/series libplist-1.12+git+1+e37ca00/debian/patches/series
--- libplist-1.12+git+1+e37ca00/debian/patches/series	2017-02-26 19:21:32.000000000 +0100
+++ libplist-1.12+git+1+e37ca00/debian/patches/series	2017-03-27 19:41:54.000000000 +0200
@@ -1 +1,2 @@
 01-libs.private.patch
+02_bplist-Make-sure-sanity-checks-work-on-32bit-platfor.patch

Reply via email to