Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 201862
b: refs/heads/master
c: 253bfae
h: refs/heads/master
v: v3
  • Loading branch information
Paul Moore authored and James Morris committed Aug 2, 2010
1 parent 9f2e990 commit 6c161f6
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 75 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 84914b7ed1c5e0f3199a5a6997022758a70fcaff
refs/heads/master: 253bfae6e0ad97554799affa0266052968a45808
119 changes: 45 additions & 74 deletions trunk/security/selinux/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -3651,26 +3651,19 @@ static u32 socket_sockcreate_sid(const struct task_security_struct *tsec)
return tsec->sockcreate_sid ? : tsec->sid;
}

static int socket_has_perm(struct task_struct *task, struct socket *sock,
u32 perms)
static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms)
{
struct inode_security_struct *isec;
struct sk_security_struct *sksec = sk->sk_security;
struct common_audit_data ad;
u32 sid;
int err = 0;
u32 tsid = task_sid(task);

isec = SOCK_INODE(sock)->i_security;

if (isec->sid == SECINITSID_KERNEL)
goto out;
sid = task_sid(task);
if (sksec->sid == SECINITSID_KERNEL)
return 0;

COMMON_AUDIT_DATA_INIT(&ad, NET);
ad.u.net.sk = sock->sk;
err = avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);
ad.u.net.sk = sk;

out:
return err;
return avc_has_perm(tsid, sksec->sid, sksec->sclass, perms, &ad);
}

static int selinux_socket_create(int family, int type,
Expand Down Expand Up @@ -3722,10 +3715,11 @@ static int selinux_socket_post_create(struct socket *sock, int family,

static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
{
struct sock *sk = sock->sk;
u16 family;
int err;

err = socket_has_perm(current, sock, SOCKET__BIND);
err = sock_has_perm(current, sk, SOCKET__BIND);
if (err)
goto out;

Expand All @@ -3734,19 +3728,16 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
* Multiple address binding for SCTP is not supported yet: we just
* check the first address now.
*/
family = sock->sk->sk_family;
family = sk->sk_family;
if (family == PF_INET || family == PF_INET6) {
char *addrp;
struct inode_security_struct *isec;
struct sk_security_struct *sksec = sk->sk_security;
struct common_audit_data ad;
struct sockaddr_in *addr4 = NULL;
struct sockaddr_in6 *addr6 = NULL;
unsigned short snum;
struct sock *sk = sock->sk;
u32 sid, node_perm;

isec = SOCK_INODE(sock)->i_security;

if (family == PF_INET) {
addr4 = (struct sockaddr_in *)address;
snum = ntohs(addr4->sin_port);
Expand All @@ -3770,15 +3761,15 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
COMMON_AUDIT_DATA_INIT(&ad, NET);
ad.u.net.sport = htons(snum);
ad.u.net.family = family;
err = avc_has_perm(isec->sid, sid,
isec->sclass,
err = avc_has_perm(sksec->sid, sid,
sksec->sclass,
SOCKET__NAME_BIND, &ad);
if (err)
goto out;
}
}

switch (isec->sclass) {
switch (sksec->sclass) {
case SECCLASS_TCP_SOCKET:
node_perm = TCP_SOCKET__NODE_BIND;
break;
Expand Down Expand Up @@ -3809,8 +3800,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
else
ipv6_addr_copy(&ad.u.net.v6info.saddr, &addr6->sin6_addr);

err = avc_has_perm(isec->sid, sid,
isec->sclass, node_perm, &ad);
err = avc_has_perm(sksec->sid, sid,
sksec->sclass, node_perm, &ad);
if (err)
goto out;
}
Expand All @@ -3821,19 +3812,18 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)
{
struct sock *sk = sock->sk;
struct inode_security_struct *isec;
struct sk_security_struct *sksec = sk->sk_security;
int err;

err = socket_has_perm(current, sock, SOCKET__CONNECT);
err = sock_has_perm(current, sk, SOCKET__CONNECT);
if (err)
return err;

/*
* If a TCP or DCCP socket, check name_connect permission for the port.
*/
isec = SOCK_INODE(sock)->i_security;
if (isec->sclass == SECCLASS_TCP_SOCKET ||
isec->sclass == SECCLASS_DCCP_SOCKET) {
if (sksec->sclass == SECCLASS_TCP_SOCKET ||
sksec->sclass == SECCLASS_DCCP_SOCKET) {
struct common_audit_data ad;
struct sockaddr_in *addr4 = NULL;
struct sockaddr_in6 *addr6 = NULL;
Expand All @@ -3856,13 +3846,13 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
if (err)
goto out;

perm = (isec->sclass == SECCLASS_TCP_SOCKET) ?
perm = (sksec->sclass == SECCLASS_TCP_SOCKET) ?
TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT;

COMMON_AUDIT_DATA_INIT(&ad, NET);
ad.u.net.dport = htons(snum);
ad.u.net.family = sk->sk_family;
err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad);
err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad);
if (err)
goto out;
}
Expand All @@ -3875,7 +3865,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,

static int selinux_socket_listen(struct socket *sock, int backlog)
{
return socket_has_perm(current, sock, SOCKET__LISTEN);
return sock_has_perm(current, sock->sk, SOCKET__LISTEN);
}

static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
Expand All @@ -3884,7 +3874,7 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
struct inode_security_struct *isec;
struct inode_security_struct *newisec;

err = socket_has_perm(current, sock, SOCKET__ACCEPT);
err = sock_has_perm(current, sock->sk, SOCKET__ACCEPT);
if (err)
return err;

Expand All @@ -3901,30 +3891,30 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
int size)
{
return socket_has_perm(current, sock, SOCKET__WRITE);
return sock_has_perm(current, sock->sk, SOCKET__WRITE);
}

static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
int size, int flags)
{
return socket_has_perm(current, sock, SOCKET__READ);
return sock_has_perm(current, sock->sk, SOCKET__READ);
}

static int selinux_socket_getsockname(struct socket *sock)
{
return socket_has_perm(current, sock, SOCKET__GETATTR);
return sock_has_perm(current, sock->sk, SOCKET__GETATTR);
}

static int selinux_socket_getpeername(struct socket *sock)
{
return socket_has_perm(current, sock, SOCKET__GETATTR);
return sock_has_perm(current, sock->sk, SOCKET__GETATTR);
}

static int selinux_socket_setsockopt(struct socket *sock, int level, int optname)
{
int err;

err = socket_has_perm(current, sock, SOCKET__SETOPT);
err = sock_has_perm(current, sock->sk, SOCKET__SETOPT);
if (err)
return err;

Expand All @@ -3934,12 +3924,12 @@ static int selinux_socket_setsockopt(struct socket *sock, int level, int optname
static int selinux_socket_getsockopt(struct socket *sock, int level,
int optname)
{
return socket_has_perm(current, sock, SOCKET__GETOPT);
return sock_has_perm(current, sock->sk, SOCKET__GETOPT);
}

static int selinux_socket_shutdown(struct socket *sock, int how)
{
return socket_has_perm(current, sock, SOCKET__SHUTDOWN);
return sock_has_perm(current, sock->sk, SOCKET__SHUTDOWN);
}

static int selinux_socket_unix_stream_connect(struct socket *sock,
Expand Down Expand Up @@ -3977,23 +3967,15 @@ static int selinux_socket_unix_stream_connect(struct socket *sock,
static int selinux_socket_unix_may_send(struct socket *sock,
struct socket *other)
{
struct inode_security_struct *isec;
struct inode_security_struct *other_isec;
struct sk_security_struct *ssec = sock->sk->sk_security;
struct sk_security_struct *osec = other->sk->sk_security;
struct common_audit_data ad;
int err;

isec = SOCK_INODE(sock)->i_security;
other_isec = SOCK_INODE(other)->i_security;

COMMON_AUDIT_DATA_INIT(&ad, NET);
ad.u.net.sk = other->sk;

err = avc_has_perm(isec->sid, other_isec->sid,
isec->sclass, SOCKET__SENDTO, &ad);
if (err)
return err;

return 0;
return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
&ad);
}

static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family,
Expand Down Expand Up @@ -4132,26 +4114,18 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
int err = 0;
char *scontext;
u32 scontext_len;
struct sk_security_struct *sksec;
struct inode_security_struct *isec;
struct sk_security_struct *sksec = sock->sk->sk_security;
u32 peer_sid = SECSID_NULL;

isec = SOCK_INODE(sock)->i_security;

if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
isec->sclass == SECCLASS_TCP_SOCKET) {
sksec = sock->sk->sk_security;
if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
sksec->sclass == SECCLASS_TCP_SOCKET)
peer_sid = sksec->peer_sid;
}
if (peer_sid == SECSID_NULL) {
err = -ENOPROTOOPT;
goto out;
}
if (peer_sid == SECSID_NULL)
return -ENOPROTOOPT;

err = security_sid_to_context(peer_sid, &scontext, &scontext_len);

if (err)
goto out;
return err;

if (scontext_len > len) {
err = -ERANGE;
Expand All @@ -4164,9 +4138,7 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
out_len:
if (put_user(scontext_len, optlen))
err = -EFAULT;

kfree(scontext);
out:
return err;
}

Expand Down Expand Up @@ -4378,22 +4350,21 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
int err = 0;
u32 perm;
struct nlmsghdr *nlh;
struct socket *sock = sk->sk_socket;
struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
struct sk_security_struct *sksec = sk->sk_security;

if (skb->len < NLMSG_SPACE(0)) {
err = -EINVAL;
goto out;
}
nlh = nlmsg_hdr(skb);

err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm);
err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm);
if (err) {
if (err == -EINVAL) {
audit_log(current->audit_context, GFP_KERNEL, AUDIT_SELINUX_ERR,
"SELinux: unrecognized netlink message"
" type=%hu for sclass=%hu\n",
nlh->nlmsg_type, isec->sclass);
nlh->nlmsg_type, sksec->sclass);
if (!selinux_enforcing || security_get_allow_unknown())
err = 0;
}
Expand All @@ -4404,7 +4375,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
goto out;
}

err = socket_has_perm(current, sock, perm);
err = sock_has_perm(current, sk, perm);
out:
return err;
}
Expand Down

0 comments on commit 6c161f6

Please sign in to comment.