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