From 13d12a85fa661c2f331a4ad61ef921d942ce9176 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Tue, 15 Aug 2017 22:03:47 +0200
Subject: Checked for out-of-bound data access without triggering integer
 overflow.

---
 ChangeLog                    |  7 +++++++
 src/analysis/contents/file.c |  4 ++--
 src/common/endianness.c      | 32 ++++++++++++++++----------------
 src/common/leb128.c          |  4 ----
 4 files changed, 25 insertions(+), 22 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0811005..dad8776 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 17-08-15  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/analysis/contents/file.c:
+	* src/common/endianness.c:
+	* src/common/leb128.c:
+	Check for out-of-bound data access without triggering integer overflow.
+
+17-08-15  Cyrille Bagard <nocbos@gmail.com>
+
 	* src/glibext/generators/prologue.c:
 	Find a location for disassembly prologues in all cases.
 
diff --git a/src/analysis/contents/file.c b/src/analysis/contents/file.c
index b6cd39c..8b371ab 100644
--- a/src/analysis/contents/file.c
+++ b/src/analysis/contents/file.c
@@ -510,10 +510,10 @@ static bool g_file_content_seek(const GFileContent *content, vmpa2t *addr, phys_
 
     offset = get_phy_addr(addr);
 
-    if (offset == VMPA_NO_PHYSICAL)
+    if (length > get_mrange_length(&content->range))
         return false;
 
-    if ((offset + length) > get_mrange_length(&content->range))
+    if (offset > (get_mrange_length(&content->range) - length))
         return false;
 
     advance_vmpa(addr, length);
diff --git a/src/common/endianness.c b/src/common/endianness.c
index ba72f3d..4dcee22 100755
--- a/src/common/endianness.c
+++ b/src/common/endianness.c
@@ -267,8 +267,8 @@ uint64_t swap_u64(const uint64_t *value, SourceEndian endian)
 
 bool read_u4(uint8_t *target, const bin_t *data, phys_t *pos, phys_t end, bool *low)
 {
-    if (*pos < 0) return false;
-    if ((end - *pos) < 1) return false;
+    if (end < 1) return false;
+    if (*pos > (end - 1)) return false;
 
     if (*low)
     {
@@ -304,8 +304,8 @@ bool read_u4(uint8_t *target, const bin_t *data, phys_t *pos, phys_t end, bool *
 
 bool read_u8(uint8_t *target, const bin_t *data, phys_t *pos, phys_t end)
 {
-    if (*pos < 0) return false;
-    if ((end - *pos) < 1) return false;
+    if (end < 1) return false;
+    if (*pos > (end - 1)) return false;
 
     *target = data[*pos];
 
@@ -334,8 +334,8 @@ bool read_u8(uint8_t *target, const bin_t *data, phys_t *pos, phys_t end)
 
 bool read_u16(uint16_t *target, const bin_t *data, phys_t *pos, phys_t end, SourceEndian endian)
 {
-    if (*pos < 0) return false;
-    if ((end - *pos) < 2) return false;
+    if (end < 2) return false;
+    if (*pos > (end - 2)) return false;
 
     switch (endian)
     {
@@ -407,8 +407,8 @@ bool read_u16(uint16_t *target, const bin_t *data, phys_t *pos, phys_t end, Sour
 
 bool read_u32(uint32_t *target, const bin_t *data, phys_t *pos, phys_t end, SourceEndian endian)
 {
-    if (*pos < 0) return false;
-    if ((end - *pos) < 4) return false;
+    if (end < 4) return false;
+    if (*pos > (end - 4)) return false;
 
     switch (endian)
     {
@@ -484,8 +484,8 @@ bool read_u32(uint32_t *target, const bin_t *data, phys_t *pos, phys_t end, Sour
 
 bool read_u64(uint64_t *target, const bin_t *data, phys_t *pos, phys_t end, SourceEndian endian)
 {
-    if (*pos < 0) return false;
-    if ((end - *pos) < 8) return false;
+    if (end < 8) return false;
+    if (*pos > (end - 8)) return false;
 
     switch (endian)
     {
@@ -572,8 +572,8 @@ bool _write_un(const bin_t *value, size_t size, bin_t *data, off_t *pos, off_t e
 {
     size_t i;                               /* Boucle de parcours          */
 
-    if (*pos < 0) return false;
-    if ((end - *pos) < size) return false;
+    if (end < size) return false;
+    if (*pos > (end - size)) return false;
 
     switch (endian)
     {
@@ -648,8 +648,8 @@ bool strtou8(uint8_t *target, const char *data, size_t *pos, size_t end, SourceE
 {
     size_t i;                               /* Boucle de parcours          */
 
-    if (*pos < 0) return false;
-    if ((end - *pos) < 2) return false;
+    if (end < 2) return false;
+    if (*pos > (end - 2)) return false;
 
     *target = 0;
 
@@ -706,8 +706,8 @@ bool _strtoun(uint8_t n, const char *data, size_t *pos, size_t end, SourceEndian
     size_t j;                               /* Boucle de parcours #2       */
     uint8_t tmp;                            /* Valeur temporaire de 8 bits */
 
-    if (*pos < 0) return false;
-    if ((end - *pos) < (n * 2)) return false;
+    if (end < (n * 2)) return false;
+    if (*pos > (end - (n * 2))) return false;
 
     /* Récupération de la destination */
 
diff --git a/src/common/leb128.c b/src/common/leb128.c
index 2450850..67d8a6b 100644
--- a/src/common/leb128.c
+++ b/src/common/leb128.c
@@ -45,8 +45,6 @@ bool read_uleb128(uleb128_t *target, const bin_t *data, phys_t *pos, phys_t len)
     int shift;                              /* Décallage à appliquer       */
     phys_t i;                               /* Boucle de parcours          */
 
-    if (*pos < 0) return false;
-
     shift = 0;
     *target = 0;
 
@@ -89,8 +87,6 @@ bool read_leb128(leb128_t *target, const bin_t *data, phys_t *pos, phys_t len)
     int shift;                              /* Décallage à appliquer       */
     phys_t i;                               /* Boucle de parcours          */
 
-    if (*pos < 0) return false;
-
     shift = 0;
     *target = 0;
 
-- 
cgit v0.11.2-87-g4458