CVE-2017-6308 (published 2017-02-24T04:59Z)

An issue was discovered in tnef before 1.4.13. Several Integer Overflows, which can lead to Heap Overflows, have been identified in the functions that wrap memory allocation.

Severity: MEDIUM
CVSS v2 base score: 6.8 (AV:N/AC:M/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 7.8, HIGH (CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-190
cwe_name: Integer Overflow or Wraparound
description: The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
extended_description: 
            
            
            
            
         
         

Fix information:
repo_url: https://github.com/verdammelt/tnef
commit_details: repo_url: https://github.com/verdammelt/tnef
author: Eric Sesterhenn
author_date: 2017-02-17 09:43:21+01:00
msg: Fix integer overflows and harden memory allocator.
repository: repo_url: https://github.com/verdammelt/tnef
repo_name: verdammelt/tnef
description: tnef
repo_language: C
owner: verdammelt
file_changes: filename: alloc.c
change_type: ModificationType.MODIFY
diff: @@ -40,14 +40,23 @@ get_alloc_limit()
     return alloc_limit;
 }
 
+size_t
+check_mul_overflow(size_t a, size_t b, size_t* res)
+{
+    size_t tmp = a * b;
+    if (a != 0 && tmp / a != b) return 1;
+    *res = tmp;
+    return 0;
+}
+
 static void
 alloc_limit_failure (char *fn_name, size_t size)
 {
-    fprintf (stderr, 
+    fprintf (stderr,
              "%s: Maximum allocation size exceeded "
              "(maxsize = %lu; size = %lu).\n",
              fn_name,
-             (unsigned long)alloc_limit, 
+             (unsigned long)alloc_limit,
              (unsigned long)size);
 }
 
@@ -56,17 +65,21 @@ alloc_limit_assert (char *fn_name, size_t size)
 {
     if (alloc_limit && size > alloc_limit)
     {
-	alloc_limit_failure (fn_name, size);
-	exit (-1);
+        alloc_limit_failure (fn_name, size);
+        exit (-1);
     }
 }
 
 /* attempts to malloc memory, if fails print error and call abort */
 void*
-xmalloc (size_t size)
+xmalloc (size_t num, size_t size)
 {
-    void *ptr = malloc (size);
-    if (!ptr 
+    size_t res;
+    if (check_mul_overflow(num, size, &res))
+        abort();
+
+    void *ptr = malloc (res);
+    if (!ptr
         && (size != 0))         /* some libc don't like size == 0 */
     {
         perror ("xmalloc: Memory allocation failure");
@@ -77,20 +90,29 @@ xmalloc (size_t size)
 
 /* Allocates memory but only up to a limit */
 void*
-checked_xmalloc (size_t size)
+checked_xmalloc (size_t num, size_t size)
 {
-    alloc_limit_assert ("checked_xmalloc", size);
-    return xmalloc (size);
+    size_t res;
+    if (check_mul_overflow(num, size, &res))
+        abort();
+
+    alloc_limit_assert ("checked_xmalloc", res);
+    return xmalloc (num, size);
 }
 
 /* xmallocs memory and clears it out */
 void*
 xcalloc (size_t num, size_t size)
 {
-    void *ptr = malloc(num * size);
+    size_t res;
+    if (check_mul_overflow(num, size, &res))
+        abort();
+
+    void *ptr;
+    ptr = malloc(res);
     if (ptr)
     {
-        memset (ptr, '\0', (num * size));
+        memset (ptr, '\0', (res));
     }
     return ptr;
 }
@@ -99,9 +121,10 @@ xcalloc (size_t num, size_t size)
 void*
 checked_xcalloc (size_t num, size_t size)
 {
-    alloc_limit_assert ("checked_xcalloc", (num *size));
+    size_t res;
+    if (check_mul_overflow(num, size, &res))
+        abort();
+
+    alloc_limit_assert ("checked_xcalloc", (res));
     return xcalloc (num, size);
 }
-
-
-

programming_language: C
filename: alloc.h
change_type: ModificationType.MODIFY
diff: @@ -35,20 +35,20 @@ extern void free (void*);
 extern void set_alloc_limit (size_t size);
 extern size_t get_alloc_limit();
 extern void alloc_limit_assert (char *fn_name, size_t size);
-extern void* checked_xmalloc (size_t size);
-extern void* xmalloc (size_t size);
+extern void* checked_xmalloc (size_t num, size_t size);
+extern void* xmalloc (size_t num, size_t size);
 extern void* checked_xcalloc (size_t num, size_t size);
 extern void* xcalloc (size_t num, size_t size);
 
 #define XMALLOC(_type,_num)			                \
-        ((_type*)xmalloc((_num)*sizeof(_type)))
+        ((_type*)xmalloc((_num), sizeof(_type)))
 #define XCALLOC(_type,_num) 				        \
         ((_type*)xcalloc((_num), sizeof (_type)))
 #define CHECKED_XMALLOC(_type,_num) 			        \
-        ((_type*)checked_xmalloc((_num)*sizeof(_type)))
+        ((_type*)checked_xmalloc((_num),sizeof(_type)))
 #define CHECKED_XCALLOC(_type,_num) 			        \
         ((_type*)checked_xcalloc((_num),sizeof(_type)))
 #define XFREE(_ptr)						\
-	do { if (_ptr) { free (_ptr); _ptr = 0; } } while (0)
+        do { if (_ptr) { free (_ptr); _ptr = 0; } } while (0)
 
 #endif /* ALLOC_H */

programming_language: C