diff -Nru libgc-7.4.2/debian/changelog libgc-7.4.2/debian/changelog --- libgc-7.4.2/debian/changelog 2016-05-17 14:36:12.000000000 +0000 +++ libgc-7.4.2/debian/changelog 2017-02-13 19:50:02.000000000 +0000 @@ -1,3 +1,20 @@ +libgc (1:7.4.2-8ubuntu1) zesty; urgency=medium + + * SECURITY UPDATE: multiple integer overflows leading to pointers to + memory zones smaller than requested size. + - d/p/CVE-2016-9427-1.patch: Fix calloc_explicitly_typed in case + of lb*n overflow. + - d/p/CVE-2016-9427-2.patch: Fix malloc routines to prevent size + value wrap-around of lb*n overflow. + - d/p/CVE-2016-9427-3.patch: Fix GC_collect_or_expand to prevent + allocation size value wrap-around + - d/p/CVE-2016-9427-test.patch: add test cases + - CVE-2016-9427 + * d/p/workaround-gcc-6-gnu++14.patch: Work around libgc test failure + due to --std=gnu++14 (https://github.com/ivmai/bdwgc/issues/87) + + -- Steve Beattie Mon, 13 Feb 2017 11:50:02 -0800 + libgc (1:7.4.2-8) unstable; urgency=medium * Fix symbols for nios (Closes: #822445), Thanks to Helmut for report diff -Nru libgc-7.4.2/debian/control libgc-7.4.2/debian/control --- libgc-7.4.2/debian/control 2015-09-24 11:28:47.000000000 +0000 +++ libgc-7.4.2/debian/control 2017-02-10 08:13:35.000000000 +0000 @@ -1,5 +1,6 @@ Source: libgc -Maintainer: Christoph Egger +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Christoph Egger Uploaders: Debian GCC Maintainers Section: libs Priority: standard diff -Nru libgc-7.4.2/debian/patches/CVE-2016-9427-1.patch libgc-7.4.2/debian/patches/CVE-2016-9427-1.patch --- libgc-7.4.2/debian/patches/CVE-2016-9427-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ libgc-7.4.2/debian/patches/CVE-2016-9427-1.patch 2017-02-13 19:50:02.000000000 +0000 @@ -0,0 +1,61 @@ +commit 41a9ed4cc88c0ed92403e1bd720c68d26c632352 +Author: Ivan Maidanski +Date: Thu Sep 15 18:40:21 2016 +0300 +Description: Fix calloc_explicitly_typed in case of lb*n overflow + + Fix calloc_explicitly_typed in case of lb*n overflow + (Cherry-pick commit b9d1634 from 'release-7_6' branch.) + + * typd_mlc.c: Include limits.h (for SIZE_MAX). + * typd_mlc.c (GC_SIZE_MAX, GC_SQRT_SIZE_MAX): New macro (same as in + malloc.c). + * typd_mlc.c (GC_calloc_explicitly_typed): Return NULL if lb * n + overflows (same algorithm as in calloc defined in malloc.c); eliminate + lb *= n code duplication. + +Index: libgc-7.4.2/typd_mlc.c +=================================================================== +--- libgc-7.4.2.orig/typd_mlc.c ++++ libgc-7.4.2/typd_mlc.c +@@ -655,6 +655,15 @@ GC_API GC_ATTR_MALLOC void * GC_CALL + return((void *) op); + } + ++#include ++#ifdef SIZE_MAX ++# define GC_SIZE_MAX SIZE_MAX ++#else ++# define GC_SIZE_MAX (~(size_t)0) ++#endif ++ ++#define GC_SQRT_SIZE_MAX ((((size_t)1) << (WORDSZ / 2)) - 1) ++ + GC_API GC_ATTR_MALLOC void * GC_CALL GC_calloc_explicitly_typed(size_t n, + size_t lb, GC_descr d) + { +@@ -667,17 +676,20 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_ + struct LeafDescriptor leaf; + DCL_LOCK_STATE; + +- descr_type = GC_make_array_descriptor((word)n, (word)lb, d, +- &simple_descr, &complex_descr, &leaf); ++ descr_type = GC_make_array_descriptor((word)n, (word)lb, d, &simple_descr, ++ &complex_descr, &leaf); ++ if ((lb | n) > GC_SQRT_SIZE_MAX /* fast initial check */ ++ && lb > 0 && n > GC_SIZE_MAX / lb) ++ return NULL; /* n*lb overflow */ ++ lb *= n; + switch(descr_type) { + case NO_MEM: return(0); +- case SIMPLE: return(GC_malloc_explicitly_typed(n*lb, simple_descr)); ++ case SIMPLE: ++ return GC_malloc_explicitly_typed(lb, simple_descr); + case LEAF: +- lb *= n; + lb += sizeof(struct LeafDescriptor) + TYPD_EXTRA_BYTES; + break; + case COMPLEX: +- lb *= n; + lb += TYPD_EXTRA_BYTES; + break; + } diff -Nru libgc-7.4.2/debian/patches/CVE-2016-9427-2.patch libgc-7.4.2/debian/patches/CVE-2016-9427-2.patch --- libgc-7.4.2/debian/patches/CVE-2016-9427-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ libgc-7.4.2/debian/patches/CVE-2016-9427-2.patch 2017-02-13 19:50:02.000000000 +0000 @@ -0,0 +1,807 @@ +commit 0b6818708f7644db5c7bd0cc80e7adaa5a889257 +Author: Ivan Maidanski +Date: Tue Sep 20 00:07:47 2016 +0300 +Description: Fix malloc routines to prevent size value wrap-around + + Fix malloc routines to prevent size value wrap-around + (Cherry-pick commit f9c8aa3 from 'release-7_6' branch.) + + See issue #135 on Github. + + * allchblk.c (GC_allochblk, GC_allochblk_nth): Use + OBJ_SZ_TO_BLOCKS_CHECKED instead of OBJ_SZ_TO_BLOCKS. + * malloc.c (GC_alloc_large): Likewise. + * alloc.c (GC_expand_hp_inner): Type of "bytes" local variable changed + from word to size_t; cast ROUNDUP_PAGESIZE argument to size_t; prevent + overflow when computing GC_heapsize+bytes > GC_max_heapsize. + * dbg_mlc.c (GC_debug_malloc, GC_debug_malloc_ignore_off_page, + GC_debug_malloc_atomic_ignore_off_page, + GC_debug_generic_malloc_inner, + GC_debug_generic_malloc_inner_ignore_off_page, + GC_debug_malloc_stubborn, GC_debug_malloc_atomic, + GC_debug_malloc_uncollectable, GC_debug_malloc_atomic_uncollectable): + Use SIZET_SAT_ADD (instead of "+" operator) to add extra bytes to lb + value. + * fnlz_mlc.c (GC_finalized_malloc): Likewise. + * gcj_mlc.c (GC_debug_gcj_malloc): Likewise. + * include/private/gc_priv.h (ROUNDUP_GRANULE_SIZE, ROUNDED_UP_GRANULES, + ADD_SLOP, ROUNDUP_PAGESIZE): Likewise. + * include/private/gcconfig.h (GET_MEM): Likewise. + * mallocx.c (GC_malloc_many, GC_memalign): Likewise. + * os_dep.c (GC_wince_get_mem, GC_win32_get_mem): Likewise. + * typd_mlc.c (GC_malloc_explicitly_typed, + GC_malloc_explicitly_typed_ignore_off_page, + GC_calloc_explicitly_typed): Likewise. + * headers.c (GC_scratch_alloc): Change type of bytes_to_get from word + to size_t (because ROUNDUP_PAGESIZE_IF_MMAP result type changed). + * include/private/gc_priv.h: Include limits.h (unless SIZE_MAX already + defined). + * include/private/gc_priv.h (GC_SIZE_MAX, GC_SQRT_SIZE_MAX): Move from + malloc.c file. + * include/private/gc_priv.h (SIZET_SAT_ADD): New macro (defined before + include gcconfig.h). + * include/private/gc_priv.h (EXTRA_BYTES, GC_page_size): Change type + to size_t. + * os_dep.c (GC_page_size): Likewise. + * include/private/gc_priv.h (ROUNDUP_GRANULE_SIZE, ROUNDED_UP_GRANULES, + ADD_SLOP, ROUNDUP_PAGESIZE): Add comment about the argument. + * include/private/gcconfig.h (GET_MEM): Likewise. + * include/private/gc_priv.h (ROUNDUP_GRANULE_SIZE, ROUNDED_UP_GRANULES, + ADD_SLOP, OBJ_SZ_TO_BLOCKS, ROUNDUP_PAGESIZE, + ROUNDUP_PAGESIZE_IF_MMAP): Rename argument to "lb". + * include/private/gc_priv.h (OBJ_SZ_TO_BLOCKS_CHECKED): New macro. + * include/private/gcconfig.h (GC_win32_get_mem, GC_wince_get_mem, + GC_unix_get_mem): Change argument type from word to int. + * os_dep.c (GC_unix_mmap_get_mem, GC_unix_get_mem, + GC_unix_sbrk_get_mem, GC_wince_get_mem, GC_win32_get_mem): Likewise. + * malloc.c (GC_alloc_large_and_clear): Call OBJ_SZ_TO_BLOCKS only + if no value wrap around is guaranteed. + * malloc.c (GC_generic_malloc): Do not check for lb_rounded < lb case + (because ROUNDED_UP_GRANULES and GRANULES_TO_BYTES guarantees no value + wrap around). + * mallocx.c (GC_generic_malloc_ignore_off_page): Likewise. + * misc.c (GC_init_size_map): Change "i" local variable type from int + to size_t. + * os_dep.c (GC_write_fault_handler, catch_exception_raise): Likewise. + * misc.c (GC_envfile_init): Cast len to size_t when passed to + ROUNDUP_PAGESIZE_IF_MMAP. + * os_dep.c (GC_setpagesize): Cast GC_sysinfo.dwPageSize and + GETPAGESIZE() to size_t (when setting GC_page_size). + * os_dep.c (GC_unix_mmap_get_mem): + Expand ROUNDUP_PAGESIZE macro but without value wrap-around checking + (the argument is of word type). + * os_dep.c (GC_unix_mmap_get_mem): Replace -GC_page_size with + ~GC_page_size+1 (because GC_page_size is unsigned); remove redundant + cast to size_t. + * os_dep.c (GC_unix_sbrk_get_mem): Add explicit cast of GC_page_size + to SBRK_ARG_T. + * os_dep.c (GC_wince_get_mem): Change type of res_bytes local variable + to size_t. + * typd_mlc.c: Do not include limits.h. + * typd_mlc.c (GC_SIZE_MAX, GC_SQRT_SIZE_MAX): Remove (as defined in + gc_priv.h now). + +CVE-2016-9427 + +Index: libgc-7.4.2/allchblk.c +=================================================================== +--- libgc-7.4.2.orig/allchblk.c ++++ libgc-7.4.2/allchblk.c +@@ -583,7 +583,7 @@ GC_allochblk(size_t sz, int kind, unsign + /* split. */ + + GC_ASSERT((sz & (GRANULE_BYTES - 1)) == 0); +- blocks = OBJ_SZ_TO_BLOCKS(sz); ++ blocks = OBJ_SZ_TO_BLOCKS_CHECKED(sz); + if ((signed_word)(blocks * HBLKSIZE) < 0) { + return 0; + } +@@ -646,7 +646,7 @@ GC_allochblk_nth(size_t sz, int kind, un + signed_word size_needed; /* number of bytes in requested objects */ + signed_word size_avail; /* bytes available in this block */ + +- size_needed = HBLKSIZE * OBJ_SZ_TO_BLOCKS(sz); ++ size_needed = HBLKSIZE * OBJ_SZ_TO_BLOCKS_CHECKED(sz); + + /* search for a big enough block in free list */ + for (hbp = GC_hblkfreelist[n];; hbp = hhdr -> hb_next) { +Index: libgc-7.4.2/alloc.c +=================================================================== +--- libgc-7.4.2.orig/alloc.c ++++ libgc-7.4.2/alloc.c +@@ -1154,32 +1154,28 @@ GC_word GC_max_retries = 0; + /* Returns FALSE on failure. */ + GC_INNER GC_bool GC_expand_hp_inner(word n) + { +- word bytes; ++ size_t bytes; + struct hblk * space; + word expansion_slop; /* Number of bytes by which we expect the */ + /* heap to expand soon. */ + + if (n < MINHINCR) n = MINHINCR; +- bytes = n * HBLKSIZE; +- /* Make sure bytes is a multiple of GC_page_size */ +- { +- word mask = GC_page_size - 1; +- bytes += mask; +- bytes &= ~mask; +- } +- +- if (GC_max_heapsize != 0 && GC_heapsize + bytes > GC_max_heapsize) { ++ bytes = ROUNDUP_PAGESIZE((size_t)n * HBLKSIZE); ++ if (GC_max_heapsize != 0 ++ && (GC_max_heapsize < (word)bytes ++ || GC_heapsize > GC_max_heapsize - (word)bytes)) { + /* Exceeded self-imposed limit */ + return(FALSE); + } + space = GET_MEM(bytes); + GC_add_to_our_memory((ptr_t)space, bytes); + if (space == 0) { +- WARN("Failed to expand heap by %" WARN_PRIdPTR " bytes\n", bytes); ++ WARN("Failed to expand heap by %" WARN_PRIdPTR " bytes\n", ++ (word)bytes); + return(FALSE); + } + GC_INFOLOG_PRINTF("Grow heap to %lu KiB after %lu bytes allocated\n", +- TO_KiB_UL(GC_heapsize + bytes), ++ TO_KiB_UL(GC_heapsize + (word)bytes), + (unsigned long)GC_bytes_allocd); + /* Adjust heap limits generously for blacklisting to work better. */ + /* GC_add_to_heap performs minimal adjustment needed for */ +@@ -1189,7 +1185,7 @@ GC_INNER GC_bool GC_expand_hp_inner(word + || (GC_last_heap_addr != 0 + && (word)GC_last_heap_addr < (word)space)) { + /* Assume the heap is growing up */ +- word new_limit = (word)space + bytes + expansion_slop; ++ word new_limit = (word)space + (word)bytes + expansion_slop; + if (new_limit > (word)space) { + GC_greatest_plausible_heap_addr = + (void *)GC_max((word)GC_greatest_plausible_heap_addr, +Index: libgc-7.4.2/dbg_mlc.c +=================================================================== +--- libgc-7.4.2.orig/dbg_mlc.c ++++ libgc-7.4.2/dbg_mlc.c +@@ -514,7 +514,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_ + /* Note that according to malloc() specification, if size is 0 then */ + /* malloc() returns either NULL, or a unique pointer value that can */ + /* later be successfully passed to free(). We always do the latter. */ +- result = GC_malloc(lb + DEBUG_BYTES); ++ result = GC_malloc(SIZET_SAT_ADD(lb, DEBUG_BYTES)); + # ifdef GC_ADD_CALLER + if (s == NULL) { + GC_caller_func_offset(ra, &s, &i); +@@ -535,7 +535,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_ + GC_API GC_ATTR_MALLOC void * GC_CALL + GC_debug_malloc_ignore_off_page(size_t lb, GC_EXTRA_PARAMS) + { +- void * result = GC_malloc_ignore_off_page(lb + DEBUG_BYTES); ++ void * result = GC_malloc_ignore_off_page(SIZET_SAT_ADD(lb, DEBUG_BYTES)); + + if (result == 0) { + GC_err_printf("GC_debug_malloc_ignore_off_page(%lu)" +@@ -552,7 +552,8 @@ GC_API GC_ATTR_MALLOC void * GC_CALL + GC_API GC_ATTR_MALLOC void * GC_CALL + GC_debug_malloc_atomic_ignore_off_page(size_t lb, GC_EXTRA_PARAMS) + { +- void * result = GC_malloc_atomic_ignore_off_page(lb + DEBUG_BYTES); ++ void * result = GC_malloc_atomic_ignore_off_page( ++ SIZET_SAT_ADD(lb, DEBUG_BYTES)); + + if (result == 0) { + GC_err_printf("GC_debug_malloc_atomic_ignore_off_page(%lu)" +@@ -574,7 +575,8 @@ GC_API GC_ATTR_MALLOC void * GC_CALL + /* we already hold the GC lock. */ + GC_INNER void * GC_debug_generic_malloc_inner(size_t lb, int k) + { +- void * result = GC_generic_malloc_inner(lb + DEBUG_BYTES, k); ++ void * result = GC_generic_malloc_inner( ++ SIZET_SAT_ADD(lb, DEBUG_BYTES), k); + + if (result == 0) { + GC_err_printf("GC internal allocation (%lu bytes) returning NULL\n", +@@ -592,7 +594,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL + int k) + { + void * result = GC_generic_malloc_inner_ignore_off_page( +- lb + DEBUG_BYTES, k); ++ SIZET_SAT_ADD(lb, DEBUG_BYTES), k); + + if (result == 0) { + GC_err_printf("GC internal allocation (%lu bytes) returning NULL\n", +@@ -611,7 +613,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL + GC_API GC_ATTR_MALLOC void * GC_CALL GC_debug_malloc_stubborn(size_t lb, + GC_EXTRA_PARAMS) + { +- void * result = GC_malloc_stubborn(lb + DEBUG_BYTES); ++ void * result = GC_malloc_stubborn(SIZET_SAT_ADD(lb, DEBUG_BYTES)); + + if (result == 0) { + GC_err_printf("GC_debug_malloc_stubborn(%lu)" +@@ -674,7 +676,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL + GC_API GC_ATTR_MALLOC void * GC_CALL GC_debug_malloc_atomic(size_t lb, + GC_EXTRA_PARAMS) + { +- void * result = GC_malloc_atomic(lb + DEBUG_BYTES); ++ void * result = GC_malloc_atomic(SIZET_SAT_ADD(lb, DEBUG_BYTES)); + + if (result == 0) { + GC_err_printf("GC_debug_malloc_atomic(%lu) returning NULL (%s:%d)\n", +@@ -752,7 +754,8 @@ GC_API GC_ATTR_MALLOC char * GC_CALL GC_ + GC_API GC_ATTR_MALLOC void * GC_CALL GC_debug_malloc_uncollectable(size_t lb, + GC_EXTRA_PARAMS) + { +- void * result = GC_malloc_uncollectable(lb + UNCOLLECTABLE_DEBUG_BYTES); ++ void * result = GC_malloc_uncollectable( ++ SIZET_SAT_ADD(lb, UNCOLLECTABLE_DEBUG_BYTES)); + + if (result == 0) { + GC_err_printf("GC_debug_malloc_uncollectable(%lu)" +@@ -770,8 +773,8 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_ + GC_API GC_ATTR_MALLOC void * GC_CALL + GC_debug_malloc_atomic_uncollectable(size_t lb, GC_EXTRA_PARAMS) + { +- void * result = +- GC_malloc_atomic_uncollectable(lb + UNCOLLECTABLE_DEBUG_BYTES); ++ void * result = GC_malloc_atomic_uncollectable( ++ SIZET_SAT_ADD(lb, UNCOLLECTABLE_DEBUG_BYTES)); + + if (result == 0) { + GC_err_printf("GC_debug_malloc_atomic_uncollectable(%lu)" +Index: libgc-7.4.2/fnlz_mlc.c +=================================================================== +--- libgc-7.4.2.orig/fnlz_mlc.c ++++ libgc-7.4.2/fnlz_mlc.c +@@ -94,7 +94,7 @@ GC_API void GC_CALL GC_register_disclaim + word lg; + DCL_LOCK_STATE; + +- lb += sizeof(word); ++ lb = SIZET_SAT_ADD(lb, sizeof(word)); + GC_ASSERT(done_init); + if (SMALL_OBJ(lb)) { + GC_DBG_COLLECT_AT_MALLOC(lb); +Index: libgc-7.4.2/gcj_mlc.c +=================================================================== +--- libgc-7.4.2.orig/gcj_mlc.c ++++ libgc-7.4.2/gcj_mlc.c +@@ -216,7 +216,8 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_ + /* confuse the backtrace. */ + LOCK(); + maybe_finalize(); +- result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind); ++ result = GC_generic_malloc_inner(SIZET_SAT_ADD(lb, DEBUG_BYTES), ++ GC_gcj_debug_kind); + if (result == 0) { + GC_oom_func oom_fn = GC_oom_fn; + UNLOCK(); +Index: libgc-7.4.2/headers.c +=================================================================== +--- libgc-7.4.2.orig/headers.c ++++ libgc-7.4.2/headers.c +@@ -119,8 +119,7 @@ GC_INNER ptr_t GC_scratch_alloc(size_t b + { + register ptr_t result = scratch_free_ptr; + +- bytes += GRANULE_BYTES-1; +- bytes &= ~(GRANULE_BYTES-1); ++ bytes = ROUNDUP_GRANULE_SIZE(bytes); + scratch_free_ptr += bytes; + if ((word)scratch_free_ptr <= (word)GC_scratch_end_ptr) { + return(result); +Index: libgc-7.4.2/include/private/gc_priv.h +=================================================================== +--- libgc-7.4.2.orig/include/private/gc_priv.h ++++ libgc-7.4.2/include/private/gc_priv.h +@@ -90,6 +90,20 @@ typedef char * ptr_t; /* A generic poi + /* byte displacements and which can be used */ + /* for address comparisons. */ + ++#ifndef SIZE_MAX ++# include ++#endif ++#ifdef SIZE_MAX ++# define GC_SIZE_MAX SIZE_MAX ++#else ++# define GC_SIZE_MAX (~(size_t)0) ++#endif ++ ++/* Saturated addition of size_t values. Used to avoid value wrap */ ++/* around on overflow. The arguments should have no side effects. */ ++#define SIZET_SAT_ADD(a, b) \ ++ ((a) < GC_SIZE_MAX - (b) ? (a) + (b) : GC_SIZE_MAX) ++ + #ifndef GCCONFIG_H + # include "gcconfig.h" + #endif +@@ -277,9 +291,9 @@ typedef char * ptr_t; /* A generic poi + # ifdef LINT2 + /* Explicitly instruct the code analysis tool that */ + /* GC_all_interior_pointers is assumed to have only 0 or 1 value. */ +-# define EXTRA_BYTES (GC_all_interior_pointers? 1 : 0) ++# define EXTRA_BYTES ((size_t)(GC_all_interior_pointers? 1 : 0)) + # else +-# define EXTRA_BYTES GC_all_interior_pointers ++# define EXTRA_BYTES (size_t)GC_all_interior_pointers + # endif + # define MAX_EXTRA_BYTES 1 + #else +@@ -735,6 +749,7 @@ GC_EXTERN GC_warn_proc GC_current_warn_p + # define LOG_HBLKSIZE ((size_t)CPP_LOG_HBLKSIZE) + # define HBLKSIZE ((size_t)CPP_HBLKSIZE) + ++#define GC_SQRT_SIZE_MAX ((((size_t)1) << (WORDSZ / 2)) - 1) + + /* max size objects supported by freelist (larger objects are */ + /* allocated directly with allchblk(), by rounding to the next */ +@@ -763,9 +778,12 @@ GC_EXTERN GC_warn_proc GC_current_warn_p + + # define HBLKDISPL(objptr) (((size_t) (objptr)) & (HBLKSIZE-1)) + ++/* Round up allocation size (in bytes) to a multiple of a granule. */ ++#define ROUNDUP_GRANULE_SIZE(lb) /* lb should have no side-effect */ \ ++ (SIZET_SAT_ADD(lb, GRANULE_BYTES - 1) & ~(GRANULE_BYTES - 1)) + /* Round up byte allocation requests to integral number of words, etc. */ +-# define ROUNDED_UP_GRANULES(n) \ +- BYTES_TO_GRANULES((n) + (GRANULE_BYTES - 1 + EXTRA_BYTES)) ++# define ROUNDED_UP_GRANULES(lb) /* lb should have no side-effect */ \ ++ BYTES_TO_GRANULES(SIZET_SAT_ADD(lb, GRANULE_BYTES - 1 + EXTRA_BYTES)) + # if MAX_EXTRA_BYTES == 0 + # define SMALL_OBJ(bytes) EXPECT((bytes) <= (MAXOBJBYTES), TRUE) + # else +@@ -775,7 +793,8 @@ GC_EXTERN GC_warn_proc GC_current_warn_p + /* This really just tests bytes <= MAXOBJBYTES - EXTRA_BYTES. */ + /* But we try to avoid looking up EXTRA_BYTES. */ + # endif +-# define ADD_SLOP(bytes) ((bytes) + EXTRA_BYTES) ++# define ADD_SLOP(lb) /* lb should have no side-effect */ \ ++ SIZET_SAT_ADD(lb, EXTRA_BYTES) + # ifndef MIN_WORDS + # define MIN_WORDS 2 /* FIXME: obsolete */ + # endif +@@ -990,9 +1009,11 @@ struct hblk { + + # define HBLK_IS_FREE(hdr) (((hdr) -> hb_flags & FREE_BLK) != 0) + +-# define OBJ_SZ_TO_BLOCKS(sz) divHBLKSZ((sz) + HBLKSIZE-1) ++# define OBJ_SZ_TO_BLOCKS(lb) divHBLKSZ((lb) + HBLKSIZE-1) ++# define OBJ_SZ_TO_BLOCKS_CHECKED(lb) /* lb should have no side-effect */ \ ++ divHBLKSZ(SIZET_SAT_ADD(lb, HBLKSIZE - 1)) + /* Size of block (in units of HBLKSIZE) needed to hold objects of */ +- /* given sz (in bytes). */ ++ /* given lb (in bytes). The checked variant prevents wrap around. */ + + /* Object free list link */ + # define obj_link(p) (*(void **)(p)) +@@ -1394,18 +1415,18 @@ GC_EXTERN word GC_n_heap_sects; /* Numbe + /* sections. */ + #endif + +-GC_EXTERN word GC_page_size; ++GC_EXTERN size_t GC_page_size; + + /* Round up allocation size to a multiple of a page size. */ + /* GC_setpagesize() is assumed to be already invoked. */ +-#define ROUNDUP_PAGESIZE(bytes) \ +- (((bytes) + GC_page_size - 1) & ~(GC_page_size - 1)) ++#define ROUNDUP_PAGESIZE(lb) /* lb should have no side-effect */ \ ++ (SIZET_SAT_ADD(lb, GC_page_size - 1) & ~(GC_page_size - 1)) + + /* Same as above but used to make GET_MEM() argument safe. */ + #ifdef MMAP_SUPPORTED +-# define ROUNDUP_PAGESIZE_IF_MMAP(bytes) ROUNDUP_PAGESIZE(bytes) ++# define ROUNDUP_PAGESIZE_IF_MMAP(lb) ROUNDUP_PAGESIZE(lb) + #else +-# define ROUNDUP_PAGESIZE_IF_MMAP(bytes) (bytes) ++# define ROUNDUP_PAGESIZE_IF_MMAP(lb) (lb) + #endif + + #if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) +Index: libgc-7.4.2/include/private/gcconfig.h +=================================================================== +--- libgc-7.4.2.orig/include/private/gcconfig.h ++++ libgc-7.4.2/include/private/gcconfig.h +@@ -2912,7 +2912,8 @@ + /* usually makes it possible to merge consecutively allocated */ + /* chunks. It also avoids unintended recursion with */ + /* REDIRECT_MALLOC macro defined. */ +- /* GET_MEM() returns a HLKSIZE aligned chunk. */ ++ /* GET_MEM() argument should be of size_t type and have */ ++ /* no side-effect. GET_MEM() returns HLKSIZE-aligned chunk; */ + /* 0 is taken to mean failure. */ + /* In case of MMAP_SUPPORTED, the argument must also be */ + /* a multiple of a physical page size. */ +@@ -2922,45 +2923,52 @@ + struct hblk; /* See gc_priv.h. */ + # if defined(PCR) + char * real_malloc(size_t bytes); +-# define GET_MEM(bytes) HBLKPTR(real_malloc((size_t)(bytes) + GC_page_size) \ ++# define GET_MEM(bytes) HBLKPTR(real_malloc(SIZET_SAT_ADD(bytes, \ ++ GC_page_size)) \ + + GC_page_size-1) + # elif defined(OS2) + void * os2_alloc(size_t bytes); +-# define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc((size_t)(bytes) \ +- + GC_page_size) + GC_page_size-1) ++# define GET_MEM(bytes) HBLKPTR((ptr_t)os2_alloc( \ ++ SIZET_SAT_ADD(bytes, \ ++ GC_page_size)) \ ++ + GC_page_size-1) + # elif defined(NEXT) || defined(DOS4GW) || defined(NONSTOP) \ + || (defined(AMIGA) && !defined(GC_AMIGA_FASTALLOC)) \ + || (defined(SOLARIS) && !defined(USE_MMAP)) || defined(RTEMS) \ + || defined(__CC_ARM) + # define GET_MEM(bytes) HBLKPTR((size_t)calloc(1, \ +- (size_t)(bytes) + GC_page_size) \ ++ SIZET_SAT_ADD(bytes, \ ++ GC_page_size)) \ + + GC_page_size - 1) + # elif defined(MSWIN32) || defined(CYGWIN32) +- ptr_t GC_win32_get_mem(GC_word bytes); ++ ptr_t GC_win32_get_mem(size_t bytes); + # define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes) + # elif defined(MACOS) + # if defined(USE_TEMPORARY_MEMORY) + Ptr GC_MacTemporaryNewPtr(size_t size, Boolean clearMemory); +-# define GET_MEM(bytes) HBLKPTR( \ +- GC_MacTemporaryNewPtr((bytes) + GC_page_size, true) \ ++# define GET_MEM(bytes) HBLKPTR(GC_MacTemporaryNewPtr( \ ++ SIZET_SAT_ADD(bytes, \ ++ GC_page_size), true) \ + + GC_page_size-1) + # else +-# define GET_MEM(bytes) HBLKPTR(NewPtrClear((bytes) + GC_page_size) \ ++# define GET_MEM(bytes) HBLKPTR(NewPtrClear(SIZET_SAT_ADD(bytes, \ ++ GC_page_size)) \ + + GC_page_size-1) + # endif + # elif defined(MSWINCE) +- ptr_t GC_wince_get_mem(GC_word bytes); ++ ptr_t GC_wince_get_mem(size_t bytes); + # define GET_MEM(bytes) (struct hblk *)GC_wince_get_mem(bytes) + # elif defined(AMIGA) && defined(GC_AMIGA_FASTALLOC) +- void *GC_amiga_get_mem(size_t size); +-# define GET_MEM(bytes) HBLKPTR((size_t) \ +- GC_amiga_get_mem((size_t)(bytes) + GC_page_size) \ ++ void *GC_amiga_get_mem(size_t bytes); ++# define GET_MEM(bytes) HBLKPTR((size_t)GC_amiga_get_mem( \ ++ SIZET_SAT_ADD(bytes, \ ++ GC_page_size)) \ + + GC_page_size-1) + # elif defined(SN_TARGET_PS3) + void *ps3_get_mem(size_t size); + # define GET_MEM(bytes) (struct hblk*)ps3_get_mem(bytes) + # else +- ptr_t GC_unix_get_mem(GC_word bytes); ++ ptr_t GC_unix_get_mem(size_t bytes); + # define GET_MEM(bytes) (struct hblk *)GC_unix_get_mem(bytes) + # endif + #endif /* GC_PRIVATE_H */ +Index: libgc-7.4.2/malloc.c +=================================================================== +--- libgc-7.4.2.orig/malloc.c ++++ libgc-7.4.2/malloc.c +@@ -46,9 +46,8 @@ GC_INNER ptr_t GC_alloc_large(size_t lb, + ptr_t result; + GC_bool retry = FALSE; + +- /* Round up to a multiple of a granule. */ +- lb = (lb + GRANULE_BYTES - 1) & ~(GRANULE_BYTES - 1); +- n_blocks = OBJ_SZ_TO_BLOCKS(lb); ++ lb = ROUNDUP_GRANULE_SIZE(lb); ++ n_blocks = OBJ_SZ_TO_BLOCKS_CHECKED(lb); + if (!EXPECT(GC_is_initialized, TRUE)) GC_init(); + /* Do our share of marking work */ + if (GC_incremental && !GC_dont_gc) +@@ -85,10 +84,11 @@ GC_INNER ptr_t GC_alloc_large(size_t lb, + STATIC ptr_t GC_alloc_large_and_clear(size_t lb, int k, unsigned flags) + { + ptr_t result = GC_alloc_large(lb, k, flags); +- word n_blocks = OBJ_SZ_TO_BLOCKS(lb); + + if (0 == result) return 0; + if (GC_debugging_started || GC_obj_kinds[k].ok_init) { ++ word n_blocks = OBJ_SZ_TO_BLOCKS(lb); ++ + /* Clear the whole block, in case of GC_realloc call. */ + BZERO(result, n_blocks * HBLKSIZE); + } +@@ -189,8 +189,6 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_ + + 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(); +@@ -396,15 +394,6 @@ void * malloc(size_t lb) + } + #endif /* GC_LINUX_THREADS */ + +-#include +-#ifdef SIZE_MAX +-# define GC_SIZE_MAX SIZE_MAX +-#else +-# 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_SQRT_SIZE_MAX /* fast initial test */ +Index: libgc-7.4.2/mallocx.c +=================================================================== +--- libgc-7.4.2.orig/mallocx.c ++++ libgc-7.4.2/mallocx.c +@@ -180,8 +180,6 @@ GC_API GC_ATTR_MALLOC void * GC_CALL + 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)) +@@ -438,9 +436,11 @@ GC_API void GC_CALL GC_generic_malloc_ma + GC_API GC_ATTR_MALLOC void * GC_CALL GC_malloc_many(size_t lb) + { + void *result; +- GC_generic_malloc_many((lb + EXTRA_BYTES + GRANULE_BYTES-1) +- & ~(GRANULE_BYTES-1), +- NORMAL, &result); ++ /* Add EXTRA_BYTES and round up to a multiple of a granule. */ ++ lb = SIZET_SAT_ADD(lb, EXTRA_BYTES + GRANULE_BYTES - 1) ++ & ~(GRANULE_BYTES - 1); ++ ++ GC_generic_malloc_many(lb, NORMAL, &result); + return result; + } + +@@ -464,7 +464,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_ + } + /* We could also try to make sure that the real rounded-up object size */ + /* is a multiple of align. That would be correct up to HBLKSIZE. */ +- new_lb = lb + align - 1; ++ new_lb = SIZET_SAT_ADD(lb, align - 1); + result = GC_malloc(new_lb); + /* It is OK not to check result for NULL as in that case */ + /* GC_memalign returns NULL too since (0 + 0 % align) is 0. */ +Index: libgc-7.4.2/misc.c +=================================================================== +--- libgc-7.4.2.orig/misc.c ++++ libgc-7.4.2/misc.c +@@ -226,7 +226,7 @@ GC_API void GC_CALL GC_set_handle_fork(i + /* quantization algorithm (but we precompute it). */ + STATIC void GC_init_size_map(void) + { +- int i; ++ size_t i; + + /* Map size 0 to something bigger. */ + /* This avoids problems at lower levels. */ +@@ -678,7 +678,7 @@ GC_API void GC_CALL GC_get_heap_usage_sa + } + /* At this execution point, GC_setpagesize() and GC_init_win32() */ + /* must already be called (for GET_MEM() to work correctly). */ +- content = (char *)GET_MEM(ROUNDUP_PAGESIZE_IF_MMAP(len + 1)); ++ content = (char *)GET_MEM(ROUNDUP_PAGESIZE_IF_MMAP((size_t)len + 1)); + if (content == NULL) { + CloseHandle(hFile); + return; /* allocation failure */ +Index: libgc-7.4.2/os_dep.c +=================================================================== +--- libgc-7.4.2.orig/os_dep.c ++++ libgc-7.4.2/os_dep.c +@@ -713,7 +713,7 @@ struct o32_obj { + # endif /* OS/2 */ + + /* Find the page size */ +-GC_INNER word GC_page_size = 0; ++GC_INNER size_t GC_page_size = 0; + + #if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) + # ifndef VER_PLATFORM_WIN32_CE +@@ -729,7 +729,7 @@ GC_INNER word GC_page_size = 0; + GC_INNER void GC_setpagesize(void) + { + GetSystemInfo(&GC_sysinfo); +- GC_page_size = GC_sysinfo.dwPageSize; ++ GC_page_size = (size_t)GC_sysinfo.dwPageSize; + # if defined(MSWINCE) && !defined(_WIN32_WCE_EMULATION) + { + OSVERSIONINFO verInfo; +@@ -813,7 +813,7 @@ GC_INNER word GC_page_size = 0; + GC_INNER void GC_setpagesize(void) + { + # if defined(MPROTECT_VDB) || defined(PROC_VDB) || defined(USE_MMAP) +- GC_page_size = GETPAGESIZE(); ++ GC_page_size = (size_t)GETPAGESIZE(); + if (!GC_page_size) ABORT("getpagesize failed"); + # else + /* It's acceptable to fake it. */ +@@ -2037,7 +2037,7 @@ void GC_register_data_segments(void) + extern char* GC_get_private_path_and_zero_file(void); + #endif + +-STATIC ptr_t GC_unix_mmap_get_mem(word bytes) ++STATIC ptr_t GC_unix_mmap_get_mem(size_t bytes) + { + void *result; + static ptr_t last_addr = HEAP_START; +@@ -2075,7 +2075,7 @@ STATIC ptr_t GC_unix_mmap_get_mem(word b + /* Oops. We got the end of the address space. This isn't */ + /* usable by arbitrary C code, since one-past-end pointers */ + /* don't work, so we discard it and try again. */ +- munmap(result, (size_t)(-GC_page_size) - (size_t)result); ++ munmap(result, ~GC_page_size - (size_t)result + 1); + /* Leave last page mapped, so we can't repeat. */ + return GC_unix_mmap_get_mem(bytes); + } +@@ -2091,13 +2091,13 @@ STATIC ptr_t GC_unix_mmap_get_mem(word b + # endif /* MMAP_SUPPORTED */ + + #if defined(USE_MMAP) +- ptr_t GC_unix_get_mem(word bytes) ++ ptr_t GC_unix_get_mem(size_t bytes) + { + return GC_unix_mmap_get_mem(bytes); + } + #else /* !USE_MMAP */ + +-STATIC ptr_t GC_unix_sbrk_get_mem(word bytes) ++STATIC ptr_t GC_unix_sbrk_get_mem(size_t bytes) + { + ptr_t result; + # ifdef IRIX5 +@@ -2114,7 +2114,7 @@ STATIC ptr_t GC_unix_sbrk_get_mem(word b + goto out; + } + if (lsbs != 0) { +- if((ptr_t)sbrk(GC_page_size - lsbs) == (ptr_t)(-1)) { ++ if((ptr_t)sbrk((SBRK_ARG_T)GC_page_size - lsbs) == (ptr_t)(-1)) { + result = 0; + goto out; + } +@@ -2138,7 +2138,7 @@ STATIC ptr_t GC_unix_sbrk_get_mem(word b + return(result); + } + +-ptr_t GC_unix_get_mem(word bytes) ++ptr_t GC_unix_get_mem(size_t bytes) + { + # if defined(MMAP_SUPPORTED) + /* By default, we try both sbrk and mmap, in that order. */ +@@ -2184,7 +2184,7 @@ void * os2_alloc(size_t bytes) + # endif /* OS2 */ + + #ifdef MSWINCE +- ptr_t GC_wince_get_mem(word bytes) ++ ptr_t GC_wince_get_mem(size_t bytes) + { + ptr_t result = 0; /* initialized to prevent warning. */ + word i; +@@ -2204,8 +2204,9 @@ void * os2_alloc(size_t bytes) + + if (i == GC_n_heap_bases) { + /* Reserve more pages */ +- word res_bytes = (bytes + GC_sysinfo.dwAllocationGranularity-1) +- & ~(GC_sysinfo.dwAllocationGranularity-1); ++ size_t res_bytes = ++ SIZET_SAT_ADD(bytes, (size_t)GC_sysinfo.dwAllocationGranularity-1) ++ & ~((size_t)GC_sysinfo.dwAllocationGranularity-1); + /* If we ever support MPROTECT_VDB here, we will probably need to */ + /* ensure that res_bytes is strictly > bytes, so that VirtualProtect */ + /* never spans regions. It seems to be OK for a VirtualFree */ +@@ -2255,7 +2256,7 @@ void * os2_alloc(size_t bytes) + # define GC_mem_top_down 0 + # endif /* !GC_USE_MEM_TOP_DOWN */ + +- ptr_t GC_win32_get_mem(word bytes) ++ ptr_t GC_win32_get_mem(size_t bytes) + { + ptr_t result; + +@@ -2267,8 +2268,8 @@ void * os2_alloc(size_t bytes) + /* VirtualAlloc doesn't like PAGE_EXECUTE_READWRITE. */ + /* There are also unconfirmed rumors of other */ + /* problems, so we dodge the issue. */ +- result = (ptr_t) GlobalAlloc(0, bytes + HBLKSIZE); +- result = (ptr_t)(((word)result + HBLKSIZE - 1) & ~(HBLKSIZE-1)); ++ result = (ptr_t)(((word)GlobalAlloc(0, SIZET_SAT_ADD(bytes, HBLKSIZE)) ++ + HBLKSIZE - 1) & ~(HBLKSIZE - 1)); + } else + # endif + /* else */ { +@@ -2297,12 +2298,13 @@ void * os2_alloc(size_t bytes) + /* available. Otherwise we waste resources or possibly */ + /* cause VirtualAlloc to fail (observed in Windows 2000 */ + /* SP2). */ +- result = (ptr_t) VirtualAlloc(NULL, bytes + VIRTUAL_ALLOC_PAD, +- GetWriteWatch_alloc_flag ++ result = (ptr_t) VirtualAlloc(NULL, ++ SIZET_SAT_ADD(bytes, VIRTUAL_ALLOC_PAD), ++ GetWriteWatch_alloc_flag + | (MEM_COMMIT | MEM_RESERVE) + | GC_mem_top_down, +- GC_pages_executable ? PAGE_EXECUTE_READWRITE : +- PAGE_READWRITE); ++ GC_pages_executable ? PAGE_EXECUTE_READWRITE : ++ PAGE_READWRITE); + # undef IGNORE_PAGES_EXECUTABLE + } + # endif /* USE_WINALLOC */ +@@ -3137,7 +3139,7 @@ GC_API GC_push_other_roots_proc GC_CALL + char * addr = (char *) (exc_info -> ExceptionRecord + -> ExceptionInformation[1]); + # endif +- unsigned i; ++ size_t i; + + if (SIG_OK && CODE_OK) { + register struct hblk * h = +@@ -4321,7 +4323,7 @@ catch_exception_raise(mach_port_t except + kern_return_t r; + char *addr; + struct hblk *h; +- unsigned int i; ++ size_t i; + thread_state_flavor_t flavor = DARWIN_EXC_STATE; + mach_msg_type_number_t exc_state_count = DARWIN_EXC_STATE_COUNT; + DARWIN_EXC_STATE_T exc_state; +Index: libgc-7.4.2/typd_mlc.c +=================================================================== +--- libgc-7.4.2.orig/typd_mlc.c ++++ libgc-7.4.2/typd_mlc.c +@@ -589,7 +589,7 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_ + size_t lg; + DCL_LOCK_STATE; + +- lb += TYPD_EXTRA_BYTES; ++ lb = SIZET_SAT_ADD(lb, TYPD_EXTRA_BYTES); + if(SMALL_OBJ(lb)) { + GC_DBG_COLLECT_AT_MALLOC(lb); + lg = GC_size_map[lb]; +@@ -626,8 +626,8 @@ GC_API GC_ATTR_MALLOC void * GC_CALL + size_t lg; + DCL_LOCK_STATE; + +- lb += TYPD_EXTRA_BYTES; +- if( SMALL_OBJ(lb) ) { ++ lb = SIZET_SAT_ADD(lb, TYPD_EXTRA_BYTES); ++ if (SMALL_OBJ(lb)) { + GC_DBG_COLLECT_AT_MALLOC(lb); + lg = GC_size_map[lb]; + opp = &(GC_eobjfreelist[lg]); +@@ -655,15 +655,6 @@ GC_API GC_ATTR_MALLOC void * GC_CALL + return((void *) op); + } + +-#include +-#ifdef SIZE_MAX +-# define GC_SIZE_MAX SIZE_MAX +-#else +-# define GC_SIZE_MAX (~(size_t)0) +-#endif +- +-#define GC_SQRT_SIZE_MAX ((((size_t)1) << (WORDSZ / 2)) - 1) +- + GC_API GC_ATTR_MALLOC void * GC_CALL GC_calloc_explicitly_typed(size_t n, + size_t lb, GC_descr d) + { +@@ -687,10 +678,11 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_ + case SIMPLE: + return GC_malloc_explicitly_typed(lb, simple_descr); + case LEAF: +- lb += sizeof(struct LeafDescriptor) + TYPD_EXTRA_BYTES; ++ lb = SIZET_SAT_ADD(lb, ++ sizeof(struct LeafDescriptor) + TYPD_EXTRA_BYTES); + break; + case COMPLEX: +- lb += TYPD_EXTRA_BYTES; ++ lb = SIZET_SAT_ADD(lb, TYPD_EXTRA_BYTES); + break; + } + if( SMALL_OBJ(lb) ) { diff -Nru libgc-7.4.2/debian/patches/CVE-2016-9427-3.patch libgc-7.4.2/debian/patches/CVE-2016-9427-3.patch --- libgc-7.4.2/debian/patches/CVE-2016-9427-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ libgc-7.4.2/debian/patches/CVE-2016-9427-3.patch 2017-02-13 19:50:02.000000000 +0000 @@ -0,0 +1,36 @@ +commit 1f3c938e5482e3770df2163ab03ed760fd12155a +Author: Ivan Maidanski +Date: Tue Sep 27 10:12:18 2016 +0300 +Description: Fix GC_collect_or_expand to prevent allocation size value wrap-around + + Fix GC_collect_or_expand to prevent allocation size value wrap-around + + Relates to issue #135 on Github. + + * alloc.c (GC_WORD_MAX): New macro. + * alloc.c (GC_collect_or_expand): Limit blocks_to_get by + GC_WORD_MAX / HBLKSIZE value (to avoid multiplication overflow in + GC_expand_hp_inner). + +diff --git a/alloc.c b/alloc.c +index 946c464..894c798 100644 +--- a/alloc.c ++++ b/alloc.c +@@ -1238,6 +1238,8 @@ GC_INNER unsigned GC_fail_count = 0; + static word last_fo_entries = 0; + static word last_bytes_finalized = 0; + ++#define GC_WORD_MAX (~(word)0) ++ + /* Collect or expand heap in an attempt make the indicated number of */ + /* free blocks available. Should be called until the blocks are */ + /* available (setting retry value to TRUE unless this is the first call */ +@@ -1291,6 +1293,8 @@ GC_INNER GC_bool GC_collect_or_expand(word needed_blocks, + } else { + blocks_to_get = MAXHINCR; + } ++ if (blocks_to_get > divHBLKSZ(GC_WORD_MAX)) ++ blocks_to_get = divHBLKSZ(GC_WORD_MAX); + } + + if (!GC_expand_hp_inner(blocks_to_get) diff -Nru libgc-7.4.2/debian/patches/CVE-2016-9427-test.patch libgc-7.4.2/debian/patches/CVE-2016-9427-test.patch --- libgc-7.4.2/debian/patches/CVE-2016-9427-test.patch 1970-01-01 00:00:00.000000000 +0000 +++ libgc-7.4.2/debian/patches/CVE-2016-9427-test.patch 2017-02-13 19:50:02.000000000 +0000 @@ -0,0 +1,99 @@ +commit e273661227b4684265c09e04f75db81f7c5e697e +Author: Ivan Maidanski +Date: Thu Sep 29 00:32:47 2016 +0300 +Description: Add more cases to huge_test to cover sizes close to word-type maximum + + Add more cases to huge_test to cover sizes close to word-type maximum + + * tests/huge_test.c (GC_WORD_MAX): New macro. + * tests/huge_test.c (GC_SWORD_MAX): Use GC_WORD_MAX. + * tests/huge_test.c (main): Add GC_SWORD_MAX+1, GC_WORD_MAX, + GC_WORD_MAX-4/8/16/1024 test cases. + +[NOTE: this patch updates the version of huge_test.c to +e273661227b4684265c09e04f75db81f7c5e697e, incorporating +intermediate commits. -- sbeattie] + +Index: libgc-7.4.2/tests/huge_test.c +=================================================================== +--- libgc-7.4.2.orig/tests/huge_test.c ++++ libgc-7.4.2/tests/huge_test.c +@@ -5,11 +5,19 @@ + + #ifndef GC_IGNORE_WARN + /* Ignore misleading "Out of Memory!" warning (which is printed on */ +- /* every GC_MALLOC(LONG_MAX) call) by defining this macro before */ +- /* "gc.h" inclusion. */ ++ /* every GC_MALLOC call below) by defining this macro before "gc.h" */ ++ /* inclusion. */ + # define GC_IGNORE_WARN + #endif + ++#ifndef GC_MAXIMUM_HEAP_SIZE ++# define GC_MAXIMUM_HEAP_SIZE 100 * 1024 * 1024 ++# define GC_INITIAL_HEAP_SIZE GC_MAXIMUM_HEAP_SIZE / 20 ++ /* Otherwise heap expansion aborts when deallocating large block. */ ++ /* That's OK. We test this corner case mostly to make sure that */ ++ /* it fails predictably. */ ++#endif ++ + #include "gc.h" + + /* +@@ -19,34 +27,31 @@ + * expected manner. + */ + ++#define CHECK_ALLOC_FAILED(r, sz_str) \ ++ do { \ ++ if (NULL != (r)) { \ ++ fprintf(stderr, \ ++ "Size " sz_str " allocation unexpectedly succeeded\n"); \ ++ exit(1); \ ++ } \ ++ } while (0) ++ ++#define GC_WORD_MAX ((GC_word)-1) ++#define GC_SWORD_MAX ((GC_signed_word)(GC_WORD_MAX >> 1)) ++ + int main(void) + { + GC_INIT(); + +- GC_set_max_heap_size(100*1024*1024); +- /* Otherwise heap expansion aborts when deallocating large block. */ +- /* That's OK. We test this corner case mostly to make sure that */ +- /* it fails predictably. */ +- GC_expand_hp(1024*1024*5); +- if (sizeof(long) == sizeof(void *)) { +- void *r = GC_MALLOC(LONG_MAX-1024); +- if (0 != r) { +- fprintf(stderr, +- "Size LONG_MAX-1024 allocation unexpectedly succeeded\n"); +- exit(1); +- } +- r = GC_MALLOC(LONG_MAX); +- if (0 != r) { +- fprintf(stderr, +- "Size LONG_MAX allocation unexpectedly succeeded\n"); +- exit(1); +- } +- r = GC_MALLOC((size_t)LONG_MAX + 1024); +- if (0 != r) { +- fprintf(stderr, +- "Size LONG_MAX+1024 allocation unexpectedly succeeded\n"); +- exit(1); +- } +- } ++ CHECK_ALLOC_FAILED(GC_MALLOC(GC_SWORD_MAX - 1024), "SWORD_MAX-1024"); ++ CHECK_ALLOC_FAILED(GC_MALLOC(GC_SWORD_MAX), "SWORD_MAX"); ++ CHECK_ALLOC_FAILED(GC_MALLOC((GC_word)GC_SWORD_MAX + 1), "SWORD_MAX+1"); ++ CHECK_ALLOC_FAILED(GC_MALLOC((GC_word)GC_SWORD_MAX + 1024), ++ "SWORD_MAX+1024"); ++ CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX - 1024), "WORD_MAX-1024"); ++ CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX - 16), "WORD_MAX-16"); ++ CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX - 8), "WORD_MAX-8"); ++ CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX - 4), "WORD_MAX-4"); ++ CHECK_ALLOC_FAILED(GC_MALLOC(GC_WORD_MAX), "WORD_MAX"); + return 0; + } diff -Nru libgc-7.4.2/debian/patches/series libgc-7.4.2/debian/patches/series --- libgc-7.4.2/debian/patches/series 2016-05-17 14:27:01.000000000 +0000 +++ libgc-7.4.2/debian/patches/series 2017-02-13 19:16:57.000000000 +0000 @@ -2,3 +2,8 @@ enable-threads-on-hurd.diff enable-parallel-mark-where-supported.diff fix-location-of-assembly-files.diff +workaround-gcc-6-gnu++14.patch +CVE-2016-9427-test.patch +CVE-2016-9427-1.patch +CVE-2016-9427-2.patch +CVE-2016-9427-3.patch diff -Nru libgc-7.4.2/debian/patches/workaround-gcc-6-gnu++14.patch libgc-7.4.2/debian/patches/workaround-gcc-6-gnu++14.patch --- libgc-7.4.2/debian/patches/workaround-gcc-6-gnu++14.patch 1970-01-01 00:00:00.000000000 +0000 +++ libgc-7.4.2/debian/patches/workaround-gcc-6-gnu++14.patch 2017-02-13 19:15:12.000000000 +0000 @@ -0,0 +1,22 @@ +Author: Steve Beattie +Subject: Work around libgc test failure due to --std=gnu++14 +Bug-upstream: https://github.com/ivmai/bdwgc/issues/87 + +The test_cpp test fails when compiled with GCC 6, as used in Ubuntu +16.10 (yakkety) due to the change to use --std=gnu++14 by default in GCC +6. This patch works around the issue by recompiling the test program +using --std=gnu++98 (the old default); however, it's likely other C++ +programs that make use of libgc will have problems under GCC 6. + +Index: libgc-7.4.2/tests/tests.am +=================================================================== +--- libgc-7.4.2.orig/tests/tests.am ++++ libgc-7.4.2/tests/tests.am +@@ -96,6 +96,7 @@ if CPLUSPLUS + TESTS += test_cpp$(EXEEXT) + check_PROGRAMS += test_cpp + test_cpp_SOURCES = tests/test_cpp.cc ++test_cpp_CXXFLAGS = -std=gnu++98 + if AVOID_CPP_LIB + test_cpp_LDADD = gc_cpp.o $(test_ldadd) $(CXXLIBS) + else