summaryrefslogtreecommitdiff
path: root/sys/uvm
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2016-05-30 21:31:31 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2016-05-30 21:31:31 +0000
commit19cbe43a59839a6617d12978da003ac9863407f3 (patch)
tree27d26f790d5dbb1249d48369e6294d0a27c44837 /sys/uvm
parent31a77d86aebee5bb9ee927869a2f82b112b8978b (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.c36
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);