Extracted from git to match Debian patch and CVE

From 5692b75a21bf71dd86ac84bcfeb9ce8c0830658e Mon Sep 17 00:00:00 2001
From: Stuart Caie <kyzer@4u.net>
Date: Thu, 15 Jan 2015 00:49:08 +0000
Subject: [PATCH] better bounds checks reading CHM data, preventing segfaults

---
 libmspack/trunk/ChangeLog     | 10 ++++++++++
 libmspack/trunk/mspack/chmd.c |  8 +++++---
 2 files changed, 15 insertions(+), 3 deletions(-)

From bef420ede1039dbdc8d6acafa2f115be2ec86bef Mon Sep 17 00:00:00 2001
From: Stuart Caie <kyzer@4u.net>
Date: Sun, 18 Jan 2015 23:05:07 +0000
Subject: [PATCH] Another fix for checking name_len is within chunk bounds

---
 libmspack/trunk/ChangeLog     | 3 +++
 libmspack/trunk/mspack/chmd.c | 6 +++---
 2 files changed, 6 insertions(+), 3 deletions(-)

From 3f8a171b95b858f2d98e60b6da8a427ef530516b Mon Sep 17 00:00:00 2001
From: Stuart Caie <kyzer@4u.net>
Date: Sun, 18 Jan 2015 23:11:39 +0000
Subject: [PATCH] better fix

---
 libmspack/trunk/ChangeLog     | 2 +-
 libmspack/trunk/mspack/chmd.c | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

#diff --git a/libmspack/trunk/ChangeLog b/libmspack/trunk/ChangeLog
#index 3472950..a7cf6f4 100644
#--- a/libmspack/trunk/ChangeLog
#+++ b/libmspack/trunk/ChangeLog
#@@ -1,3 +1,13 @@
#+2015-01-15  Stuart Caie <kyzer@4u.net>
#+
#+	* chmd_read_headers(): add a bounds check to prevent over-reading data,
#+	which caused a segfault on 32-bit architectures. Thanks to Jakub Wilk.
#+
#+	* search_chunk(): change the order of pointer arithmetic operations to
#+	avoid overflow during bounds checks, which lead to segfaults on 32-bit
#+	architectures. Again, thanks to Jakub Wilk for finding this issue,
#+	providing sample files and a patch.
#+
# 2015-01-08  Stuart Caie <kyzer@4u.net>
# 
# 	* cabd_extract(): No longer uses broken state data if extracting from
#diff --git a/libmspack/trunk/ChangeLog b/libmspack/trunk/ChangeLog
#index 97eb31b..a59c779 100644
#--- a/libmspack/trunk/ChangeLog
#+++ b/libmspack/trunk/ChangeLog
#@@ -9,6 +9,9 @@
# 	* inflate(): off-by-one error. Distance codes are 0-29, not 0-30.
# 	Thanks to Jakub Wilk again.
# 
#+	* chmd_read_headers(), search_chunk(): another fix for checking name_len
#+	is within a chunk, thanks again to Jakub Wilk.
#+
# 2015-01-17  Stuart Caie <kyzer@4u.net>
# 
# 	* GET_UTF8_CHAR(): Remove 5/6-byte encoding support and check decoded
#diff --git a/libmspack/trunk/ChangeLog b/libmspack/trunk/ChangeLog
#index a59c779..63d88b5 100644
#--- a/libmspack/trunk/ChangeLog
#+++ b/libmspack/trunk/ChangeLog
#@@ -9,7 +9,7 @@
# 	* inflate(): off-by-one error. Distance codes are 0-29, not 0-30.
# 	Thanks to Jakub Wilk again.
# 
#-	* chmd_read_headers(), search_chunk(): another fix for checking name_len
#+	* chmd_read_headers(), search_chunk(): another fix for checking pointer
# 	is within a chunk, thanks again to Jakub Wilk.
# 
# 2015-01-17  Stuart Caie <kyzer@4u.net>
Index: libmspack-0.0.20060920alpha/mspack/chmd.c
===================================================================
--- libmspack-0.0.20060920alpha.orig/mspack/chmd.c
+++ libmspack-0.0.20060920alpha/mspack/chmd.c
@@ -231,7 +231,7 @@ static int chmd_read_headers(struct mspa
 			     struct mschmd_header *chm, int entire)
 {
   unsigned int num_chunks, num_entries, section, name_len, x;
-  unsigned char buf[0x54], *chunk = NULL, *name, *p;
+  unsigned char buf[0x54], *chunk = NULL, *name, *p, *end;
   struct mschmd_file *fi, *link = NULL;
   off_t offset, length;
 
@@ -373,8 +373,10 @@ static int chmd_read_headers(struct mspa
     /* process only directory (PMGL) chunks */
     if (EndGetI32(&chunk[pmgl_Signature]) != 0x4C474D50) continue;
 
-    num_entries = EndGetI16(&chunk[chm->chunk_size-2]);
     p = &chunk[pmgl_Entries];
+    end = &chunk[chm->chunk_size-2];
+    num_entries = EndGetI16(end);
+
     while (num_entries--) {
       if (p > &chunk[chm->chunk_size]) {
 	D(("read beyond end of chunk"))
@@ -385,6 +387,7 @@ static int chmd_read_headers(struct mspa
       name_len = 0; section  = 0;
       offset   = 0; length   = 0;
       do { name_len = (name_len << 7) | (*p & 0x7F); } while (*p++ & 0x80);
+      if (name_len > (unsigned int) (end - p)) goto chunk_end;
       name = p; p += name_len;
       do { section  = (section  << 7) | (*p & 0x7F); } while (*p++ & 0x80);
       do { offset   = (offset   << 7) | (*p & 0x7F); } while (*p++ & 0x80);
@@ -439,6 +442,9 @@ static int chmd_read_headers(struct mspa
   }
   sys->free(chunk);
   return MSPACK_ERR_OK;
+ chunk_end:
+  sys->free(chunk);
+  return MSPACK_ERR_DATAFORMAT;
 }
 
 /***************************************
