]> granicus.if.org Git - gc/commitdiff
Fix GET_MEM argument rounding in GC_scratch_alloc and similar
authorIvan Maidanski <ivmai@mail.ru>
Sun, 30 Mar 2014 08:31:49 +0000 (12:31 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Sun, 30 Mar 2014 08:31:49 +0000 (12:31 +0400)
(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
headers.c
include/private/gc_priv.h
include/private/gcconfig.h
misc.c
os_dep.c

index d6f3223d7324f72acf3ddff5b135edced2aa2d22..5cc85b4a098663dff4bafecac9859c04aa44f759 100644 (file)
@@ -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));
index 69f15751a8afa3c57bd305e3396dd4f8b5b9a5aa..ea83378e89db5a201b229785e1f7b9801029d45a 100644 (file)
--- 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;
index fe77e3a20f8099d5f45859b34e6c53a21278aeb0..c3235421459d12616de8af4a9799d96f0339f5a9 100644 (file)
@@ -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;
index 5bbf494087a6d92e130f299821a44e25099b8972..de7998be0f5448151ef9c7b75925973a235073a0 100644 (file)
 # 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
         /* 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 1ca9dd1b4b8930b8781755375e598bbd3d87e034..2aac144b9ecab420cc9fbbeaac79e071e05d1605 100644 (file)
--- 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 */
index e19fcc06fff5b8b43afbc15d4e37f0917b1e82db..09327f572cc48da100414f104d0eb32ba6bee79b 100644 (file)
--- a/os_dep.c
+++ b/os_dep.c
 # include <malloc.h>   /* 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"