From dfa9d6788792af78bc6b4b0c3f72ae0304fb2fa6 Mon Sep 17 00:00:00 2001 From: deraadt Date: Fri, 23 Oct 2015 01:10:01 +0000 Subject: [PATCH] Add 3 new pledge requests. "ps" exposes enough sysctl information for ps-style programs (there are quite a few in the tree, including tmux). "vminfo" exposes a bit more system operation information, which many observation programs want (such as top). settime allows setting the system time, and will be used to pledge-protect the last ntpd process. --- lib/libc/sys/pledge.2 | 26 +++++++++++++-- sys/kern/kern_pledge.c | 75 ++++++++++++++++++++++++++++++++++++++++-- sys/sys/pledge.h | 6 +++- sys/uvm/uvm_swap.c | 5 +-- 4 files changed, 105 insertions(+), 7 deletions(-) diff --git a/lib/libc/sys/pledge.2 b/lib/libc/sys/pledge.2 index b41e034884a..90505f6020e 100644 --- a/lib/libc/sys/pledge.2 +++ b/lib/libc/sys/pledge.2 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pledge.2,v 1.8 2015/10/22 09:23:41 deraadt Exp $ +.\" $OpenBSD: pledge.2,v 1.9 2015/10/23 01:10:01 deraadt Exp $ .\" .\" Copyright (c) 2015 Nicholas Marriott .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: October 22 2015 $ +.Dd $Mdocdate: October 23 2015 $ .Dt PLEDGE 2 .Os .Sh NAME @@ -455,6 +455,28 @@ with .Xr mmap 2 and .Xr mprotect 2 . +.It Va "settime" +Allows the setting of system time, via the +.Xr settimeofday 2 , +.Xr adjtime 2 , +and +.Xr adjfreq 2 +system calls. +.It Va "ps" +Allows enough +.Xr sysctl 2 +interfaces to allow inspection of processes operating on the system using +programs like +.Xr ps 1 . +Allows the following system calls: +.It Va "vminfo" +Allows enough +.Xr sysctl 2 +interfaces to allow inspection of the system's virtual memory by +programs like +.Xr top 1 , +and +.Xr vmstat 8 . .It Va "id" Allows the following system calls: .Pp diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c index 51384557ec0..a5ed8cc26cc 100644 --- a/sys/kern/kern_pledge.c +++ b/sys/kern/kern_pledge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_pledge.c,v 1.65 2015/10/23 00:56:52 deraadt Exp $ */ +/* $OpenBSD: kern_pledge.c,v 1.66 2015/10/23 01:10:01 deraadt Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -86,7 +86,6 @@ const u_int pledge_syscalls[SYS_MAXSYSCALL] = { [SYS_getpid] = PLEDGE_SELF, [SYS_umask] = PLEDGE_SELF, [SYS_sysctl] = PLEDGE_SELF, /* read-only; narrow subset */ - [SYS_adjtime] = PLEDGE_SELF, /* read-only */ [SYS_setsockopt] = PLEDGE_SELF, /* white list */ [SYS_getsockopt] = PLEDGE_SELF, @@ -116,6 +115,10 @@ const u_int pledge_syscalls[SYS_MAXSYSCALL] = { [SYS_wait4] = PLEDGE_SELF, + [SYS_adjtime] = PLEDGE_SELF, /* read-only, unless "settime" */ + [SYS_adjfreq] = PLEDGE_SETTIME, + [SYS_settimeofday] = PLEDGE_SETTIME, + [SYS_poll] = PLEDGE_RW, [SYS_kevent] = PLEDGE_RW, [SYS_kqueue] = PLEDGE_RW, @@ -191,6 +194,7 @@ const u_int pledge_syscalls[SYS_MAXSYSCALL] = { [SYS_readlink] = PLEDGE_SELF, /* further checks in namei */ [SYS_chdir] = PLEDGE_RPATH, + [SYS_chroot] = PLEDGE_ID, [SYS_openat] = PLEDGE_RPATH | PLEDGE_WPATH, [SYS_fstatat] = PLEDGE_RPATH | PLEDGE_WPATH, [SYS_faccessat] = PLEDGE_RPATH | PLEDGE_WPATH, @@ -248,6 +252,8 @@ const u_int pledge_syscalls[SYS_MAXSYSCALL] = { [SYS_getpeername] = PLEDGE_INET | PLEDGE_UNIX, [SYS_flock] = PLEDGE_FLOCK | PLEDGE_YP_ACTIVE, + + [SYS_swapctl] = PLEDGE_VMINFO, /* XXX should limit to "get" operations */ }; static const struct { @@ -278,6 +284,9 @@ static const struct { { "fattr", PLEDGE_FATTR }, { "prot_exec", PLEDGE_PROTEXEC }, { "flock", PLEDGE_FLOCK }, + { "ps", PLEDGE_PS }, + { "vminfo", PLEDGE_VMINFO }, + { "settime", PLEDGE_SETTIME }, }; int @@ -644,6 +653,11 @@ pledge_namei(struct proc *p, char *origpath) strcmp(path, "/etc/resolv.conf") == 0) return (0); break; + case SYS_chroot: + /* Allowed for "proc id" */ + if ((p->p_p->ps_pledge & PLEDGE_PROC)) + return (0); + break; } /* ensure PLEDGE_RPATH request for doing read */ @@ -857,6 +871,53 @@ pledge_sysctl_check(struct proc *p, int miblen, int *mib, void *new) return (0); } + if (p->p_p->ps_pledge & (PLEDGE_PS | PLEDGE_VMINFO)) { + if (miblen == 2 && /* kern.fscale */ + mib[0] == CTL_KERN && mib[1] == KERN_FSCALE) + return (0); + if (miblen == 2 && /* kern.boottime */ + mib[0] == CTL_KERN && mib[1] == KERN_BOOTTIME) + return (0); + if (miblen == 2 && /* kern.consdev */ + mib[0] == CTL_KERN && mib[1] == KERN_CONSDEV) + return (0); + if (miblen == 2 && /* kern.loadavg */ + mib[0] == CTL_VM && mib[1] == VM_LOADAVG) + return (0); + if (miblen == 3 && /* kern.cptime2 */ + mib[0] == CTL_KERN && mib[1] == KERN_CPTIME2) + return (0); + } + + if ((p->p_p->ps_pledge & PLEDGE_PS)) { + if (miblen == 4 && /* kern.procargs.* */ + mib[0] == CTL_KERN && mib[1] == KERN_PROC_ARGS && + (mib[3] == KERN_PROC_ARGV || mib[3] == KERN_PROC_ENV)) + return (0); + if (miblen == 6 && /* kern.proc.* */ + mib[0] == CTL_KERN && mib[1] == KERN_PROC) + return (0); + if (miblen == 2 && /* hw.physmem */ + mib[0] == CTL_HW && mib[1] == HW_PHYSMEM64) + return (0); + if (miblen == 2 && /* kern.ccpu */ + mib[0] == CTL_KERN && mib[1] == KERN_CCPU) + return (0); + if (miblen == 2 && /* vm.maxslp */ + mib[0] == CTL_VM && mib[1] == VM_MAXSLP) + return (0); + } + + if ((p->p_p->ps_pledge & PLEDGE_VMINFO)) { + if (miblen == 2 && /* vm.uvmexp */ + mib[0] == CTL_VM && mib[1] == VM_UVMEXP) + return (0); + if (miblen == 3 && /* vfs.generic.bcachestat */ + mib[0] == CTL_VFS && mib[1] == VFS_GENERIC && + mib[2] == VFS_BCACHESTAT) + return (0); + } + if ((p->p_p->ps_pledge & (PLEDGE_ROUTE | PLEDGE_INET))) { if (miblen == 6 && /* getifaddrs() */ mib[0] == CTL_NET && mib[1] == PF_ROUTE && @@ -932,6 +993,8 @@ pledge_adjtime_check(struct proc *p, const void *v) if ((p->p_p->ps_flags & PS_PLEDGE) == 0) return (0); + if ((p->p_p->ps_pledge & PLEDGE_SETTIME)) + return (0); if (delta) return (EFAULT); return (0); @@ -1191,6 +1254,14 @@ pledge_flock_check(struct proc *p) return (pledge_fail(p, EPERM, PLEDGE_FLOCK)); } +int +pledge_swapctl_check(struct proc *p) +{ + if ((p->p_p->ps_flags & PS_PLEDGE) == 0) + return (0); + return (EPERM); +} + void pledge_dropwpaths(struct process *pr) { diff --git a/sys/sys/pledge.h b/sys/sys/pledge.h index a241305980a..a781041fb79 100644 --- a/sys/sys/pledge.h +++ b/sys/sys/pledge.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pledge.h,v 1.9 2015/10/20 18:04:03 deraadt Exp $ */ +/* $OpenBSD: pledge.h,v 1.10 2015/10/23 01:10:01 deraadt Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -47,6 +47,9 @@ #define PLEDGE_ROUTE 0x00100000 /* routing lookups */ #define PLEDGE_MCAST 0x00200000 /* multicast joins */ #define PLEDGE_FLOCK 0x00400000 /* file locking */ +#define PLEDGE_PS 0x00800000 /* ps listings */ +#define PLEDGE_VMINFO 0x01000000 /* vminfo listings */ +#define PLEDGE_SETTIME 0x02000000 /* able to set/adj time/freq */ #define PLEDGE_ABORT 0x08000000 /* SIGABRT instead of SIGKILL */ @@ -72,6 +75,7 @@ int pledge_sockopt_check(struct proc *p, int level, int optname); int pledge_socket_check(struct proc *p, int dns); int pledge_ioctl_check(struct proc *p, long com, void *); int pledge_flock_check(struct proc *p); +int pledge_swapctl_check(struct proc *p); #define PLEDGE_MAXPATHS 8192 diff --git a/sys/uvm/uvm_swap.c b/sys/uvm/uvm_swap.c index ba8f10a7f8b..f7fa31d28dd 100644 --- a/sys/uvm/uvm_swap.c +++ b/sys/uvm/uvm_swap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_swap.c,v 1.137 2015/09/06 17:06:43 deraadt Exp $ */ +/* $OpenBSD: uvm_swap.c,v 1.138 2015/10/23 01:10:01 deraadt Exp $ */ /* $NetBSD: uvm_swap.c,v 1.40 2000/11/17 11:39:39 mrg Exp $ */ /* @@ -51,6 +51,7 @@ #include #include #include +#include #if defined(NFSCLIENT) #include #include @@ -669,7 +670,7 @@ sys_swapctl(struct proc *p, void *v, register_t *retval) } /* all other requests require superuser privs. verify. */ - if ((error = suser(p, 0))) + if ((error = suser(p, 0)) || pledge_swapctl_check(p)) goto out; /* -- 2.20.1