summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_pledge.c34
-rw-r--r--sys/kern/uipc_syscalls.c44
-rw-r--r--sys/sys/pledge.h4
3 files changed, 64 insertions, 18 deletions
diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c
index 5a1b5d74c60..e74a3c1c0bc 100644
--- a/sys/kern/kern_pledge.c
+++ b/sys/kern/kern_pledge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_pledge.c,v 1.114 2015/11/17 15:03:53 sthen Exp $ */
+/* $OpenBSD: kern_pledge.c,v 1.115 2015/11/18 08:24:22 semarie Exp $ */
/*
* Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -1317,16 +1317,32 @@ pledge_sockopt(struct proc *p, int set, int level, int optname)
}
int
-pledge_socket(struct proc *p, int dns)
+pledge_socket(struct proc *p, int domain, int state)
{
- if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
- return (0);
+ if (! ISSET(p->p_p->ps_flags, PS_PLEDGE))
+ return 0;
- if (dns && (p->p_p->ps_pledge & PLEDGE_DNS))
- return (0);
- if ((p->p_p->ps_pledge & (PLEDGE_INET|PLEDGE_UNIX|PLEDGE_YPACTIVE)))
- return (0);
- return pledge_fail(p, EPERM, dns ? PLEDGE_DNS : PLEDGE_INET);
+ if (ISSET(state, SS_DNS)) {
+ if (ISSET(p->p_p->ps_pledge, PLEDGE_DNS))
+ return 0;
+ return pledge_fail(p, EPERM, PLEDGE_DNS);
+ }
+
+ switch (domain) {
+ case AF_INET:
+ case AF_INET6:
+ if (ISSET(p->p_p->ps_pledge, PLEDGE_INET) ||
+ ISSET(p->p_p->ps_pledge, PLEDGE_YPACTIVE))
+ return 0;
+ return pledge_fail(p, EPERM, PLEDGE_INET);
+
+ case AF_UNIX:
+ if (ISSET(p->p_p->ps_pledge, PLEDGE_UNIX))
+ return 0;
+ return pledge_fail(p, EPERM, PLEDGE_UNIX);
+ }
+
+ return pledge_fail(p, EINVAL, PLEDGE_INET);
}
int
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index e2866a1a363..122d51f2a0a 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_syscalls.c,v 1.124 2015/11/08 23:23:12 tedu Exp $ */
+/* $OpenBSD: uipc_syscalls.c,v 1.125 2015/11/18 08:24:22 semarie Exp $ */
/* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */
/*
@@ -80,11 +80,14 @@ sys_socket(struct proc *p, void *v, register_t *retval)
struct file *fp;
int type = SCARG(uap, type);
int domain = SCARG(uap, domain);
- int fd, error;
+ int fd, error, ss = 0;
if ((type & SOCK_DNS) && !(domain == AF_INET || domain == AF_INET6))
return (EINVAL);
- error = pledge_socket(p, type & SOCK_DNS);
+
+ if (ISSET(type, SOCK_DNS))
+ ss |= SS_DNS;
+ error = pledge_socket(p, domain, ss);
if (error)
return (error);
@@ -110,8 +113,7 @@ sys_socket(struct proc *p, void *v, register_t *retval)
fp->f_data = so;
if (type & SOCK_NONBLOCK)
(*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&type, p);
- if (type & SOCK_DNS)
- so->so_state |= SS_DNS;
+ so->so_state |= ss;
FILE_SET_MATURE(fp, p);
*retval = fd;
}
@@ -158,10 +160,16 @@ sys_bind(struct proc *p, void *v, register_t *retval)
} */ *uap = v;
struct file *fp;
struct mbuf *nam;
+ struct socket *so;
int error;
if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
return (error);
+ so = fp->f_data;
+ error = pledge_socket(p, so->so_proto->pr_domain->dom_family,
+ so->so_state);
+ if (error)
+ return (error);
error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
MT_SONAME);
if (error == 0) {
@@ -169,7 +177,7 @@ sys_bind(struct proc *p, void *v, register_t *retval)
if (KTRPOINT(p, KTR_STRUCT))
ktrsockaddr(p, mtod(nam, caddr_t), SCARG(uap, namelen));
#endif
- error = sobind(fp->f_data, nam, p);
+ error = sobind(so, nam, p);
m_freem(nam);
}
FRELE(fp, p);
@@ -185,11 +193,17 @@ sys_listen(struct proc *p, void *v, register_t *retval)
syscallarg(int) backlog;
} */ *uap = v;
struct file *fp;
+ struct socket *so;
int error;
if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
return (error);
- error = solisten(fp->f_data, SCARG(uap, backlog));
+ so = fp->f_data;
+ error = pledge_socket(p, so->so_proto->pr_domain->dom_family,
+ so->so_state);
+ if (error)
+ return (error);
+ error = solisten(so, SCARG(uap, backlog));
FRELE(fp, p);
return (error);
}
@@ -245,6 +259,10 @@ doaccept(struct proc *p, int sock, struct sockaddr *name, socklen_t *anamelen,
headfp = fp;
head = fp->f_data;
+ error = pledge_socket(p, head->so_proto->pr_domain->dom_family,
+ head->so_state);
+ if (error)
+ goto bad;
if (isdnssocket((struct socket *)fp->f_data)) {
error = EINVAL;
goto bad;
@@ -372,6 +390,10 @@ sys_connect(struct proc *p, void *v, register_t *retval)
MT_SONAME);
if (error)
goto bad;
+ error = pledge_socket(p, so->so_proto->pr_domain->dom_family,
+ so->so_state);
+ if (error)
+ goto bad;
#ifdef KTRACE
if (KTRPOINT(p, KTR_STRUCT))
ktrsockaddr(p, mtod(nam, caddr_t), SCARG(uap, namelen));
@@ -1029,6 +1051,10 @@ sys_getsockname(struct proc *p, void *v, register_t *retval)
if (error)
goto bad;
so = fp->f_data;
+ error = pledge_socket(p, so->so_proto->pr_domain->dom_family,
+ so->so_state);
+ if (error)
+ goto bad;
m = m_getclr(M_WAIT, MT_SONAME);
error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0, p);
if (error)
@@ -1062,6 +1088,10 @@ sys_getpeername(struct proc *p, void *v, register_t *retval)
if ((error = getsock(p, SCARG(uap, fdes), &fp)) != 0)
return (error);
so = fp->f_data;
+ error = pledge_socket(p, so->so_proto->pr_domain->dom_family,
+ so->so_state);
+ if (error)
+ return (error);
if ((so->so_state & SS_ISCONNECTED) == 0) {
FRELE(fp, p);
return (ENOTCONN);
diff --git a/sys/sys/pledge.h b/sys/sys/pledge.h
index 94766c745a6..f0bc6e700c0 100644
--- a/sys/sys/pledge.h
+++ b/sys/sys/pledge.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pledge.h,v 1.18 2015/11/04 21:24:23 tedu Exp $ */
+/* $OpenBSD: pledge.h,v 1.19 2015/11/18 08:24:22 semarie Exp $ */
/*
* Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -106,7 +106,7 @@ int pledge_chown(struct proc *p, uid_t, gid_t);
int pledge_adjtime(struct proc *p, const void *v);
int pledge_sendit(struct proc *p, const void *to);
int pledge_sockopt(struct proc *p, int set, int level, int optname);
-int pledge_socket(struct proc *p, int dns);
+int pledge_socket(struct proc *p, int domain, int state);
int pledge_ioctl(struct proc *p, long com, struct file *);
int pledge_flock(struct proc *p);
int pledge_fcntl(struct proc *p, int cmd);