svn commit: r215307 - head/sys/vm

Konstantin Belousov kib at FreeBSD.org
Sun Nov 14 17:53:52 UTC 2010


Author: kib
Date: Sun Nov 14 17:53:52 2010
New Revision: 215307
URL: http://svn.freebsd.org/changeset/base/215307

Log:
  Implement a (soft) stack guard page for auto-growing stack mappings.
  The unmapped page separates the tip of the stack and possible adjanced
  segment, making some uses of stack overflow harder.  The stack growing
  code refuses to expand the segment to the last page of the reseved
  region when sysctl security.bsd.stack_guard_page is set to 1. The
  default value for sysctl and accompanying tunable is 0.
  
  Please note that mmap(MAP_FIXED) still can place a mapping right up to
  the stack, making continuous region.
  
  Reviewed by:	alc
  MFC after:	1 week

Modified:
  head/sys/vm/vm_map.c

Modified: head/sys/vm/vm_map.c
==============================================================================
--- head/sys/vm/vm_map.c	Sun Nov 14 17:24:15 2010	(r215306)
+++ head/sys/vm/vm_map.c	Sun Nov 14 17:53:52 2010	(r215307)
@@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/systm.h>
+#include <sys/kernel.h>
 #include <sys/ktr.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
@@ -76,6 +77,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/vnode.h>
 #include <sys/resourcevar.h>
 #include <sys/file.h>
+#include <sys/sysctl.h>
 #include <sys/sysent.h>
 #include <sys/shm.h>
 
@@ -3216,6 +3218,12 @@ vm_map_stack(vm_map_t map, vm_offset_t a
 	return (rv);
 }
 
+static int stack_guard_page = 0;
+TUNABLE_INT("security.bsd.stack_guard_page", &stack_guard_page);
+SYSCTL_INT(_security_bsd, OID_AUTO, stack_guard_page, CTLFLAG_RW,
+    &stack_guard_page, 0,
+    "Insert stack guard page ahead of the growable segments.");
+
 /* Attempts to grow a vm stack entry.  Returns KERN_SUCCESS if the
  * desired address is already mapped, or if we successfully grow
  * the stack.  Also returns KERN_SUCCESS if addr is outside the
@@ -3312,7 +3320,7 @@ Retry:
 	 * This also effectively destroys any guard page the user might have
 	 * intended by limiting the stack size.
 	 */
-	if (grow_amount > max_grow) {
+	if (grow_amount + (stack_guard_page ? PAGE_SIZE : 0) > max_grow) {
 		if (vm_map_lock_upgrade(map))
 			goto Retry;
 
@@ -3365,6 +3373,8 @@ Retry:
 		if (addr < end) {
 			stack_entry->avail_ssize = max_grow;
 			addr = end;
+			if (stack_guard_page)
+				addr += PAGE_SIZE;
 		}
 
 		rv = vm_map_insert(map, NULL, 0, addr, stack_entry->start,
@@ -3397,6 +3407,8 @@ Retry:
 		if (addr > end) {
 			stack_entry->avail_ssize = end - stack_entry->end;
 			addr = end;
+			if (stack_guard_page)
+				addr -= PAGE_SIZE;
 		}
 
 		grow_amount = addr - stack_entry->end;


More information about the svn-src-head mailing list