@ -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 ,
@ -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 , soc k , SOCKET__BIND ) ;
err = sock_has_perm ( current , sk , SOCKET__BIND ) ;
if ( err )
goto out ;
@ -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 - > s k - > 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 ) ;
@ -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 ( i sec- > sid , sid ,
i sec- > sclass ,
err = avc_has_perm ( sk sec- > sid , sid ,
sk sec- > sclass ,
SOCKET__NAME_BIND , & ad ) ;
if ( err )
goto out ;
}
}
switch ( i sec- > sclass ) {
switch ( sk sec- > sclass ) {
case SECCLASS_TCP_SOCKET :
node_perm = TCP_SOCKET__NODE_BIND ;
break ;
@ -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 ( i sec- > sid , sid ,
i sec- > sclass , node_perm , & ad ) ;
err = avc_has_perm ( sk sec- > sid , sid ,
sk sec- > sclass , node_perm , & ad ) ;
if ( err )
goto out ;
}
@ -3821,19 +3812,18 @@ out:
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 , soc k , 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 ;
@ -3856,13 +3846,13 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
if ( err )
goto out ;
perm = ( i sec- > sclass = = SECCLASS_TCP_SOCKET ) ?
perm = ( sk sec- > 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 ( i sec- > sid , sid , i sec- > sclass , perm , & ad ) ;
err = avc_has_perm ( sk sec- > sid , sid , sk sec- > sclass , perm , & ad ) ;
if ( err )
goto out ;
}
@ -3875,7 +3865,7 @@ out:
static int selinux_socket_listen ( struct socket * sock , int backlog )
{
return socket _has_perm ( current , sock , SOCKET__LISTEN ) ;
return sock_has_perm ( current , sock - > s k , SOCKET__LISTEN ) ;
}
static int selinux_socket_accept ( struct socket * sock , struct socket * newsock )
@ -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 - > s k , SOCKET__ACCEPT ) ;
if ( err )
return err ;
@ -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 - > s k , 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 - > s k , SOCKET__READ ) ;
}
static int selinux_socket_getsockname ( struct socket * sock )
{
return socket _has_perm ( current , sock , SOCKET__GETATTR ) ;
return sock_has_perm ( current , sock - > s k , SOCKET__GETATTR ) ;
}
static int selinux_socket_getpeername ( struct socket * sock )
{
return socket _has_perm ( current , sock , SOCKET__GETATTR ) ;
return sock_has_perm ( current , sock - > s k , 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 - > s k , SOCKET__SETOPT ) ;
if ( err )
return err ;
@ -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 - > s k , 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 - > s k , SOCKET__SHUTDOWN ) ;
}
static int selinux_socket_unix_stream_connect ( struct socket * sock ,
@ -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_i sec ;
struct sk_security_struct * ssec = sock - > sk - > sk_security ;
struct sk _security_struct * osec = o ther - > 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 ,
@ -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 ;
@ -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 ;
}
@ -4378,8 +4350,7 @@ 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 ;
@ -4387,13 +4358,13 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
}
nlh = nlmsg_hdr ( skb ) ;
err = selinux_nlmsg_lookup ( i sec- > sclass , nlh - > nlmsg_type , & perm ) ;
err = selinux_nlmsg_lookup ( sk sec- > 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 , i sec- > sclass ) ;
nlh - > nlmsg_type , sk sec- > sclass ) ;
if ( ! selinux_enforcing | | security_get_allow_unknown ( ) )
err = 0 ;
}
@ -4404,7 +4375,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
goto out ;
}
err = socket _has_perm ( current , soc k , perm ) ;
err = sock_has_perm ( current , sk , perm ) ;
out :
return err ;
}