summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libc/sys/mmap.214
-rw-r--r--lib/libc/sys/mount.215
-rw-r--r--lib/libc/sys/mprotect.214
-rw-r--r--sbin/mount/mntopts.h3
-rw-r--r--sbin/mount/mount.815
-rw-r--r--sbin/mount/mount.c3
-rw-r--r--sbin/mount_ffs/mount_ffs.c3
-rw-r--r--sbin/mount_nfs/mount_nfs.c3
-rw-r--r--sys/kern/kern_sysctl.c5
-rw-r--r--sys/kern/vfs_syscalls.c6
-rw-r--r--sys/sys/mount.h3
-rw-r--r--sys/sys/sysctl.h6
-rw-r--r--sys/uvm/uvm_mmap.c42
-rw-r--r--usr.sbin/pstat/pstat.c7
14 files changed, 117 insertions, 22 deletions
diff --git a/lib/libc/sys/mmap.2 b/lib/libc/sys/mmap.2
index eef128dbe47..f1be136300c 100644
--- a/lib/libc/sys/mmap.2
+++ b/lib/libc/sys/mmap.2
@@ -1,4 +1,4 @@
-.\" $OpenBSD: mmap.2,v 1.51 2014/07/10 19:00:23 matthew Exp $
+.\" $OpenBSD: mmap.2,v 1.52 2016/05/27 19:45:04 deraadt Exp $
.\" $NetBSD: mmap.2,v 1.5 1995/06/24 10:48:59 cgd Exp $
.\"
.\" Copyright (c) 1991, 1993
@@ -30,7 +30,7 @@
.\"
.\" @(#)mmap.2 8.1 (Berkeley) 6/4/93
.\"
-.Dd $Mdocdate: July 10 2014 $
+.Dd $Mdocdate: May 27 2016 $
.Dt MMAP 2
.Os
.Sh NAME
@@ -273,6 +273,16 @@ was specified and the
parameter wasn't available.
.Dv MAP_ANON
was specified and insufficient memory was available.
+.It Bq Er ENOTSUP
+The accesses requested in the
+.Ar prot
+argument are not allowed.
+In particular,
+.Dv PROT_WRITE | PROT_EXEC
+mappings are not permitted in most binaries (see
+.Dv kern.wxabort
+in sysctl 3
+for more information).
.El
.Sh SEE ALSO
.Xr madvise 2 ,
diff --git a/lib/libc/sys/mount.2 b/lib/libc/sys/mount.2
index b2a126a01db..b295b824989 100644
--- a/lib/libc/sys/mount.2
+++ b/lib/libc/sys/mount.2
@@ -1,4 +1,4 @@
-.\" $OpenBSD: mount.2,v 1.45 2015/11/23 10:01:45 jmc Exp $
+.\" $OpenBSD: mount.2,v 1.46 2016/05/27 19:45:04 deraadt Exp $
.\" $NetBSD: mount.2,v 1.12 1996/02/29 23:47:48 jtc Exp $
.\"
.\" Copyright (c) 1980, 1989, 1993
@@ -30,7 +30,7 @@
.\"
.\" @(#)mount.2 8.2 (Berkeley) 12/11/93
.\"
-.Dd $Mdocdate: November 23 2015 $
+.Dd $Mdocdate: May 27 2016 $
.Dt MOUNT 2
.Os
.Sh NAME
@@ -95,6 +95,17 @@ All I/O to the filesystem should be done asynchronously.
Use soft dependencies.
Applies to FFS filesystems only (see 'softdep' in
.Xr mount 8 ) .
+.It MNT_WXALLOWED
+Processes that ask for memory to be made writeable plus executable
+using the
+.Xr mmap 2
+and
+.Xr mprotect 2
+system calls are killed by default.
+This option allows those processes to continue operation.
+The option is typically used on the
+.Pa /usr/local
+filesystem.
.El
.Pp
The flag
diff --git a/lib/libc/sys/mprotect.2 b/lib/libc/sys/mprotect.2
index 48720ef3764..c26b628075b 100644
--- a/lib/libc/sys/mprotect.2
+++ b/lib/libc/sys/mprotect.2
@@ -1,4 +1,4 @@
-.\" $OpenBSD: mprotect.2,v 1.19 2014/07/02 22:22:35 matthew Exp $
+.\" $OpenBSD: mprotect.2,v 1.20 2016/05/27 19:45:04 deraadt Exp $
.\" $NetBSD: mprotect.2,v 1.6 1995/10/12 15:41:08 jtc Exp $
.\"
.\" Copyright (c) 1991, 1993
@@ -30,7 +30,7 @@
.\"
.\" @(#)mprotect.2 8.1 (Berkeley) 6/9/93
.\"
-.Dd $Mdocdate: July 2 2014 $
+.Dd $Mdocdate: May 27 2016 $
.Dt MPROTECT 2
.Os
.Sh NAME
@@ -96,6 +96,16 @@ The process has locked future pages with
.Fn mlockall MCL_FUTURE ,
a page being protected is not currently accessible,
and making it accessible and locked would exceed process or system limits.
+.It Bq Er ENOTSUP
+The accesses requested in the
+.Ar prot
+argument are not allowed.
+In particular,
+.Dv PROT_WRITE | PROT_EXEC
+mappings are not permitted in most binaries (see
+.Dv kern.wxabort
+in sysctl 3
+for more information).
.It Bq Er EINVAL
The
.Fa prot
diff --git a/sbin/mount/mntopts.h b/sbin/mount/mntopts.h
index da0ea3f6f10..6c51ed72155 100644
--- a/sbin/mount/mntopts.h
+++ b/sbin/mount/mntopts.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mntopts.h,v 1.16 2014/07/13 12:01:30 claudio Exp $ */
+/* $OpenBSD: mntopts.h,v 1.17 2016/05/27 19:45:04 deraadt Exp $ */
/* $NetBSD: mntopts.h,v 1.3 1995/03/18 14:56:59 cgd Exp $ */
/*-
@@ -58,6 +58,7 @@ union mntval {
#define MOPT_NODEV { "dev", MNT_NODEV, MFLAG_INVERSE | MFLAG_SET }
#define MOPT_NOEXEC { "exec", MNT_NOEXEC, MFLAG_INVERSE | MFLAG_SET }
#define MOPT_NOSUID { "suid", MNT_NOSUID, MFLAG_INVERSE | MFLAG_SET }
+#define MOPT_WXALLOWED { "wxallowed", MNT_WXALLOWED, MFLAG_SET }
#define MOPT_RDONLY { "rdonly", MNT_RDONLY, MFLAG_SET }
#define MOPT_SYNC { "sync", MNT_SYNCHRONOUS, MFLAG_SET }
#define MOPT_USERQUOTA { "userquota", 0, MFLAG_SET | MFLAG_STRVAL \
diff --git a/sbin/mount/mount.8 b/sbin/mount/mount.8
index 3a2e9e63fce..2a0ccb7d0e3 100644
--- a/sbin/mount/mount.8
+++ b/sbin/mount/mount.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: mount.8,v 1.77 2014/09/08 04:40:30 doug Exp $
+.\" $OpenBSD: mount.8,v 1.78 2016/05/27 19:45:04 deraadt Exp $
.\" $NetBSD: mount.8,v 1.11 1995/07/12 06:23:21 cgd Exp $
.\"
.\" Copyright (c) 1980, 1989, 1991, 1993
@@ -30,7 +30,7 @@
.\"
.\" @(#)mount.8 8.7 (Berkeley) 3/27/94
.\"
-.Dd $Mdocdate: September 8 2014 $
+.Dd $Mdocdate: May 27 2016 $
.Dt MOUNT 8
.Os
.Sh NAME
@@ -234,6 +234,17 @@ are mutually exclusive.
.It sync
Regular data I/O to the file system should be done synchronously.
By default, only metadata is read/written synchronously.
+.It wxallowed
+Processes that ask for memory to be made writeable plus executable
+using the
+.Xr mmap 2
+and
+.Xr mprotect 2
+system calls are killed by default.
+This option allows those processes to continue operation.
+The option is typically used on the
+.Pa /usr/local
+filesystem.
.It update
The same as
.Fl u ;
diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c
index 01463a3855f..4758d441a7a 100644
--- a/sbin/mount/mount.c
+++ b/sbin/mount/mount.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mount.c,v 1.63 2016/05/25 13:56:37 deraadt Exp $ */
+/* $OpenBSD: mount.c,v 1.64 2016/05/27 19:45:04 deraadt Exp $ */
/* $NetBSD: mount.c,v 1.24 1995/11/18 03:34:29 cgd Exp $ */
/*
@@ -88,6 +88,7 @@ static struct opt {
{ MNT_NODEV, 0, "nodev", "nodev" },
{ MNT_NOEXEC, 0, "noexec", "noexec" },
{ MNT_NOSUID, 0, "nosuid", "nosuid" },
+ { MNT_WXALLOWED, 0, "wxallowed", "wxallowed" },
{ MNT_QUOTA, 0, "with quotas", "" },
{ MNT_RDONLY, 0, "read-only", "ro" },
{ MNT_ROOTFS, 1, "root file system", "" },
diff --git a/sbin/mount_ffs/mount_ffs.c b/sbin/mount_ffs/mount_ffs.c
index f2c5ee2568a..98b8ad795cc 100644
--- a/sbin/mount_ffs/mount_ffs.c
+++ b/sbin/mount_ffs/mount_ffs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mount_ffs.c,v 1.22 2015/12/08 15:56:42 tedu Exp $ */
+/* $OpenBSD: mount_ffs.c,v 1.23 2016/05/27 19:45:04 deraadt Exp $ */
/* $NetBSD: mount_ffs.c,v 1.3 1996/04/13 01:31:19 jtc Exp $ */
/*-
@@ -47,6 +47,7 @@ void ffs_usage(void);
static const struct mntopt mopts[] = {
MOPT_STDOPTS,
+ MOPT_WXALLOWED,
MOPT_ASYNC,
MOPT_SYNC,
MOPT_UPDATE,
diff --git a/sbin/mount_nfs/mount_nfs.c b/sbin/mount_nfs/mount_nfs.c
index 8d3094a8fa9..21b4cc54e77 100644
--- a/sbin/mount_nfs/mount_nfs.c
+++ b/sbin/mount_nfs/mount_nfs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mount_nfs.c,v 1.52 2015/01/16 06:39:59 deraadt Exp $ */
+/* $OpenBSD: mount_nfs.c,v 1.53 2016/05/27 19:45:04 deraadt Exp $ */
/* $NetBSD: mount_nfs.c,v 1.12.4.1 1996/05/25 22:48:05 fvdl Exp $ */
/*
@@ -85,6 +85,7 @@
const struct mntopt mopts[] = {
MOPT_STDOPTS,
+ MOPT_WXALLOWED,
MOPT_FORCE,
MOPT_UPDATE,
MOPT_SYNC,
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index b3c854376fe..24c783637e2 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.304 2016/05/23 15:59:19 deraadt Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.305 2016/05/27 19:45:04 deraadt Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -278,6 +278,7 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
extern int usermount, nosuidcoredump;
extern int maxlocksperuid;
extern int pool_debug;
+ extern int uvm_wxabort;
/* all sysctl names at this level are terminal except a ton of them */
if (namelen != 1) {
@@ -590,6 +591,8 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
}
return(0);
}
+ case KERN_WXABORT:
+ return (sysctl_int(oldp, oldlenp, newp, newlen, &uvm_wxabort));
case KERN_CONSDEV:
if (cn_tab != NULL)
dev = cn_tab->cn_dev;
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 7a0aa126a59..6798f32f8a5 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_syscalls.c,v 1.254 2016/05/15 05:04:28 semarie Exp $ */
+/* $OpenBSD: vfs_syscalls.c,v 1.255 2016/05/27 19:45:04 deraadt Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
/*
@@ -252,10 +252,10 @@ update:
mp->mnt_flag |= MNT_RDONLY;
else if (mp->mnt_flag & MNT_RDONLY)
mp->mnt_flag |= MNT_WANTRDWR;
- mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
+ mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_WXALLOWED | MNT_NODEV |
MNT_SYNCHRONOUS | MNT_ASYNC | MNT_SOFTDEP | MNT_NOATIME |
MNT_FORCE);
- mp->mnt_flag |= flags & (MNT_NOSUID | MNT_NOEXEC |
+ mp->mnt_flag |= flags & (MNT_NOSUID | MNT_NOEXEC | MNT_WXALLOWED |
MNT_NODEV | MNT_SYNCHRONOUS | MNT_ASYNC | MNT_SOFTDEP |
MNT_NOATIME | MNT_FORCE);
/*
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 7e55c0e8162..2ab1cc7821a 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mount.h,v 1.125 2016/05/25 13:31:44 deraadt Exp $ */
+/* $OpenBSD: mount.h,v 1.126 2016/05/27 19:45:04 deraadt Exp $ */
/* $NetBSD: mount.h,v 1.48 1996/02/18 11:55:47 fvdl Exp $ */
/*
@@ -369,6 +369,7 @@ struct mount {
#define MNT_NOSUID 0x00000008 /* don't honor setuid bits on fs */
#define MNT_NODEV 0x00000010 /* don't interpret special files */
#define MNT_ASYNC 0x00000040 /* file system written asynchronously */
+#define MNT_WXALLOWED 0x00000800 /* filesystem allows W|X mappings */
/*
* exported mount flags.
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index 9f01bc20c50..04ec9e8fcbd 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysctl.h,v 1.162 2016/05/23 15:48:57 deraadt Exp $ */
+/* $OpenBSD: sysctl.h,v 1.163 2016/05/27 19:45:04 deraadt Exp $ */
/* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */
/*
@@ -174,7 +174,7 @@ struct ctlname {
#define KERN_CPTIME2 71 /* array: cp_time2 */
#define KERN_CACHEPCT 72 /* buffer cache % of physmem */
#define KERN_FILE 73 /* struct: file entries */
-/* was KERN_RTHREADS 74 */
+#define KERN_WXABORT 74 /* int: w^x sigabrt & core */
#define KERN_CONSDEV 75 /* dev_t: console terminal device */
#define KERN_NETLIVELOCKS 76 /* int: number of network livelocks */
#define KERN_POOL_DEBUG 77 /* int: enable pool_debug */
@@ -261,7 +261,7 @@ struct ctlname {
{ "cp_time2", CTLTYPE_STRUCT }, \
{ "bufcachepercent", CTLTYPE_INT }, \
{ "file", CTLTYPE_STRUCT }, \
- { "gap", 0 }, \
+ { "wxabort", CTLTYPE_INT }, \
{ "consdev", CTLTYPE_STRUCT }, \
{ "netlivelocks", CTLTYPE_INT }, \
{ "pool_debug", CTLTYPE_INT }, \
diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c
index e5651310afc..0ac5a9ea325 100644
--- a/sys/uvm/uvm_mmap.c
+++ b/sys/uvm/uvm_mmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_mmap.c,v 1.125 2016/05/11 21:52:51 deraadt Exp $ */
+/* $OpenBSD: uvm_mmap.c,v 1.126 2016/05/27 19:45:04 deraadt Exp $ */
/* $NetBSD: uvm_mmap.c,v 1.49 2001/02/18 21:19:08 chs Exp $ */
/*
@@ -62,6 +62,7 @@
#include <sys/vnode.h>
#include <sys/conf.h>
#include <sys/signalvar.h>
+#include <sys/syslog.h>
#include <sys/stat.h>
#include <sys/specdev.h>
#include <sys/stdint.h>
@@ -305,6 +306,38 @@ sys_mincore(struct proc *p, void *v, register_t *retval)
return (error);
}
+int uvm_wxabort;
+
+/*
+ * W^X violations are only allowed on permitted filesystems.
+ */
+static inline int
+uvm_wxcheck(struct proc *p)
+{
+#if (defined(__mips64__) || defined(__hppa))
+ /* XXX got/plt repairs still needed */
+ return 0;
+#endif
+ int mpwx = (p->p_p->ps_textvp->v_mount &&
+ (p->p_p->ps_textvp->v_mount->mnt_flag & MNT_WXALLOWED));
+
+ if (!mpwx) {
+ 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);
+ }
+ return (0);
+}
+
/*
* sys_mmap: mmap system call.
*
@@ -351,6 +384,10 @@ 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)))
+ return (error);
+
if ((flags & MAP_FLAGMASK) != flags)
return (EINVAL);
if (flags & MAP_OLDCOPY)
@@ -664,6 +701,9 @@ 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)))
+ return (error);
error = pledge_protexec(p, prot);
if (error)
diff --git a/usr.sbin/pstat/pstat.c b/usr.sbin/pstat/pstat.c
index 28a65fc6032..38b8e9de386 100644
--- a/usr.sbin/pstat/pstat.c
+++ b/usr.sbin/pstat/pstat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pstat.c,v 1.104 2016/05/25 13:32:29 deraadt Exp $ */
+/* $OpenBSD: pstat.c,v 1.105 2016/05/27 19:45:04 deraadt Exp $ */
/* $NetBSD: pstat.c,v 1.27 1996/10/23 22:50:06 cgd Exp $ */
/*-
@@ -723,6 +723,11 @@ mount_print(struct mount *mp)
flags &= ~MNT_EXPORTANON;
comma = ",";
}
+ if (flags & MNT_WXALLOWED) {
+ (void)printf("%swxallowed", comma);
+ flags &= ~MNT_WXALLOWED;
+ comma = ",";
+ }
if (flags & MNT_LOCAL) {
(void)printf("%slocal", comma);
flags &= ~MNT_LOCAL;