diff options
-rw-r--r-- | lib/libc/sys/mmap.2 | 14 | ||||
-rw-r--r-- | lib/libc/sys/mount.2 | 15 | ||||
-rw-r--r-- | lib/libc/sys/mprotect.2 | 14 | ||||
-rw-r--r-- | sbin/mount/mntopts.h | 3 | ||||
-rw-r--r-- | sbin/mount/mount.8 | 15 | ||||
-rw-r--r-- | sbin/mount/mount.c | 3 | ||||
-rw-r--r-- | sbin/mount_ffs/mount_ffs.c | 3 | ||||
-rw-r--r-- | sbin/mount_nfs/mount_nfs.c | 3 | ||||
-rw-r--r-- | sys/kern/kern_sysctl.c | 5 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 6 | ||||
-rw-r--r-- | sys/sys/mount.h | 3 | ||||
-rw-r--r-- | sys/sys/sysctl.h | 6 | ||||
-rw-r--r-- | sys/uvm/uvm_mmap.c | 42 | ||||
-rw-r--r-- | usr.sbin/pstat/pstat.c | 7 |
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; |