From 1d2596af6fde469622861abefd46ec934e9b86f9d015208576704a5e56bf060b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ismail=20D=C3=B6nmez?= Date: Tue, 7 Aug 2012 19:22:16 +0000 Subject: [PATCH] Accepting request 130342 from home:uli_suse:branches:devel:libraries:c_c++ - fix for malloc()/calloc() overflows (CVE-2012-2673, bnc#765444) OBS-URL: https://build.opensuse.org/request/show/130342 OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/gc?expand=0&rev=18 --- ...ation-size-overflows-due-to-rounding.patch | 40 +++++++++++++++++++ 0001-Fix-calloc-overflow.patch | 32 +++++++++++++++ ...ed-code-to-prevent-SIZE_MAX-redefini.patch | 39 ++++++++++++++++++ ...ize-overflow-check-by-preventing-div.patch | 34 ++++++++++++++++ gc.changes | 5 +++ gc.spec | 12 +++++- 6 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 0001-Fix-allocation-size-overflows-due-to-rounding.patch create mode 100644 0001-Fix-calloc-overflow.patch create mode 100644 0001-Fix-calloc-related-code-to-prevent-SIZE_MAX-redefini.patch create mode 100644 0001-Speedup-calloc-size-overflow-check-by-preventing-div.patch diff --git a/0001-Fix-allocation-size-overflows-due-to-rounding.patch b/0001-Fix-allocation-size-overflows-due-to-rounding.patch new file mode 100644 index 0000000..d35c38b --- /dev/null +++ b/0001-Fix-allocation-size-overflows-due-to-rounding.patch @@ -0,0 +1,40 @@ +From be9df82919960214ee4b9d3313523bff44fd99e1 Mon Sep 17 00:00:00 2001 +From: Xi Wang +Date: Thu, 15 Mar 2012 04:55:08 +0800 +Subject: [PATCH] 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. +--- + malloc.c | 2 ++ + mallocx.c | 2 ++ + 2 files changed, 4 insertions(+), 0 deletions(-) + +diff --git a/malloc.c b/malloc.c +index cc0cc00..899d6ff 100644 +--- a/malloc.c ++++ b/malloc.c +@@ -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(); +diff --git a/mallocx.c b/mallocx.c +index 2c79f41..0d9c0a6 100644 +--- a/mallocx.c ++++ b/mallocx.c +@@ -183,4 +183,6 @@ GC_INNER void * GC_generic_malloc_ignore_off_page(size_t lb, int 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; +-- +1.7.7 + diff --git a/0001-Fix-calloc-overflow.patch b/0001-Fix-calloc-overflow.patch new file mode 100644 index 0000000..6e1c4d5 --- /dev/null +++ b/0001-Fix-calloc-overflow.patch @@ -0,0 +1,32 @@ +From e10c1eb9908c2774c16b3148b30d2f3823d66a9a Mon Sep 17 00:00:00 2001 +From: Xi Wang +Date: Thu, 15 Mar 2012 04:46:49 +0800 +Subject: [PATCH] Fix calloc() overflow + +* malloc.c (calloc): Check multiplication overflow in calloc(), +assuming REDIRECT_MALLOC. +--- + malloc.c | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + +diff --git a/malloc.c b/malloc.c +index da68f13..cc0cc00 100644 +--- a/malloc.c ++++ b/malloc.c +@@ -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. */ +-- +1.7.7 + diff --git a/0001-Fix-calloc-related-code-to-prevent-SIZE_MAX-redefini.patch b/0001-Fix-calloc-related-code-to-prevent-SIZE_MAX-redefini.patch new file mode 100644 index 0000000..9a369ff --- /dev/null +++ b/0001-Fix-calloc-related-code-to-prevent-SIZE_MAX-redefini.patch @@ -0,0 +1,39 @@ +From 6a93f8e5bcad22137f41b6c60a1c7384baaec2b3 Mon Sep 17 00:00:00 2001 +From: Ivan Maidanski +Date: Thu, 15 Mar 2012 20:30:11 +0400 +Subject: [PATCH] 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. +--- + malloc.c | 10 +++++++--- + 1 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/malloc.c b/malloc.c +index 899d6ff..cb49a5c 100644 +--- a/malloc.c ++++ b/malloc.c +@@ -374,12 +374,16 @@ void * malloc(size_t lb) + } + #endif /* GC_LINUX_THREADS */ + +-#ifndef SIZE_MAX +-#define SIZE_MAX (~(size_t)0) ++#include ++#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 */ +-- +1.7.7 + diff --git a/0001-Speedup-calloc-size-overflow-check-by-preventing-div.patch b/0001-Speedup-calloc-size-overflow-check-by-preventing-div.patch new file mode 100644 index 0000000..8e85c58 --- /dev/null +++ b/0001-Speedup-calloc-size-overflow-check-by-preventing-div.patch @@ -0,0 +1,34 @@ +From 83231d0ab5ed60015797c3d1ad9056295ac3b2bb Mon Sep 17 00:00:00 2001 +From: Hans Boehm +Date: Thu, 15 Mar 2012 21:09:05 +0400 +Subject: [PATCH] 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. +--- + malloc.c | 5 ++++- + 1 files changed, 4 insertions(+), 1 deletions(-) + +diff --git a/malloc.c b/malloc.c +index cb49a5c..c9b9eb6 100644 +--- a/malloc.c ++++ b/malloc.c +@@ -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 */ +-- +1.7.7 + diff --git a/gc.changes b/gc.changes index d8cc9b6..2c0a362 100644 --- a/gc.changes +++ b/gc.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Tue Aug 7 15:23:30 UTC 2012 - uli@suse.com + +- fix for malloc()/calloc() overflows (CVE-2012-2673, bnc#765444) + ------------------------------------------------------------------- Sat Feb 11 08:55:11 UTC 2012 - coolo@suse.com diff --git a/gc.spec b/gc.spec index b39a424..aa86211 100644 --- a/gc.spec +++ b/gc.spec @@ -26,6 +26,11 @@ License: BSD-3-Clause Group: Development/Libraries/C and C++ Source: %{name}-%{src_ver}.tar.bz2 Patch0: %{name}-build.patch +Patch1: 0001-Fix-allocation-size-overflows-due-to-rounding.patch +Patch2: 0001-Fix-calloc-overflow.patch +Patch3: 0001-Fix-calloc-related-code-to-prevent-SIZE_MAX-redefini.patch +Patch4: 0001-Speedup-calloc-size-overflow-check-by-preventing-div.patch + BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: gcc-c++ BuildRequires: libtool @@ -60,7 +65,8 @@ be otherwise accessed. Summary: A garbage collector for C and C++ Group: Development/Libraries/C and C++ Provides: gc:/usr/include/gc/gc.h -Requires: libgc1 = %version, glibc-devel +Requires: glibc-devel +Requires: libgc1 = %version %description devel The Boehm-Demers-Weiser conservative garbage collector can be used as a @@ -87,6 +93,10 @@ that involves minimum overhead across a variety of architectures. %prep %setup -q -n %{name}-%{src_ver} %patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 %build # refresh auto*/libtool to purge rpaths