aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c292
1 files changed, 114 insertions, 178 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2a8a0a915ff3..42043f96e54f 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -87,9 +87,6 @@
87#include "netlabel.h" 87#include "netlabel.h"
88#include "audit.h" 88#include "audit.h"
89 89
90#define XATTR_SELINUX_SUFFIX "selinux"
91#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
92
93#define NUM_SEL_MNT_OPTS 5 90#define NUM_SEL_MNT_OPTS 5
94 91
95extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); 92extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
@@ -188,7 +185,7 @@ static inline u32 task_sid(const struct task_struct *task)
188 */ 185 */
189static inline u32 current_sid(void) 186static inline u32 current_sid(void)
190{ 187{
191 const struct task_security_struct *tsec = current_cred()->security; 188 const struct task_security_struct *tsec = current_security();
192 189
193 return tsec->sid; 190 return tsec->sid;
194} 191}
@@ -279,32 +276,6 @@ static void superblock_free_security(struct super_block *sb)
279 kfree(sbsec); 276 kfree(sbsec);
280} 277}
281 278
282static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
283{
284 struct sk_security_struct *sksec;
285
286 sksec = kzalloc(sizeof(*sksec), priority);
287 if (!sksec)
288 return -ENOMEM;
289
290 sksec->peer_sid = SECINITSID_UNLABELED;
291 sksec->sid = SECINITSID_UNLABELED;
292 sk->sk_security = sksec;
293
294 selinux_netlbl_sk_security_reset(sksec);
295
296 return 0;
297}
298
299static void sk_free_security(struct sock *sk)
300{
301 struct sk_security_struct *sksec = sk->sk_security;
302
303 sk->sk_security = NULL;
304 selinux_netlbl_sk_security_free(sksec);
305 kfree(sksec);
306}
307
308/* The security server must be initialized before 279/* The security server must be initialized before
309 any labeling or access decisions can be provided. */ 280 any labeling or access decisions can be provided. */
310extern int ss_initialized; 281extern int ss_initialized;
@@ -1584,8 +1555,7 @@ static int may_create(struct inode *dir,
1584 struct dentry *dentry, 1555 struct dentry *dentry,
1585 u16 tclass) 1556 u16 tclass)
1586{ 1557{
1587 const struct cred *cred = current_cred(); 1558 const struct task_security_struct *tsec = current_security();
1588 const struct task_security_struct *tsec = cred->security;
1589 struct inode_security_struct *dsec; 1559 struct inode_security_struct *dsec;
1590 struct superblock_security_struct *sbsec; 1560 struct superblock_security_struct *sbsec;
1591 u32 sid, newsid; 1561 u32 sid, newsid;
@@ -1806,27 +1776,9 @@ static inline u32 open_file_to_av(struct file *file)
1806{ 1776{
1807 u32 av = file_to_av(file); 1777 u32 av = file_to_av(file);
1808 1778
1809 if (selinux_policycap_openperm) { 1779 if (selinux_policycap_openperm)
1810 mode_t mode = file->f_path.dentry->d_inode->i_mode; 1780 av |= FILE__OPEN;
1811 /* 1781
1812 * lnk files and socks do not really have an 'open'
1813 */
1814 if (S_ISREG(mode))
1815 av |= FILE__OPEN;
1816 else if (S_ISCHR(mode))
1817 av |= CHR_FILE__OPEN;
1818 else if (S_ISBLK(mode))
1819 av |= BLK_FILE__OPEN;
1820 else if (S_ISFIFO(mode))
1821 av |= FIFO_FILE__OPEN;
1822 else if (S_ISDIR(mode))
1823 av |= DIR__OPEN;
1824 else if (S_ISSOCK(mode))
1825 av |= SOCK_FILE__OPEN;
1826 else
1827 printk(KERN_ERR "SELinux: WARNING: inside %s with "
1828 "unknown mode:%o\n", __func__, mode);
1829 }
1830 return av; 1782 return av;
1831} 1783}
1832 1784
@@ -2183,8 +2135,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
2183 2135
2184static int selinux_bprm_secureexec(struct linux_binprm *bprm) 2136static int selinux_bprm_secureexec(struct linux_binprm *bprm)
2185{ 2137{
2186 const struct cred *cred = current_cred(); 2138 const struct task_security_struct *tsec = current_security();
2187 const struct task_security_struct *tsec = cred->security;
2188 u32 sid, osid; 2139 u32 sid, osid;
2189 int atsecure = 0; 2140 int atsecure = 0;
2190 2141
@@ -2562,8 +2513,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2562 char **name, void **value, 2513 char **name, void **value,
2563 size_t *len) 2514 size_t *len)
2564{ 2515{
2565 const struct cred *cred = current_cred(); 2516 const struct task_security_struct *tsec = current_security();
2566 const struct task_security_struct *tsec = cred->security;
2567 struct inode_security_struct *dsec; 2517 struct inode_security_struct *dsec;
2568 struct superblock_security_struct *sbsec; 2518 struct superblock_security_struct *sbsec;
2569 u32 sid, newsid, clen; 2519 u32 sid, newsid, clen;
@@ -2679,14 +2629,26 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na
2679static int selinux_inode_permission(struct inode *inode, int mask) 2629static int selinux_inode_permission(struct inode *inode, int mask)
2680{ 2630{
2681 const struct cred *cred = current_cred(); 2631 const struct cred *cred = current_cred();
2632 struct common_audit_data ad;
2633 u32 perms;
2634 bool from_access;
2682 2635
2683 if (!mask) { 2636 from_access = mask & MAY_ACCESS;
2684 /* No permission to check. Existence test. */ 2637 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
2638
2639 /* No permission to check. Existence test. */
2640 if (!mask)
2685 return 0; 2641 return 0;
2686 }
2687 2642
2688 return inode_has_perm(cred, inode, 2643 COMMON_AUDIT_DATA_INIT(&ad, FS);
2689 file_mask_to_av(inode->i_mode, mask), NULL); 2644 ad.u.fs.inode = inode;
2645
2646 if (from_access)
2647 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS;
2648
2649 perms = file_mask_to_av(inode->i_mode, mask);
2650
2651 return inode_has_perm(cred, inode, perms, &ad);
2690} 2652}
2691 2653
2692static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) 2654static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
@@ -3675,71 +3637,54 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
3675} 3637}
3676 3638
3677/* socket security operations */ 3639/* socket security operations */
3678static int socket_has_perm(struct task_struct *task, struct socket *sock, 3640
3679 u32 perms) 3641static u32 socket_sockcreate_sid(const struct task_security_struct *tsec)
3680{ 3642{
3681 struct inode_security_struct *isec; 3643 return tsec->sockcreate_sid ? : tsec->sid;
3682 struct common_audit_data ad; 3644}
3683 u32 sid;
3684 int err = 0;
3685 3645
3686 isec = SOCK_INODE(sock)->i_security; 3646static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms)
3647{
3648 struct sk_security_struct *sksec = sk->sk_security;
3649 struct common_audit_data ad;
3650 u32 tsid = task_sid(task);
3687 3651
3688 if (isec->sid == SECINITSID_KERNEL) 3652 if (sksec->sid == SECINITSID_KERNEL)
3689 goto out; 3653 return 0;
3690 sid = task_sid(task);
3691 3654
3692 COMMON_AUDIT_DATA_INIT(&ad, NET); 3655 COMMON_AUDIT_DATA_INIT(&ad, NET);
3693 ad.u.net.sk = sock->sk; 3656 ad.u.net.sk = sk;
3694 err = avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);
3695 3657
3696out: 3658 return avc_has_perm(tsid, sksec->sid, sksec->sclass, perms, &ad);
3697 return err;
3698} 3659}
3699 3660
3700static int selinux_socket_create(int family, int type, 3661static int selinux_socket_create(int family, int type,
3701 int protocol, int kern) 3662 int protocol, int kern)
3702{ 3663{
3703 const struct cred *cred = current_cred(); 3664 const struct task_security_struct *tsec = current_security();
3704 const struct task_security_struct *tsec = cred->security; 3665 u32 newsid;
3705 u32 sid, newsid;
3706 u16 secclass; 3666 u16 secclass;
3707 int err = 0;
3708 3667
3709 if (kern) 3668 if (kern)
3710 goto out; 3669 return 0;
3711
3712 sid = tsec->sid;
3713 newsid = tsec->sockcreate_sid ?: sid;
3714 3670
3671 newsid = socket_sockcreate_sid(tsec);
3715 secclass = socket_type_to_security_class(family, type, protocol); 3672 secclass = socket_type_to_security_class(family, type, protocol);
3716 err = avc_has_perm(sid, newsid, secclass, SOCKET__CREATE, NULL); 3673 return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
3717
3718out:
3719 return err;
3720} 3674}
3721 3675
3722static int selinux_socket_post_create(struct socket *sock, int family, 3676static int selinux_socket_post_create(struct socket *sock, int family,
3723 int type, int protocol, int kern) 3677 int type, int protocol, int kern)
3724{ 3678{
3725 const struct cred *cred = current_cred(); 3679 const struct task_security_struct *tsec = current_security();
3726 const struct task_security_struct *tsec = cred->security; 3680 struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
3727 struct inode_security_struct *isec;
3728 struct sk_security_struct *sksec; 3681 struct sk_security_struct *sksec;
3729 u32 sid, newsid;
3730 int err = 0; 3682 int err = 0;
3731 3683
3732 sid = tsec->sid;
3733 newsid = tsec->sockcreate_sid;
3734
3735 isec = SOCK_INODE(sock)->i_security;
3736
3737 if (kern) 3684 if (kern)
3738 isec->sid = SECINITSID_KERNEL; 3685 isec->sid = SECINITSID_KERNEL;
3739 else if (newsid)
3740 isec->sid = newsid;
3741 else 3686 else
3742 isec->sid = sid; 3687 isec->sid = socket_sockcreate_sid(tsec);
3743 3688
3744 isec->sclass = socket_type_to_security_class(family, type, protocol); 3689 isec->sclass = socket_type_to_security_class(family, type, protocol);
3745 isec->initialized = 1; 3690 isec->initialized = 1;
@@ -3760,10 +3705,11 @@ static int selinux_socket_post_create(struct socket *sock, int family,
3760 3705
3761static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) 3706static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
3762{ 3707{
3708 struct sock *sk = sock->sk;
3763 u16 family; 3709 u16 family;
3764 int err; 3710 int err;
3765 3711
3766 err = socket_has_perm(current, sock, SOCKET__BIND); 3712 err = sock_has_perm(current, sk, SOCKET__BIND);
3767 if (err) 3713 if (err)
3768 goto out; 3714 goto out;
3769 3715
@@ -3772,19 +3718,16 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
3772 * Multiple address binding for SCTP is not supported yet: we just 3718 * Multiple address binding for SCTP is not supported yet: we just
3773 * check the first address now. 3719 * check the first address now.
3774 */ 3720 */
3775 family = sock->sk->sk_family; 3721 family = sk->sk_family;
3776 if (family == PF_INET || family == PF_INET6) { 3722 if (family == PF_INET || family == PF_INET6) {
3777 char *addrp; 3723 char *addrp;
3778 struct inode_security_struct *isec; 3724 struct sk_security_struct *sksec = sk->sk_security;
3779 struct common_audit_data ad; 3725 struct common_audit_data ad;
3780 struct sockaddr_in *addr4 = NULL; 3726 struct sockaddr_in *addr4 = NULL;
3781 struct sockaddr_in6 *addr6 = NULL; 3727 struct sockaddr_in6 *addr6 = NULL;
3782 unsigned short snum; 3728 unsigned short snum;
3783 struct sock *sk = sock->sk;
3784 u32 sid, node_perm; 3729 u32 sid, node_perm;
3785 3730
3786 isec = SOCK_INODE(sock)->i_security;
3787
3788 if (family == PF_INET) { 3731 if (family == PF_INET) {
3789 addr4 = (struct sockaddr_in *)address; 3732 addr4 = (struct sockaddr_in *)address;
3790 snum = ntohs(addr4->sin_port); 3733 snum = ntohs(addr4->sin_port);
@@ -3808,15 +3751,15 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
3808 COMMON_AUDIT_DATA_INIT(&ad, NET); 3751 COMMON_AUDIT_DATA_INIT(&ad, NET);
3809 ad.u.net.sport = htons(snum); 3752 ad.u.net.sport = htons(snum);
3810 ad.u.net.family = family; 3753 ad.u.net.family = family;
3811 err = avc_has_perm(isec->sid, sid, 3754 err = avc_has_perm(sksec->sid, sid,
3812 isec->sclass, 3755 sksec->sclass,
3813 SOCKET__NAME_BIND, &ad); 3756 SOCKET__NAME_BIND, &ad);
3814 if (err) 3757 if (err)
3815 goto out; 3758 goto out;
3816 } 3759 }
3817 } 3760 }
3818 3761
3819 switch (isec->sclass) { 3762 switch (sksec->sclass) {
3820 case SECCLASS_TCP_SOCKET: 3763 case SECCLASS_TCP_SOCKET:
3821 node_perm = TCP_SOCKET__NODE_BIND; 3764 node_perm = TCP_SOCKET__NODE_BIND;
3822 break; 3765 break;
@@ -3847,8 +3790,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
3847 else 3790 else
3848 ipv6_addr_copy(&ad.u.net.v6info.saddr, &addr6->sin6_addr); 3791 ipv6_addr_copy(&ad.u.net.v6info.saddr, &addr6->sin6_addr);
3849 3792
3850 err = avc_has_perm(isec->sid, sid, 3793 err = avc_has_perm(sksec->sid, sid,
3851 isec->sclass, node_perm, &ad); 3794 sksec->sclass, node_perm, &ad);
3852 if (err) 3795 if (err)
3853 goto out; 3796 goto out;
3854 } 3797 }
@@ -3859,19 +3802,18 @@ out:
3859static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen) 3802static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)
3860{ 3803{
3861 struct sock *sk = sock->sk; 3804 struct sock *sk = sock->sk;
3862 struct inode_security_struct *isec; 3805 struct sk_security_struct *sksec = sk->sk_security;
3863 int err; 3806 int err;
3864 3807
3865 err = socket_has_perm(current, sock, SOCKET__CONNECT); 3808 err = sock_has_perm(current, sk, SOCKET__CONNECT);
3866 if (err) 3809 if (err)
3867 return err; 3810 return err;
3868 3811
3869 /* 3812 /*
3870 * If a TCP or DCCP socket, check name_connect permission for the port. 3813 * If a TCP or DCCP socket, check name_connect permission for the port.
3871 */ 3814 */
3872 isec = SOCK_INODE(sock)->i_security; 3815 if (sksec->sclass == SECCLASS_TCP_SOCKET ||
3873 if (isec->sclass == SECCLASS_TCP_SOCKET || 3816 sksec->sclass == SECCLASS_DCCP_SOCKET) {
3874 isec->sclass == SECCLASS_DCCP_SOCKET) {
3875 struct common_audit_data ad; 3817 struct common_audit_data ad;
3876 struct sockaddr_in *addr4 = NULL; 3818 struct sockaddr_in *addr4 = NULL;
3877 struct sockaddr_in6 *addr6 = NULL; 3819 struct sockaddr_in6 *addr6 = NULL;
@@ -3894,13 +3836,13 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
3894 if (err) 3836 if (err)
3895 goto out; 3837 goto out;
3896 3838
3897 perm = (isec->sclass == SECCLASS_TCP_SOCKET) ? 3839 perm = (sksec->sclass == SECCLASS_TCP_SOCKET) ?
3898 TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; 3840 TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT;
3899 3841
3900 COMMON_AUDIT_DATA_INIT(&ad, NET); 3842 COMMON_AUDIT_DATA_INIT(&ad, NET);
3901 ad.u.net.dport = htons(snum); 3843 ad.u.net.dport = htons(snum);
3902 ad.u.net.family = sk->sk_family; 3844 ad.u.net.family = sk->sk_family;
3903 err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad); 3845 err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad);
3904 if (err) 3846 if (err)
3905 goto out; 3847 goto out;
3906 } 3848 }
@@ -3913,7 +3855,7 @@ out:
3913 3855
3914static int selinux_socket_listen(struct socket *sock, int backlog) 3856static int selinux_socket_listen(struct socket *sock, int backlog)
3915{ 3857{
3916 return socket_has_perm(current, sock, SOCKET__LISTEN); 3858 return sock_has_perm(current, sock->sk, SOCKET__LISTEN);
3917} 3859}
3918 3860
3919static int selinux_socket_accept(struct socket *sock, struct socket *newsock) 3861static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
@@ -3922,7 +3864,7 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
3922 struct inode_security_struct *isec; 3864 struct inode_security_struct *isec;
3923 struct inode_security_struct *newisec; 3865 struct inode_security_struct *newisec;
3924 3866
3925 err = socket_has_perm(current, sock, SOCKET__ACCEPT); 3867 err = sock_has_perm(current, sock->sk, SOCKET__ACCEPT);
3926 if (err) 3868 if (err)
3927 return err; 3869 return err;
3928 3870
@@ -3939,30 +3881,30 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
3939static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, 3881static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
3940 int size) 3882 int size)
3941{ 3883{
3942 return socket_has_perm(current, sock, SOCKET__WRITE); 3884 return sock_has_perm(current, sock->sk, SOCKET__WRITE);
3943} 3885}
3944 3886
3945static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg, 3887static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
3946 int size, int flags) 3888 int size, int flags)
3947{ 3889{
3948 return socket_has_perm(current, sock, SOCKET__READ); 3890 return sock_has_perm(current, sock->sk, SOCKET__READ);
3949} 3891}
3950 3892
3951static int selinux_socket_getsockname(struct socket *sock) 3893static int selinux_socket_getsockname(struct socket *sock)
3952{ 3894{
3953 return socket_has_perm(current, sock, SOCKET__GETATTR); 3895 return sock_has_perm(current, sock->sk, SOCKET__GETATTR);
3954} 3896}
3955 3897
3956static int selinux_socket_getpeername(struct socket *sock) 3898static int selinux_socket_getpeername(struct socket *sock)
3957{ 3899{
3958 return socket_has_perm(current, sock, SOCKET__GETATTR); 3900 return sock_has_perm(current, sock->sk, SOCKET__GETATTR);
3959} 3901}
3960 3902
3961static int selinux_socket_setsockopt(struct socket *sock, int level, int optname) 3903static int selinux_socket_setsockopt(struct socket *sock, int level, int optname)
3962{ 3904{
3963 int err; 3905 int err;
3964 3906
3965 err = socket_has_perm(current, sock, SOCKET__SETOPT); 3907 err = sock_has_perm(current, sock->sk, SOCKET__SETOPT);
3966 if (err) 3908 if (err)
3967 return err; 3909 return err;
3968 3910
@@ -3972,68 +3914,58 @@ static int selinux_socket_setsockopt(struct socket *sock, int level, int optname
3972static int selinux_socket_getsockopt(struct socket *sock, int level, 3914static int selinux_socket_getsockopt(struct socket *sock, int level,
3973 int optname) 3915 int optname)
3974{ 3916{
3975 return socket_has_perm(current, sock, SOCKET__GETOPT); 3917 return sock_has_perm(current, sock->sk, SOCKET__GETOPT);
3976} 3918}
3977 3919
3978static int selinux_socket_shutdown(struct socket *sock, int how) 3920static int selinux_socket_shutdown(struct socket *sock, int how)
3979{ 3921{
3980 return socket_has_perm(current, sock, SOCKET__SHUTDOWN); 3922 return sock_has_perm(current, sock->sk, SOCKET__SHUTDOWN);
3981} 3923}
3982 3924
3983static int selinux_socket_unix_stream_connect(struct socket *sock, 3925static int selinux_socket_unix_stream_connect(struct socket *sock,
3984 struct socket *other, 3926 struct socket *other,
3985 struct sock *newsk) 3927 struct sock *newsk)
3986{ 3928{
3987 struct sk_security_struct *sksec; 3929 struct sk_security_struct *sksec_sock = sock->sk->sk_security;
3988 struct inode_security_struct *isec; 3930 struct sk_security_struct *sksec_other = other->sk->sk_security;
3989 struct inode_security_struct *other_isec; 3931 struct sk_security_struct *sksec_new = newsk->sk_security;
3990 struct common_audit_data ad; 3932 struct common_audit_data ad;
3991 int err; 3933 int err;
3992 3934
3993 isec = SOCK_INODE(sock)->i_security;
3994 other_isec = SOCK_INODE(other)->i_security;
3995
3996 COMMON_AUDIT_DATA_INIT(&ad, NET); 3935 COMMON_AUDIT_DATA_INIT(&ad, NET);
3997 ad.u.net.sk = other->sk; 3936 ad.u.net.sk = other->sk;
3998 3937
3999 err = avc_has_perm(isec->sid, other_isec->sid, 3938 err = avc_has_perm(sksec_sock->sid, sksec_other->sid,
4000 isec->sclass, 3939 sksec_other->sclass,
4001 UNIX_STREAM_SOCKET__CONNECTTO, &ad); 3940 UNIX_STREAM_SOCKET__CONNECTTO, &ad);
4002 if (err) 3941 if (err)
4003 return err; 3942 return err;
4004 3943
4005 /* connecting socket */
4006 sksec = sock->sk->sk_security;
4007 sksec->peer_sid = other_isec->sid;
4008
4009 /* server child socket */ 3944 /* server child socket */
4010 sksec = newsk->sk_security; 3945 sksec_new->peer_sid = sksec_sock->sid;
4011 sksec->peer_sid = isec->sid; 3946 err = security_sid_mls_copy(sksec_other->sid, sksec_sock->sid,
4012 err = security_sid_mls_copy(other_isec->sid, sksec->peer_sid, &sksec->sid); 3947 &sksec_new->sid);
3948 if (err)
3949 return err;
4013 3950
4014 return err; 3951 /* connecting socket */
3952 sksec_sock->peer_sid = sksec_new->sid;
3953
3954 return 0;
4015} 3955}
4016 3956
4017static int selinux_socket_unix_may_send(struct socket *sock, 3957static int selinux_socket_unix_may_send(struct socket *sock,
4018 struct socket *other) 3958 struct socket *other)
4019{ 3959{
4020 struct inode_security_struct *isec; 3960 struct sk_security_struct *ssec = sock->sk->sk_security;
4021 struct inode_security_struct *other_isec; 3961 struct sk_security_struct *osec = other->sk->sk_security;
4022 struct common_audit_data ad; 3962 struct common_audit_data ad;
4023 int err;
4024
4025 isec = SOCK_INODE(sock)->i_security;
4026 other_isec = SOCK_INODE(other)->i_security;
4027 3963
4028 COMMON_AUDIT_DATA_INIT(&ad, NET); 3964 COMMON_AUDIT_DATA_INIT(&ad, NET);
4029 ad.u.net.sk = other->sk; 3965 ad.u.net.sk = other->sk;
4030 3966
4031 err = avc_has_perm(isec->sid, other_isec->sid, 3967 return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
4032 isec->sclass, SOCKET__SENDTO, &ad); 3968 &ad);
4033 if (err)
4034 return err;
4035
4036 return 0;
4037} 3969}
4038 3970
4039static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family, 3971static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family,
@@ -4172,26 +4104,18 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
4172 int err = 0; 4104 int err = 0;
4173 char *scontext; 4105 char *scontext;
4174 u32 scontext_len; 4106 u32 scontext_len;
4175 struct sk_security_struct *sksec; 4107 struct sk_security_struct *sksec = sock->sk->sk_security;
4176 struct inode_security_struct *isec;
4177 u32 peer_sid = SECSID_NULL; 4108 u32 peer_sid = SECSID_NULL;
4178 4109
4179 isec = SOCK_INODE(sock)->i_security; 4110 if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
4180 4111 sksec->sclass == SECCLASS_TCP_SOCKET)
4181 if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
4182 isec->sclass == SECCLASS_TCP_SOCKET) {
4183 sksec = sock->sk->sk_security;
4184 peer_sid = sksec->peer_sid; 4112 peer_sid = sksec->peer_sid;
4185 } 4113 if (peer_sid == SECSID_NULL)
4186 if (peer_sid == SECSID_NULL) { 4114 return -ENOPROTOOPT;
4187 err = -ENOPROTOOPT;
4188 goto out;
4189 }
4190 4115
4191 err = security_sid_to_context(peer_sid, &scontext, &scontext_len); 4116 err = security_sid_to_context(peer_sid, &scontext, &scontext_len);
4192
4193 if (err) 4117 if (err)
4194 goto out; 4118 return err;
4195 4119
4196 if (scontext_len > len) { 4120 if (scontext_len > len) {
4197 err = -ERANGE; 4121 err = -ERANGE;
@@ -4204,9 +4128,7 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
4204out_len: 4128out_len:
4205 if (put_user(scontext_len, optlen)) 4129 if (put_user(scontext_len, optlen))
4206 err = -EFAULT; 4130 err = -EFAULT;
4207
4208 kfree(scontext); 4131 kfree(scontext);
4209out:
4210 return err; 4132 return err;
4211} 4133}
4212 4134
@@ -4238,12 +4160,27 @@ out:
4238 4160
4239static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority) 4161static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
4240{ 4162{
4241 return sk_alloc_security(sk, family, priority); 4163 struct sk_security_struct *sksec;
4164
4165 sksec = kzalloc(sizeof(*sksec), priority);
4166 if (!sksec)
4167 return -ENOMEM;
4168
4169 sksec->peer_sid = SECINITSID_UNLABELED;
4170 sksec->sid = SECINITSID_UNLABELED;
4171 selinux_netlbl_sk_security_reset(sksec);
4172 sk->sk_security = sksec;
4173
4174 return 0;
4242} 4175}
4243 4176
4244static void selinux_sk_free_security(struct sock *sk) 4177static void selinux_sk_free_security(struct sock *sk)
4245{ 4178{
4246 sk_free_security(sk); 4179 struct sk_security_struct *sksec = sk->sk_security;
4180
4181 sk->sk_security = NULL;
4182 selinux_netlbl_sk_security_free(sksec);
4183 kfree(sksec);
4247} 4184}
4248 4185
4249static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) 4186static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
@@ -4403,8 +4340,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
4403 int err = 0; 4340 int err = 0;
4404 u32 perm; 4341 u32 perm;
4405 struct nlmsghdr *nlh; 4342 struct nlmsghdr *nlh;
4406 struct socket *sock = sk->sk_socket; 4343 struct sk_security_struct *sksec = sk->sk_security;
4407 struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
4408 4344
4409 if (skb->len < NLMSG_SPACE(0)) { 4345 if (skb->len < NLMSG_SPACE(0)) {
4410 err = -EINVAL; 4346 err = -EINVAL;
@@ -4412,13 +4348,13 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
4412 } 4348 }
4413 nlh = nlmsg_hdr(skb); 4349 nlh = nlmsg_hdr(skb);
4414 4350
4415 err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm); 4351 err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm);
4416 if (err) { 4352 if (err) {
4417 if (err == -EINVAL) { 4353 if (err == -EINVAL) {
4418 audit_log(current->audit_context, GFP_KERNEL, AUDIT_SELINUX_ERR, 4354 audit_log(current->audit_context, GFP_KERNEL, AUDIT_SELINUX_ERR,
4419 "SELinux: unrecognized netlink message" 4355 "SELinux: unrecognized netlink message"
4420 " type=%hu for sclass=%hu\n", 4356 " type=%hu for sclass=%hu\n",
4421 nlh->nlmsg_type, isec->sclass); 4357 nlh->nlmsg_type, sksec->sclass);
4422 if (!selinux_enforcing || security_get_allow_unknown()) 4358 if (!selinux_enforcing || security_get_allow_unknown())
4423 err = 0; 4359 err = 0;
4424 } 4360 }
@@ -4429,7 +4365,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
4429 goto out; 4365 goto out;
4430 } 4366 }
4431 4367
4432 err = socket_has_perm(current, sock, perm); 4368 err = sock_has_perm(current, sk, perm);
4433out: 4369out:
4434 return err; 4370 return err;
4435} 4371}