summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>2015-10-20 01:44:00 +0000
committerderaadt <deraadt@openbsd.org>2015-10-20 01:44:00 +0000
commit7ba9c3eba0ab719782f31ed4f9953cc9e5e68b24 (patch)
treec31136a61b7629767a1e179c1e7d9cde882b4e4f
parentRemove old tame() stub (diff)
downloadwireguard-openbsd-7ba9c3eba0ab719782f31ed4f9953cc9e5e68b24.tar.xz
wireguard-openbsd-7ba9c3eba0ab719782f31ed4f9953cc9e5e68b24.zip
Always allow the setsockopt & getsockopt system calls... however, in the
default case only allows SOL_SOCKET SO_RCVBUF which is very common in network-facing daemons. Many of them manage this on a socket after dropping abilities which can get them _new_ sockets.. syslogd, bgpd, relayd, etc etc. Other sockopts still require specific pledges. Tested by bluhm.
-rw-r--r--sys/kern/kern_pledge.c35
-rw-r--r--sys/kern/uipc_syscalls.c8
-rw-r--r--sys/sys/pledge.h4
3 files changed, 37 insertions, 10 deletions
diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c
index 7bff183f241..4c8dae3686a 100644
--- a/sys/kern/kern_pledge.c
+++ b/sys/kern/kern_pledge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_pledge.c,v 1.57 2015/10/19 16:20:56 deraadt Exp $ */
+/* $OpenBSD: kern_pledge.c,v 1.58 2015/10/20 01:44:00 deraadt Exp $ */
/*
* Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -87,6 +87,9 @@ const u_int pledge_syscalls[SYS_MAXSYSCALL] = {
[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_fchdir] = PLEDGE_SELF, /* careful of directory fd inside jails */
/* needed by threaded programs */
@@ -242,8 +245,6 @@ const u_int pledge_syscalls[SYS_MAXSYSCALL] = {
[SYS_accept] = PLEDGE_INET | PLEDGE_UNIX,
[SYS_getpeername] = PLEDGE_INET | PLEDGE_UNIX,
[SYS_getsockname] = PLEDGE_INET | PLEDGE_UNIX,
- [SYS_setsockopt] = PLEDGE_INET | PLEDGE_UNIX,
- [SYS_getsockopt] = PLEDGE_INET | PLEDGE_UNIX,
[SYS_flock] = PLEDGE_FLOCK | PLEDGE_YP_ACTIVE,
};
@@ -1057,12 +1058,35 @@ pledge_ioctl_check(struct proc *p, long com, void *v)
}
int
-pledge_setsockopt_check(struct proc *p, int level, int optname)
+pledge_sockopt_check(struct proc *p, int level, int optname)
{
if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
return (0);
- /* common case for PLEDGE_UNIX and PLEDGE_INET */
+ /* Always allow these, which are too common to reject */
+ switch (level) {
+ case SOL_SOCKET:
+ switch (optname) {
+ case SO_RCVBUF:
+ return 0;
+ }
+ break;
+ }
+
+ if ((p->p_p->ps_pledge & (PLEDGE_INET|PLEDGE_UNIX|PLEDGE_DNS)) == 0)
+ return (EPERM);
+ /* In use by some service libraries */
+ switch (level) {
+ case SOL_SOCKET:
+ switch (optname) {
+ case SO_TIMESTAMP:
+ return 0;
+ }
+ break;
+ }
+
+ if ((p->p_p->ps_pledge & (PLEDGE_INET|PLEDGE_UNIX)) == 0)
+ return (EPERM);
switch (level) {
case SOL_SOCKET:
switch (optname) {
@@ -1074,7 +1098,6 @@ pledge_setsockopt_check(struct proc *p, int level, int optname)
if ((p->p_p->ps_pledge & PLEDGE_INET) == 0)
return (EPERM);
-
switch (level) {
case IPPROTO_TCP:
switch (optname) {
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index b80c055e243..c95a77afea6 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_syscalls.c,v 1.115 2015/10/18 20:15:10 deraadt Exp $ */
+/* $OpenBSD: uipc_syscalls.c,v 1.116 2015/10/20 01:44:00 deraadt Exp $ */
/* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */
/*
@@ -930,7 +930,7 @@ sys_setsockopt(struct proc *p, void *v, register_t *retval)
error = EINVAL;
goto bad;
}
- if (pledge_setsockopt_check(p, SCARG(uap, level), SCARG(uap, name))) {
+ if (pledge_sockopt_check(p, SCARG(uap, level), SCARG(uap, name))) {
error = pledge_fail(p, EPERM, PLEDGE_INET);
goto bad;
}
@@ -985,6 +985,10 @@ sys_getsockopt(struct proc *p, void *v, register_t *retval)
if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
return (error);
+ if (pledge_sockopt_check(p, SCARG(uap, level), SCARG(uap, name))) {
+ error = pledge_fail(p, EPERM, PLEDGE_INET);
+ goto out;
+ }
if (isdnssocket((struct socket *)fp->f_data)) {
error = EINVAL;
goto out;
diff --git a/sys/sys/pledge.h b/sys/sys/pledge.h
index 67af2b60688..68b0ca13853 100644
--- a/sys/sys/pledge.h
+++ b/sys/sys/pledge.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pledge.h,v 1.7 2015/10/18 20:15:10 deraadt Exp $ */
+/* $OpenBSD: pledge.h,v 1.8 2015/10/20 01:44:00 deraadt Exp $ */
/*
* Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -69,7 +69,7 @@ int pledge_adjtime_check(struct proc *p, const void *v);
int pledge_recvit_check(struct proc *p, const void *from);
int pledge_sendit_check(struct proc *p, const void *to);
int pledge_socket_check(struct proc *p, int domain);
-int pledge_setsockopt_check(struct proc *p, int level, int optname);
+int pledge_sockopt_check(struct proc *p, int level, int optname);
int pledge_dns_check(struct proc *p, in_port_t port);
int pledge_ioctl_check(struct proc *p, long com, void *);
int pledge_flock_check(struct proc *p);