-/* $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>
[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 */
[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,
};
}
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) {
if ((p->p_p->ps_pledge & PLEDGE_INET) == 0)
return (EPERM);
-
switch (level) {
case IPPROTO_TCP:
switch (optname) {
-/* $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 $ */
/*
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;
}
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;
-/* $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>
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);