diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2019-02-15 16:47:00 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2019-02-15 16:47:00 +0000 |
commit | dcca27ace36d0de4368860c1435c5662ae7c5b4f (patch) | |
tree | 6602bac5890cb5b5b63f27da770d7602946ae751 /sys/uvm | |
parent | 8161f8c874744488c51097dd7d7bd73380437e54 (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.c | 8 |
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; |