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/09 22:29:25 UTC

svn commit: r1593615 - in /apr/apr/trunk: CHANGES configure.in memory/unix/apr_pools.c

Author: sf
Date: Fri May  9 20:29:25 2014
New Revision: 1593615

URL: http://svn.apache.org/r1593615
Log:
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.

Modified:
    apr/apr/trunk/CHANGES
    apr/apr/trunk/configure.in
    apr/apr/trunk/memory/unix/apr_pools.c

Modified: apr/apr/trunk/CHANGES
URL: http://svn.apache.org/viewvc/apr/apr/trunk/CHANGES?rev=1593615&r1=1593614&r2=1593615&view=diff
==============================================================================
--- apr/apr/trunk/CHANGES [utf-8] (original)
+++ apr/apr/trunk/CHANGES [utf-8] Fri May  9 20:29:25 2014
@@ -1,6 +1,11 @@
                                                      -*- coding: utf-8 -*-
 Changes for APR 2.0.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. [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/trunk/configure.in
URL: http://svn.apache.org/viewvc/apr/apr/trunk/configure.in?rev=1593615&r1=1593614&r2=1593615&view=diff
==============================================================================
--- apr/apr/trunk/configure.in (original)
+++ apr/apr/trunk/configure.in Fri May  9 20:29:25 2014
@@ -1032,7 +1032,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)
@@ -1492,6 +1492,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/trunk/memory/unix/apr_pools.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/memory/unix/apr_pools.c?rev=1593615&r1=1593614&r2=1593615&view=diff
==============================================================================
--- apr/apr/trunk/memory/unix/apr_pools.c (original)
+++ apr/apr/trunk/memory/unix/apr_pools.c Fri May  9 20:29:25 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
@@ -76,6 +80,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 
@@ -158,7 +172,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
@@ -347,7 +362,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
@@ -355,6 +373,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;
 
@@ -437,7 +462,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