-/* $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>
[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,
[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,
[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,
[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 {
{ "fattr", PLEDGE_FATTR },
{ "prot_exec", PLEDGE_PROTEXEC },
{ "flock", PLEDGE_FLOCK },
+ { "ps", PLEDGE_PS },
+ { "vminfo", PLEDGE_VMINFO },
+ { "settime", PLEDGE_SETTIME },
};
int
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 */
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 &&
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);
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)
{
-/* $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>
#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 */
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