From 180b56cc54c765a8ba0283f718cdf64f45090ccf Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Sun, 30 Mar 2014 12:31:49 +0400 Subject: [PATCH] Fix GET_MEM argument rounding in GC_scratch_alloc and similar (Prevent abort in GC_unix_mmap_get_mem if the allocation size is not a multiple of a page size.) * backgraph.c (new_back_edges, push_in_progress): Use ROUNDUP_PAGESIZE_IF_MMAP() to adjust GET_MEM() argument (when needed). * headers.c (GC_scratch_alloc): Likewise. * misc.c (GC_envfile_init): Likewise. * include/private/gc_priv.h (ROUNDUP_PAGESIZE_IF_MMAP): New macro. * include/private/gcconfig.h (MMAP_SUPPORTED): Move definition from os_dep.c (as needed for ROUNDUP_PAGESIZE_IF_MMAP() definition). * include/private/gcconfig.h (GET_MEM): Refine comment (regarding its argument). --- backgraph.c | 9 ++++++--- headers.c | 12 ++++-------- include/private/gc_priv.h | 7 +++++++ include/private/gcconfig.h | 9 +++++++-- misc.c | 2 +- os_dep.c | 5 ----- 6 files changed, 25 insertions(+), 19 deletions(-) diff --git a/backgraph.c b/backgraph.c index d6f3223d..5cc85b4a 100644 --- a/backgraph.c +++ b/backgraph.c @@ -86,8 +86,9 @@ static back_edges *avail_back_edges = 0; static back_edges * new_back_edges(void) { if (0 == back_edge_space) { - back_edge_space = (back_edges *) - GET_MEM(MAX_BACK_EDGE_STRUCTS*sizeof(back_edges)); + back_edge_space = (back_edges *)GET_MEM( + ROUNDUP_PAGESIZE_IF_MMAP(MAX_BACK_EDGE_STRUCTS + * sizeof(back_edges))); GC_add_to_our_memory((ptr_t)back_edge_space, MAX_BACK_EDGE_STRUCTS*sizeof(back_edges)); } @@ -127,7 +128,9 @@ static void push_in_progress(ptr_t p) { if (n_in_progress >= in_progress_size) { if (in_progress_size == 0) { - in_progress_size = INITIAL_IN_PROGRESS; + in_progress_size = ROUNDUP_PAGESIZE_IF_MMAP(INITIAL_IN_PROGRESS + * sizeof(ptr_t)) + / sizeof(ptr_t); in_progress_space = (ptr_t *)GET_MEM(in_progress_size * sizeof(ptr_t)); GC_add_to_our_memory((ptr_t)in_progress_space, in_progress_size * sizeof(ptr_t)); diff --git a/headers.c b/headers.c index 69f15751..ea83378e 100644 --- a/headers.c +++ b/headers.c @@ -129,25 +129,21 @@ GC_INNER ptr_t GC_scratch_alloc(size_t bytes) if (bytes_to_get <= bytes) { /* Undo the damage, and get memory directly */ - bytes_to_get = bytes; -# ifdef USE_MMAP - bytes_to_get = ROUNDUP_PAGESIZE(bytes_to_get); -# endif + bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(bytes); result = (ptr_t)GET_MEM(bytes_to_get); GC_add_to_our_memory(result, bytes_to_get); scratch_free_ptr -= bytes; GC_scratch_last_end_ptr = result + bytes; return(result); } + + bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(bytes_to_get); /* for safety */ result = (ptr_t)GET_MEM(bytes_to_get); GC_add_to_our_memory(result, bytes_to_get); if (result == 0) { WARN("Out of memory - trying to allocate less\n", 0); scratch_free_ptr -= bytes; - bytes_to_get = bytes; -# ifdef USE_MMAP - bytes_to_get = ROUNDUP_PAGESIZE(bytes_to_get); -# endif + bytes_to_get = ROUNDUP_PAGESIZE_IF_MMAP(bytes); result = (ptr_t)GET_MEM(bytes_to_get); GC_add_to_our_memory(result, bytes_to_get); return result; diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index fe77e3a2..c3235421 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -1407,6 +1407,13 @@ GC_EXTERN word GC_page_size; #define ROUNDUP_PAGESIZE(bytes) \ (((bytes) + 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) +#else +# define ROUNDUP_PAGESIZE_IF_MMAP(bytes) (bytes) +#endif + #if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) struct _SYSTEM_INFO; GC_EXTERN struct _SYSTEM_INFO GC_sysinfo; diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index 5bbf4940..de7998be 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -2558,6 +2558,11 @@ # undef USE_MMAP #endif +#if defined(LINUX) || defined(FREEBSD) || defined(SOLARIS) || defined(IRIX5) \ + || ((defined(USE_MMAP) || defined(USE_MUNMAP)) && !defined(USE_WINALLOC)) +# define MMAP_SUPPORTED +#endif + #if defined(GC_DISABLE_INCREMENTAL) || defined(MANUAL_VDB) # undef GWW_VDB # undef MPROTECT_VDB @@ -2894,8 +2899,8 @@ /* REDIRECT_MALLOC macro defined. */ /* GET_MEM() returns a HLKSIZE aligned chunk. */ /* 0 is taken to mean failure. */ - /* In the case os USE_MMAP, the argument must also be a */ - /* physical page size. */ + /* In case of MMAP_SUPPORTED, the argument must also be */ + /* a multiple of a physical page size. */ /* GET_MEM is currently not assumed to retrieve 0 filled space, */ /* though we should perhaps take advantage of the case in which */ /* does. */ diff --git a/misc.c b/misc.c index 1ca9dd1b..2aac144b 100644 --- a/misc.c +++ b/misc.c @@ -682,7 +682,7 @@ GC_API void GC_CALL GC_get_heap_usage_safe(GC_word *pheap_size, } /* At this execution point, GC_setpagesize() and GC_init_win32() */ /* must already be called (for GET_MEM() to work correctly). */ - content = (char *)GET_MEM(len + 1); + content = (char *)GET_MEM(ROUNDUP_PAGESIZE_IF_MMAP(len + 1)); if (content == NULL) { CloseHandle(hFile); return; /* allocation failure */ diff --git a/os_dep.c b/os_dep.c index e19fcc06..09327f57 100644 --- a/os_dep.c +++ b/os_dep.c @@ -98,11 +98,6 @@ # include /* for locking */ #endif -#if defined(LINUX) || defined(FREEBSD) || defined(SOLARIS) || defined(IRIX5) \ - || ((defined(USE_MMAP) || defined(USE_MUNMAP)) && !defined(USE_WINALLOC)) -# define MMAP_SUPPORTED -#endif - #if defined(MMAP_SUPPORTED) || defined(ADD_HEAP_GUARD_PAGES) # if defined(USE_MUNMAP) && !defined(USE_MMAP) # error "invalid config - USE_MUNMAP requires USE_MMAP" -- 2.40.0