summaryrefslogtreecommitdiff
path: root/sys/uvm
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2019-02-15 16:47:00 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2019-02-15 16:47:00 +0000
commitdcca27ace36d0de4368860c1435c5662ae7c5b4f (patch)
tree6602bac5890cb5b5b63f27da770d7602946ae751 /sys/uvm
parent8161f8c874744488c51097dd7d7bd73380437e54 (diff)
With an opportunistic check performed at every trap, we insist userland
sp must be on a MAP_STACK page. Relax the check a bit -- the sp may be on a PROT_NONE page. Can't see how an attacker can leverage that situation. (New perl build process contains a "how many call frames can my stack hold" checker, and this triggers via the MAP_STACK fault rather than the normal access check. The MAP_STACK check still has a kernel printf as we hunt for applications which map stacks poorly. Interestingly the perl code has a knob to disable similar printing alerts on Windows, which apparently has a feature somewhat like MAP_STACK!) ok tedu guenther kettenis
Diffstat (limited to 'sys/uvm')
-rw-r--r--sys/uvm/uvm_map.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/sys/uvm/uvm_map.c b/sys/uvm/uvm_map.c
index 311b556c9d6..fcb6e16b43f 100644
--- a/sys/uvm/uvm_map.c
+++ b/sys/uvm/uvm_map.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_map.c,v 1.240 2019/02/10 16:42:35 phessler Exp $ */
+/* $OpenBSD: uvm_map.c,v 1.241 2019/02/15 16:46:59 deraadt Exp $ */
/* $NetBSD: uvm_map.c,v 1.86 2000/11/27 08:40:03 chs Exp $ */
/*
@@ -1768,7 +1768,7 @@ uvm_map_lookup_entry(struct vm_map *map, vaddr_t address,
* Inside a vm_map find the sp address and verify MAP_STACK, and also
* remember low and high regions of that of region which is marked
* with MAP_STACK. Return TRUE.
- * If sp isn't in a MAP_STACK region return FALSE.
+ * If sp isn't in a non-guard MAP_STACK region return FALSE.
*/
boolean_t
uvm_map_check_stack_range(struct proc *p, vaddr_t sp)
@@ -1789,7 +1789,11 @@ uvm_map_check_stack_range(struct proc *p, vaddr_t sp)
}
if ((entry->etype & UVM_ET_STACK) == 0) {
+ int protection = entry->protection;
+
vm_map_unlock_read(map);
+ if (protection == PROT_NONE)
+ return (TRUE); /* don't update range */
return (FALSE);
}
p->p_spstart = entry->start;