CVE-2012-2673 (published 2012-07-25T19:55Z)

Multiple integer overflows in the (1) GC_generic_malloc and (2) calloc functions in malloc.c, and the (3) GC_generic_malloc_ignore_off_page function in mallocx.c in Boehm-Demers-Weiser GC (libgc) before 7.2 make it easier for context-dependent attackers to perform memory-related attacks such as buffer overflows via a large size value, which causes less memory to be allocated than expected.

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:N/I:P/A:N)

Weakness information:
cwe_id: CWE-189
cwe_name: Numeric Errors
description: Weaknesses in this category are related to improper calculation or conversion of numbers.

Fix information:
repo_url: https://github.com/ivmai/bdwgc
commit_details: repo_url: https://github.com/ivmai/bdwgc
author: Hans Boehm
author_date: 2012-03-15 21:09:05+04:00
msg: Speedup calloc size overflow check by preventing division if small values

* malloc.c (GC_SQRT_SIZE_MAX): New macro.
* malloc.c (calloc): Add fast initial size overflow check to avoid
integer division for reasonably small values passed.
repository: repo_url: https://github.com/ivmai/bdwgc
repo_name: ivmai/bdwgc
description: The Boehm-Demers-Weiser conservative C/C++ Garbage Collector (bdwgc, also known as bdw-gc, boehm-gc, libgc)
repo_language: C
owner: ivmai
file_changes: filename: malloc.c
change_type: ModificationType.MODIFY
diff: @@ -381,9 +381,12 @@ void * malloc(size_t lb)
 # define GC_SIZE_MAX (~(size_t)0)
 #endif
 
+#define GC_SQRT_SIZE_MAX ((1U << (WORDSZ / 2)) - 1)
+
 void * calloc(size_t n, size_t lb)
 {
-    if (lb && n > GC_SIZE_MAX / lb)
+    if ((lb | n) > GC_SQRT_SIZE_MAX /* fast initial test */
+        && lb && n > GC_SIZE_MAX / lb)
       return NULL;
 #   if defined(GC_LINUX_THREADS) /* && !defined(USE_PROC_FOR_LIBRARIES) */
         /* libpthread allocated some memory that is only pointed to by  */

programming_language: C
repo_url: https://github.com/ivmai/bdwgc
commit_details: repo_url: https://github.com/ivmai/bdwgc
author: Ivan Maidanski
author_date: 2012-03-15 20:30:11+04:00
msg: Fix calloc-related code to prevent SIZE_MAX redefinition in sys headers

* malloc.c: Include limits.h for SIZE_MAX.
* malloc.c (SIZE_MAX, calloc): Define GC_SIZE_MAX instead of SIZE_MAX.
repository: repo_url: https://github.com/ivmai/bdwgc
repo_name: ivmai/bdwgc
description: The Boehm-Demers-Weiser conservative C/C++ Garbage Collector (bdwgc, also known as bdw-gc, boehm-gc, libgc)
repo_language: C
owner: ivmai
file_changes: filename: malloc.c
change_type: ModificationType.MODIFY
diff: @@ -374,12 +374,16 @@ void * malloc(size_t lb)
   }
 #endif /* GC_LINUX_THREADS */
 
-#ifndef SIZE_MAX
-#define SIZE_MAX (~(size_t)0)
+#include <limits.h>
+#ifdef SIZE_MAX
+# define GC_SIZE_MAX SIZE_MAX
+#else
+# define GC_SIZE_MAX (~(size_t)0)
 #endif
+
 void * calloc(size_t n, size_t lb)
 {
-    if (lb && n > SIZE_MAX / lb)
+    if (lb && n > GC_SIZE_MAX / lb)
       return NULL;
 #   if defined(GC_LINUX_THREADS) /* && !defined(USE_PROC_FOR_LIBRARIES) */
         /* libpthread allocated some memory that is only pointed to by  */

programming_language: C
repo_url: https://github.com/ivmai/bdwgc
commit_details: repo_url: https://github.com/ivmai/bdwgc
author: Xi Wang
author_date: 2012-03-15 04:46:49+08:00
msg: Fix calloc() overflow

* malloc.c (calloc): Check multiplication overflow in calloc(),
assuming REDIRECT_MALLOC.
repository: repo_url: https://github.com/ivmai/bdwgc
repo_name: ivmai/bdwgc
description: The Boehm-Demers-Weiser conservative C/C++ Garbage Collector (bdwgc, also known as bdw-gc, boehm-gc, libgc)
repo_language: C
owner: ivmai
file_changes: filename: malloc.c
change_type: ModificationType.MODIFY
diff: @@ -372,8 +372,13 @@ void * malloc(size_t lb)
   }
 #endif /* GC_LINUX_THREADS */
 
+#ifndef SIZE_MAX
+#define SIZE_MAX (~(size_t)0)
+#endif
 void * calloc(size_t n, size_t lb)
 {
+    if (lb && n > SIZE_MAX / lb)
+      return NULL;
 #   if defined(GC_LINUX_THREADS) /* && !defined(USE_PROC_FOR_LIBRARIES) */
         /* libpthread allocated some memory that is only pointed to by  */
         /* mmapped thread stacks.  Make sure it's not collectable.      */

programming_language: C
repo_url: https://github.com/ivmai/bdwgc
commit_details: repo_url: https://github.com/ivmai/bdwgc
author: Xi Wang
author_date: 2012-03-15 04:55:08+08:00
msg: Fix allocation size overflows due to rounding.

* malloc.c (GC_generic_malloc): Check if the allocation size is
rounded to a smaller value.
* mallocx.c (GC_generic_malloc_ignore_off_page): Likewise.
repository: repo_url: https://github.com/ivmai/bdwgc
repo_name: ivmai/bdwgc
description: The Boehm-Demers-Weiser conservative C/C++ Garbage Collector (bdwgc, also known as bdw-gc, boehm-gc, libgc)
repo_language: C
owner: ivmai
file_changes: filename: malloc.c
change_type: ModificationType.MODIFY
diff: @@ -169,6 +169,8 @@ GC_API void * GC_CALL GC_generic_malloc(size_t lb, int k)
         GC_bool init;
         lg = ROUNDED_UP_GRANULES(lb);
         lb_rounded = GRANULES_TO_BYTES(lg);
+        if (lb_rounded < lb)
+            return((*GC_get_oom_fn())(lb));
         n_blocks = OBJ_SZ_TO_BLOCKS(lb_rounded);
         init = GC_obj_kinds[k].ok_init;
         LOCK();

programming_language: C
filename: mallocx.c
change_type: ModificationType.MODIFY
diff: @@ -182,6 +182,8 @@ GC_INNER void * GC_generic_malloc_ignore_off_page(size_t lb, int k)
         return(GC_generic_malloc((word)lb, k));
     lg = ROUNDED_UP_GRANULES(lb);
     lb_rounded = GRANULES_TO_BYTES(lg);
+    if (lb_rounded < lb)
+        return((*GC_get_oom_fn())(lb));
     n_blocks = OBJ_SZ_TO_BLOCKS(lb_rounded);
     init = GC_obj_kinds[k].ok_init;
     if (EXPECT(GC_have_errors, FALSE))

programming_language: C