You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by sf...@apache.org on 2014/05/14 23:14:05 UTC

svn commit: r1594720 - in /apr/apr/branches/1.6.x: ./ CHANGES configure.in memory/unix/apr_pools.c

Author: sf
Date: Wed May 14 21:14:05 2014
New Revision: 1594720

URL: http://svn.apache.org/r1594720
Log:
Backport r1593615, r1594708 from trunk:

    Add option to use guard pages
    
    Add new --enable-allocator-guard-pages configure option which works like
    --enable-allocator-uses-mmap, but will also add inaccessible guard pages before
    and after each memnode.  This will result in higher ressource usage but allow
    to find/protect against certain buffer overflow/overread bugs.


    Add a pointer to /proc/sys/vm/max_map_count for the guard page feature


Modified:
    apr/apr/branches/1.6.x/   (props changed)
    apr/apr/branches/1.6.x/CHANGES
    apr/apr/branches/1.6.x/configure.in
    apr/apr/branches/1.6.x/memory/unix/apr_pools.c

Propchange: apr/apr/branches/1.6.x/
------------------------------------------------------------------------------
  Merged /apr/apr/trunk:r1593615,1594708

Modified: apr/apr/branches/1.6.x/CHANGES
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.6.x/CHANGES?rev=1594720&r1=1594719&r2=1594720&view=diff
==============================================================================
--- apr/apr/branches/1.6.x/CHANGES [utf-8] (original)
+++ apr/apr/branches/1.6.x/CHANGES [utf-8] Wed May 14 21:14:05 2014
@@ -1,6 +1,12 @@
                                                      -*- coding: utf-8 -*-
 Changes for APR 1.6.0
 
+  *) Add new --enable-allocator-guard-pages which is like allocator-uses-mmap,
+     but will also add inaccessible guard pages before and after each memnode.
+     This will result in higher ressource usage but allow to find/protect
+     against certain buffer overflow/overread bugs. Under Linux, it may be
+     necessary to increase /proc/sys/vm/max_map_count . [Stefan Fritsch]
+
   *) Add new --enable-pool-concurrency-check configure option to detect
      thread-unsafe concurrent accesses to pools. Runtime costs should be
      relatively low. [Stefan Fritsch]

Modified: apr/apr/branches/1.6.x/configure.in
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.6.x/configure.in?rev=1594720&r1=1594719&r2=1594720&view=diff
==============================================================================
--- apr/apr/branches/1.6.x/configure.in (original)
+++ apr/apr/branches/1.6.x/configure.in Wed May 14 21:14:05 2014
@@ -1136,7 +1136,7 @@ esac
 
 AC_CHECK_HEADERS([sys/types.h sys/mman.h sys/ipc.h sys/mutex.h sys/shm.h sys/file.h kernel/OS.h os2.h windows.h])
 AC_CHECK_FUNCS([mmap munmap shm_open shm_unlink shmget shmat shmdt shmctl \
-                create_area])
+                create_area mprotect])
 
 APR_CHECK_DEFINE(MAP_ANON, sys/mman.h)
 AC_CHECK_FILE(/dev/zero)
@@ -1576,6 +1576,19 @@ AC_ARG_ENABLE(allocator-uses-mmap,
     fi ]
 )
 
+AC_ARG_ENABLE(allocator-guard-pages,
+  [  --enable-allocator-guard-pages  Use guard pages in apr_allocator
+                                  (implies --enable-allocator-uses-mmap) ] ,
+  [ if test "$enableval" = "yes"; then
+        APR_IFALLYES(header:sys/mman.h func:mmap func:munmap func:mprotect define:MAP_ANON,
+                     [AC_DEFINE(APR_ALLOCATOR_GUARD_PAGES, 1,
+                                [Define if apr_allocator should use guard pages]) ],
+                     [AC_MSG_ERROR([mmap()/MAP_ANON/mprotect() not supported]) ]
+                   )
+    fi ]
+)
+
+
 AC_ARG_ENABLE(pool-concurrency-check,
   [  --enable-pool-concurrency-check Check for concurrent usage of memory pools],
   [ if test "$enableval" = "yes"; then

Modified: apr/apr/branches/1.6.x/memory/unix/apr_pools.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.6.x/memory/unix/apr_pools.c?rev=1594720&r1=1594719&r2=1594720&view=diff
==============================================================================
--- apr/apr/branches/1.6.x/memory/unix/apr_pools.c (original)
+++ apr/apr/branches/1.6.x/memory/unix/apr_pools.c Wed May 14 21:14:05 2014
@@ -40,6 +40,10 @@
 #include <unistd.h>     /* for getpid and sysconf */
 #endif
 
+#if APR_ALLOCATOR_GUARD_PAGES && !APR_ALLOCATOR_USES_MMAP
+#define APR_ALLOCATOR_USES_MMAP   1
+#endif
+
 #if APR_ALLOCATOR_USES_MMAP
 #include <sys/mman.h>
 #endif
@@ -91,6 +95,16 @@ static unsigned int boundary_size;
 #define BOUNDARY_SIZE (1 << BOUNDARY_INDEX)
 #endif
 
+#if APR_ALLOCATOR_GUARD_PAGES
+#if defined(_SC_PAGESIZE)
+#define GUARDPAGE_SIZE boundary_size
+#else
+#error Cannot determine page size
+#endif /* _SC_PAGESIZE */
+#else
+#define GUARDPAGE_SIZE 0
+#endif /* APR_ALLOCATOR_GUARD_PAGES */
+
 /* 
  * Timing constants for killing subprocesses
  * There is a total 3-second delay between sending a SIGINT 
@@ -173,7 +187,8 @@ APR_DECLARE(void) apr_allocator_destroy(
         while ((node = *ref) != NULL) {
             *ref = node->next;
 #if APR_ALLOCATOR_USES_MMAP
-            munmap(node, (node->index+1) << BOUNDARY_INDEX);
+            munmap((char *)node - GUARDPAGE_SIZE,
+                   2 * GUARDPAGE_SIZE + ((node->index+1) << BOUNDARY_INDEX));
 #else
             free(node);
 #endif
@@ -362,7 +377,10 @@ apr_memnode_t *allocator_alloc(apr_alloc
     /* If we haven't got a suitable node, malloc a new one
      * and initialize it.
      */
-#if APR_ALLOCATOR_USES_MMAP
+#if APR_ALLOCATOR_GUARD_PAGES
+    if ((node = mmap(NULL, size + 2 * GUARDPAGE_SIZE, PROT_NONE,
+                     MAP_PRIVATE|MAP_ANON, -1, 0)) == MAP_FAILED)
+#elif APR_ALLOCATOR_USES_MMAP
     if ((node = mmap(NULL, size, PROT_READ|PROT_WRITE,
                      MAP_PRIVATE|MAP_ANON, -1, 0)) == MAP_FAILED)
 #else
@@ -370,6 +388,13 @@ apr_memnode_t *allocator_alloc(apr_alloc
 #endif
         return NULL;
 
+#if APR_ALLOCATOR_GUARD_PAGES
+    node = (apr_memnode_t *)((char *)node + GUARDPAGE_SIZE);
+    if (mprotect(node, size, PROT_READ|PROT_WRITE) != 0) {
+        munmap((char *)node - GUARDPAGE_SIZE, size + 2 * GUARDPAGE_SIZE);
+        return NULL;
+    }
+#endif
     node->index = index;
     node->endp = (char *)node + size;
 
@@ -452,7 +477,8 @@ void allocator_free(apr_allocator_t *all
         node = freelist;
         freelist = node->next;
 #if APR_ALLOCATOR_USES_MMAP
-        munmap(node, (node->index+1) << BOUNDARY_INDEX);
+        munmap((char *)node - GUARDPAGE_SIZE,
+               2 * GUARDPAGE_SIZE + ((node->index+1) << BOUNDARY_INDEX));
 #else
         free(node);
 #endif