summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>2015-10-23 01:10:01 +0000
committerderaadt <deraadt@openbsd.org>2015-10-23 01:10:01 +0000
commitdfa9d6788792af78bc6b4b0c3f72ae0304fb2fa6 (patch)
tree611b5fbc10f6137d1080b856752adf6f9f62ad62
parentremove the pointer from hfsc_class structs back to hfsc_if. (diff)
downloadwireguard-openbsd-dfa9d6788792af78bc6b4b0c3f72ae0304fb2fa6.tar.xz
wireguard-openbsd-dfa9d6788792af78bc6b4b0c3f72ae0304fb2fa6.zip
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.
-rw-r--r--lib/libc/sys/pledge.226
-rw-r--r--sys/kern/kern_pledge.c75
-rw-r--r--sys/sys/pledge.h6
-rw-r--r--sys/uvm/uvm_swap.c5
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 <nicm@openbsd.org>
.\"
@@ -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 <nicm@openbsd.org>
@@ -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 <nicm@openbsd.org>
@@ -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 <sys/swap.h>
#include <sys/disk.h>
#include <sys/task.h>
+#include <sys/pledge.h>
#if defined(NFSCLIENT)
#include <sys/socket.h>
#include <sys/domain.h>
@@ -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;
/*