diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2016-05-30 21:31:31 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2016-05-30 21:31:31 +0000 |
commit | 19cbe43a59839a6617d12978da003ac9863407f3 (patch) | |
tree | 27d26f790d5dbb1249d48369e6294d0a27c44837 /sys/uvm | |
parent | 31a77d86aebee5bb9ee927869a2f82b112b8978b (diff) |
Identify W^X labelled binaries at execve() time based upon WX_OPENBSD_WXNEEDED
flag set by ld -zwxneeded. Such binaries are allowed to run only on wxallowed
mountpoints. They do not report mmap/mprotect problems.
Rate limit mmap/mprotect reports from other binaries.
These semantics are chosen to encourage progress in the ports ecosystem,
without overwhelming the developers who work in the area.
ok sthen kettenis
Diffstat (limited to 'sys/uvm')
-rw-r--r-- | sys/uvm/uvm_mmap.c | 36 |
1 files changed, 19 insertions, 17 deletions
diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c index 9aa0d2d08ca..171eaa2f228 100644 --- a/sys/uvm/uvm_mmap.c +++ b/sys/uvm/uvm_mmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_mmap.c,v 1.128 2016/05/30 21:25:48 deraadt Exp $ */ +/* $OpenBSD: uvm_mmap.c,v 1.129 2016/05/30 21:31:30 deraadt Exp $ */ /* $NetBSD: uvm_mmap.c,v 1.49 2001/02/18 21:19:08 chs Exp $ */ /* @@ -312,30 +312,32 @@ int uvm_wxabort; * W^X violations are only allowed on permitted filesystems. */ static inline int -uvm_wxcheck(struct proc *p) +uvm_wxcheck(struct proc *p, char *call) { #if (defined(__mips64__) || defined(__hppa)) /* XXX got/plt repairs still needed */ return 0; #endif - int mpwx = (p->p_p->ps_textvp->v_mount && + int wxallowed = (p->p_p->ps_textvp->v_mount && (p->p_p->ps_textvp->v_mount->mnt_flag & MNT_WXALLOWED)); - if (!mpwx) { + if (wxallowed && (p->p_p->ps_flags & PS_WXNEEDED)) + return (0); + + /* Report W^X failures, and potentially SIGABRT */ + if (p->p_p->ps_wxcounter++ == 0) + log(LOG_NOTICE, "%s(%d): %s W^X violation\n", + p->p_comm, p->p_pid, call); + if (uvm_wxabort) { struct sigaction sa; - log(LOG_NOTICE, "%s(%d): mmap W^X violation\n", - p->p_comm, p->p_pid); - if (uvm_wxabort) { - /* Send uncatchable SIGABRT for coredump */ - memset(&sa, 0, sizeof sa); - sa.sa_handler = SIG_DFL; - setsigvec(p, SIGABRT, &sa); - psignal(p, SIGABRT); - } - return (ENOTSUP); + /* Send uncatchable SIGABRT for coredump */ + memset(&sa, 0, sizeof sa); + sa.sa_handler = SIG_DFL; + setsigvec(p, SIGABRT, &sa); + psignal(p, SIGABRT); } - return (0); + return (0); /* ENOTSUP later */ } /* @@ -385,7 +387,7 @@ sys_mmap(struct proc *p, void *v, register_t *retval) if ((prot & PROT_MASK) != prot) return (EINVAL); if ((prot & (PROT_WRITE | PROT_EXEC)) == (PROT_WRITE | PROT_EXEC) && - (error = uvm_wxcheck(p))) + (error = uvm_wxcheck(p, "mmap"))) return (error); if ((flags & MAP_FLAGMASK) != flags) @@ -702,7 +704,7 @@ sys_mprotect(struct proc *p, void *v, register_t *retval) if ((prot & PROT_MASK) != prot) return (EINVAL); if ((prot & (PROT_WRITE | PROT_EXEC)) == (PROT_WRITE | PROT_EXEC) && - (error = uvm_wxcheck(p))) + (error = uvm_wxcheck(p, "mprotect"))) return (error); error = pledge_protexec(p, prot); |