diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2018-04-12 17:13:45 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2018-04-12 17:13:45 +0000 |
commit | 9e91f96d779c665c5377cfd5667ee7e276f4c6eb (patch) | |
tree | fe187bb093929803715228a98ffc99028915fbad /sys/kern | |
parent | 0f04bf0af32f3ceff2d723822807131626fbff5d (diff) |
Implement MAP_STACK option for mmap(). Synchronous faults (pagefault and
syscall) confirm the stack register points at MAP_STACK memory, otherwise
SIGSEGV is delivered. sigaltstack() and pthread_attr_setstack() are modified
to create a MAP_STACK sub-region which satisfies alignment requirements.
Observe that MAP_STACK can only be set/cleared by mmap(), which zeroes the
contents of the region -- there is no mprotect() equivalent operation, so
there is no MAP_STACK-adding gadget.
This opportunistic software-emulation of a stack protection bit makes
stack-pivot operations during ROPchain fragile (kind of like removing a
tool from the toolbox).
original discussion with tedu, uvm work by stefan, testing by mortimer
ok kettenis
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/exec_subr.c | 19 | ||||
-rw-r--r-- | sys/kern/init_main.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 7 |
3 files changed, 19 insertions, 11 deletions
diff --git a/sys/kern/exec_subr.c b/sys/kern/exec_subr.c index c1924edbaab..f2282a4a357 100644 --- a/sys/kern/exec_subr.c +++ b/sys/kern/exec_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: exec_subr.c,v 1.54 2018/02/10 02:54:33 mortimer Exp $ */ +/* $OpenBSD: exec_subr.c,v 1.55 2018/04/12 17:13:44 deraadt Exp $ */ /* $NetBSD: exec_subr.c,v 1.9 1994/12/04 03:10:42 mycroft Exp $ */ /* @@ -276,7 +276,8 @@ vmcmd_map_zero(struct proc *p, struct exec_vmcmd *cmd) return (uvm_map(&p->p_vmspace->vm_map, &cmd->ev_addr, round_page(cmd->ev_len), NULL, UVM_UNKNOWN_OFFSET, 0, UVM_MAPFLAG(cmd->ev_prot, PROT_MASK, MAP_INHERIT_COPY, - MADV_NORMAL, UVM_FLAG_FIXED|UVM_FLAG_COPYONW))); + MADV_NORMAL, UVM_FLAG_FIXED|UVM_FLAG_COPYONW | + (cmd->ev_flags & VMCMD_STACK ? UVM_FLAG_STACK : 0)))); } /* @@ -379,17 +380,19 @@ exec_setup_stack(struct proc *p, struct exec_package *epp) #ifdef MACHINE_STACK_GROWS_UP NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, ((epp->ep_minsaddr - epp->ep_ssize) - epp->ep_maxsaddr), - epp->ep_maxsaddr + epp->ep_ssize, NULLVP, 0, PROT_NONE); - NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, epp->ep_ssize, + epp->ep_maxsaddr + epp->ep_ssize, NULLVP, 0, + PROT_NONE); + NEW_VMCMD2(&epp->ep_vmcmds, vmcmd_map_zero, epp->ep_ssize, epp->ep_maxsaddr, NULLVP, 0, - PROT_READ | PROT_WRITE); + PROT_READ | PROT_WRITE, VMCMD_STACK); #else NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, ((epp->ep_minsaddr - epp->ep_ssize) - epp->ep_maxsaddr), - epp->ep_maxsaddr, NULLVP, 0, PROT_NONE); - NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, epp->ep_ssize, + epp->ep_maxsaddr, NULLVP, 0, + PROT_NONE); + NEW_VMCMD2(&epp->ep_vmcmds, vmcmd_map_zero, epp->ep_ssize, (epp->ep_minsaddr - epp->ep_ssize), NULLVP, 0, - PROT_READ | PROT_WRITE); + PROT_READ | PROT_WRITE, VMCMD_STACK); #endif return (0); diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 17bff8830fb..87604c5b501 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init_main.c,v 1.275 2018/03/20 15:45:32 mpi Exp $ */ +/* $OpenBSD: init_main.c,v 1.276 2018/04/12 17:13:44 deraadt Exp $ */ /* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */ /* @@ -652,7 +652,7 @@ start_init(void *arg) if (uvm_map(&p->p_vmspace->vm_map, &addr, PAGE_SIZE, NULL, UVM_UNKNOWN_OFFSET, 0, UVM_MAPFLAG(PROT_READ | PROT_WRITE, PROT_MASK, MAP_INHERIT_COPY, - MADV_NORMAL, UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW))) + MADV_NORMAL, UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW|UVM_FLAG_STACK))) panic("init: couldn't allocate argument space"); for (pathp = &initpaths[0]; (path = *pathp) != NULL; pathp++) { diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index c6ed90cc214..cb448f48280 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.218 2018/03/27 08:22:41 mpi Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.219 2018/04/12 17:13:44 deraadt Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -554,6 +554,11 @@ sys_sigaltstack(struct proc *p, void *v, register_t *retval) } if (ss.ss_size < MINSIGSTKSZ) return (ENOMEM); + + error = uvm_map_remap_as_stack(p, (vaddr_t)ss.ss_sp, ss.ss_size); + if (error) + return (error); + p->p_sigstk = ss; return (0); } |