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 5c9f25ba1c95..9b40f4c0ac70 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
@@ -2559,8 +2510,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2559 char **name, void **value, 2510 char **name, void **value,
2560 size_t *len) 2511 size_t *len)
2561{ 2512{
2562 const struct cred *cred = current_cred(); 2513 const struct task_security_struct *tsec = current_security();
2563 const struct task_security_struct *tsec = cred->security;
2564 struct inode_security_struct *dsec; 2514 struct inode_security_struct *dsec;
2565 struct superblock_security_struct *sbsec; 2515 struct superblock_security_struct *sbsec;
2566 u32 sid, newsid, clen; 2516 u32 sid, newsid, clen;
@@ -2676,14 +2626,26 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na
2676static int selinux_inode_permission(struct inode *inode, int mask) 2626static int selinux_inode_permission(struct inode *inode, int mask)
2677{ 2627{
2678 const struct cred *cred = current_cred(); 2628 const struct cred *cred = current_cred();
2629 struct common_audit_data ad;
2630 u32 perms;
2631 bool from_access;
2679 2632
2680 if (!mask) { 2633 from_access = mask & MAY_ACCESS;
2681 /* No permission to check. Existence test. */ 2634 mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND);
2635
2636 /* No permission to check. Existence test. */
2637 if (!mask)
2682 return 0; 2638 return 0;
2683 }
2684 2639
2685 return inode_has_perm(cred, inode, 2640 COMMON_AUDIT_DATA_INIT(&ad, FS);
2686 file_mask_to_av(inode->i_mode, mask), NULL); 2641 ad.u.fs.inode = inode;
2642
2643 if (from_access)
2644 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS;
2645
2646 perms = file_mask_to_av(inode->i_mode, mask);
2647
2648 return inode_has_perm(cred, inode, perms, &ad);
2687} 2649}
2688 2650
2689static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) 2651static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
@@ -3671,71 +3633,54 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
3671} 3633}
3672 3634
3673/* socket security operations */ 3635/* socket security operations */
3674static int socket_has_perm(struct task_struct *task, struct socket *sock, 3636
3675 u32 perms) 3637static u32 socket_sockcreate_sid(const struct task_security_struct *tsec)
3676{ 3638{
3677 struct inode_security_struct *isec; 3639 return tsec->sockcreate_sid ? : tsec->sid;
3678 struct common_audit_data ad; 3640}
3679 u32 sid;
3680 int err = 0;
3681 3641
3682 isec = SOCK_INODE(sock)->i_security; 3642static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms)
3643{
3644 struct sk_security_struct *sksec = sk->sk_security;
3645 struct common_audit_data ad;
3646 u32 tsid = task_sid(task);
3683 3647
3684 if (isec->sid == SECINITSID_KERNEL) 3648 if (sksec->sid == SECINITSID_KERNEL)
3685 goto out; 3649 return 0;
3686 sid = task_sid(task);
3687 3650
3688 COMMON_AUDIT_DATA_INIT(&ad, NET); 3651 COMMON_AUDIT_DATA_INIT(&ad, NET);
3689 ad.u.net.sk = sock->sk; 3652 ad.u.net.sk = sk;
3690 err = avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);
3691 3653
3692out: 3654 return avc_has_perm(tsid, sksec->sid, sksec->sclass, perms, &ad);
3693 return err;
3694} 3655}
3695 3656
3696static int selinux_socket_create(int family, int type, 3657static int selinux_socket_create(int family, int type,
3697 int protocol, int kern) 3658 int protocol, int kern)
3698{ 3659{
3699 const struct cred *cred = current_cred(); 3660 const struct task_security_struct *tsec = current_security();
3700 const struct task_security_struct *tsec = cred->security; 3661 u32 newsid;
3701 u32 sid, newsid;
3702 u16 secclass; 3662 u16 secclass;
3703 int err = 0;
3704 3663
3705 if (kern) 3664 if (kern)
3706 goto out; 3665 return 0;
3707
3708 sid = tsec->sid;
3709 newsid = tsec->sockcreate_sid ?: sid;
3710 3666
3667 newsid = socket_sockcreate_sid(tsec);
3711 secclass = socket_type_to_security_class(family, type, protocol); 3668 secclass = socket_type_to_security_class(family, type, protocol);
3712 err = avc_has_perm(sid, newsid, secclass, SOCKET__CREATE, NULL); 3669 return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
3713
3714out:
3715 return err;
3716} 3670}
3717 3671
3718static int selinux_socket_post_create(struct socket *sock, int family, 3672static int selinux_socket_post_create(struct socket *sock, int family,
3719 int type, int protocol, int kern) 3673 int type, int protocol, int kern)
3720{ 3674{
3721 const struct cred *cred = current_cred(); 3675 const struct task_security_struct *tsec = current_security();
3722 const struct task_security_struct *tsec = cred->security; 3676 struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
3723 struct inode_security_struct *isec;
3724 struct sk_security_struct *sksec; 3677 struct sk_security_struct *sksec;
3725 u32 sid, newsid;
3726 int err = 0; 3678 int err = 0;
3727 3679
3728 sid = tsec->sid;
3729 newsid = tsec->sockcreate_sid;
3730
3731 isec = SOCK_INODE(sock)->i_security;
3732
3733 if (kern) 3680 if (kern)
3734 isec->sid = SECINITSID_KERNEL; 3681 isec->sid = SECINITSID_KERNEL;
3735 else if (newsid)
3736 isec->sid = newsid;
3737 else 3682 else
3738 isec->sid = sid; 3683 isec->sid = socket_sockcreate_sid(tsec);
3739 3684
3740 isec->sclass = socket_type_to_security_class(family, type, protocol); 3685 isec->sclass = socket_type_to_security_class(family, type, protocol);
3741 isec->initialized = 1; 3686 isec->initialized = 1;
@@ -3756,10 +3701,11 @@ static int selinux_socket_post_create(struct socket *sock, int family,
3756 3701
3757static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) 3702static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
3758{ 3703{
3704 struct sock *sk = sock->sk;
3759 u16 family; 3705 u16 family;
3760 int err; 3706 int err;
3761 3707
3762 err = socket_has_perm(current, sock, SOCKET__BIND); 3708 err = sock_has_perm(current, sk, SOCKET__BIND);
3763 if (err) 3709 if (err)
3764 goto out; 3710 goto out;
3765 3711
@@ -3768,19 +3714,16 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
3768 * Multiple address binding for SCTP is not supported yet: we just 3714 * Multiple address binding for SCTP is not supported yet: we just
3769 * check the first address now. 3715 * check the first address now.
3770 */ 3716 */
3771 family = sock->sk->sk_family; 3717 family = sk->sk_family;
3772 if (family == PF_INET || family == PF_INET6) { 3718 if (family == PF_INET || family == PF_INET6) {
3773 char *addrp; 3719 char *addrp;
3774 struct inode_security_struct *isec; 3720 struct sk_security_struct *sksec = sk->sk_security;
3775 struct common_audit_data ad; 3721 struct common_audit_data ad;
3776 struct sockaddr_in *addr4 = NULL; 3722 struct sockaddr_in *addr4 = NULL;
3777 struct sockaddr_in6 *addr6 = NULL; 3723 struct sockaddr_in6 *addr6 = NULL;
3778 unsigned short snum; 3724 unsigned short snum;
3779 struct sock *sk = sock->sk;
3780 u32 sid, node_perm; 3725 u32 sid, node_perm;
3781 3726
3782 isec = SOCK_INODE(sock)->i_security;
3783
3784 if (family == PF_INET) { 3727 if (family == PF_INET) {
3785 addr4 = (struct sockaddr_in *)address; 3728 addr4 = (struct sockaddr_in *)address;
3786 snum = ntohs(addr4->sin_port); 3729 snum = ntohs(addr4->sin_port);
@@ -3804,15 +3747,15 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
3804 COMMON_AUDIT_DATA_INIT(&ad, NET); 3747 COMMON_AUDIT_DATA_INIT(&ad, NET);
3805 ad.u.net.sport = htons(snum); 3748 ad.u.net.sport = htons(snum);
3806 ad.u.net.family = family; 3749 ad.u.net.family = family;
3807 err = avc_has_perm(isec->sid, sid, 3750 err = avc_has_perm(sksec->sid, sid,
3808 isec->sclass, 3751 sksec->sclass,
3809 SOCKET__NAME_BIND, &ad); 3752 SOCKET__NAME_BIND, &ad);
3810 if (err) 3753 if (err)
3811 goto out; 3754 goto out;
3812 } 3755 }
3813 } 3756 }
3814 3757
3815 switch (isec->sclass) { 3758 switch (sksec->sclass) {
3816 case SECCLASS_TCP_SOCKET: 3759 case SECCLASS_TCP_SOCKET:
3817 node_perm = TCP_SOCKET__NODE_BIND; 3760 node_perm = TCP_SOCKET__NODE_BIND;
3818 break; 3761 break;
@@ -3843,8 +3786,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
3843 else 3786 else
3844 ipv6_addr_copy(&ad.u.net.v6info.saddr, &addr6->sin6_addr); 3787 ipv6_addr_copy(&ad.u.net.v6info.saddr, &addr6->sin6_addr);
3845 3788
3846 err = avc_has_perm(isec->sid, sid, 3789 err = avc_has_perm(sksec->sid, sid,
3847 isec->sclass, node_perm, &ad); 3790 sksec->sclass, node_perm, &ad);
3848 if (err) 3791 if (err)
3849 goto out; 3792 goto out;
3850 } 3793 }
@@ -3855,19 +3798,18 @@ out:
3855static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen) 3798static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen)
3856{ 3799{
3857 struct sock *sk = sock->sk; 3800 struct sock *sk = sock->sk;
3858 struct inode_security_struct *isec; 3801 struct sk_security_struct *sksec = sk->sk_security;
3859 int err; 3802 int err;
3860 3803
3861 err = socket_has_perm(current, sock, SOCKET__CONNECT); 3804 err = sock_has_perm(current, sk, SOCKET__CONNECT);
3862 if (err) 3805 if (err)
3863 return err; 3806 return err;
3864 3807
3865 /* 3808 /*
3866 * If a TCP or DCCP socket, check name_connect permission for the port. 3809 * If a TCP or DCCP socket, check name_connect permission for the port.
3867 */ 3810 */
3868 isec = SOCK_INODE(sock)->i_security; 3811 if (sksec->sclass == SECCLASS_TCP_SOCKET ||
3869 if (isec->sclass == SECCLASS_TCP_SOCKET || 3812 sksec->sclass == SECCLASS_DCCP_SOCKET) {
3870 isec->sclass == SECCLASS_DCCP_SOCKET) {
3871 struct common_audit_data ad; 3813 struct common_audit_data ad;
3872 struct sockaddr_in *addr4 = NULL; 3814 struct sockaddr_in *addr4 = NULL;
3873 struct sockaddr_in6 *addr6 = NULL; 3815 struct sockaddr_in6 *addr6 = NULL;
@@ -3890,13 +3832,13 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
3890 if (err) 3832 if (err)
3891 goto out; 3833 goto out;
3892 3834
3893 perm = (isec->sclass == SECCLASS_TCP_SOCKET) ? 3835 perm = (sksec->sclass == SECCLASS_TCP_SOCKET) ?
3894 TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; 3836 TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT;
3895 3837
3896 COMMON_AUDIT_DATA_INIT(&ad, NET); 3838 COMMON_AUDIT_DATA_INIT(&ad, NET);
3897 ad.u.net.dport = htons(snum); 3839 ad.u.net.dport = htons(snum);
3898 ad.u.net.family = sk->sk_family; 3840 ad.u.net.family = sk->sk_family;
3899 err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad); 3841 err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad);
3900 if (err) 3842 if (err)
3901 goto out; 3843 goto out;
3902 } 3844 }
@@ -3909,7 +3851,7 @@ out:
3909 3851
3910static int selinux_socket_listen(struct socket *sock, int backlog) 3852static int selinux_socket_listen(struct socket *sock, int backlog)
3911{ 3853{
3912 return socket_has_perm(current, sock, SOCKET__LISTEN); 3854 return sock_has_perm(current, sock->sk, SOCKET__LISTEN);
3913} 3855}
3914 3856
3915static int selinux_socket_accept(struct socket *sock, struct socket *newsock) 3857static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
@@ -3918,7 +3860,7 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
3918 struct inode_security_struct *isec; 3860 struct inode_security_struct *isec;
3919 struct inode_security_struct *newisec; 3861 struct inode_security_struct *newisec;
3920 3862
3921 err = socket_has_perm(current, sock, SOCKET__ACCEPT); 3863 err = sock_has_perm(current, sock->sk, SOCKET__ACCEPT);
3922 if (err) 3864 if (err)
3923 return err; 3865 return err;
3924 3866
@@ -3935,30 +3877,30 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
3935static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, 3877static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
3936 int size) 3878 int size)
3937{ 3879{
3938 return socket_has_perm(current, sock, SOCKET__WRITE); 3880 return sock_has_perm(current, sock->sk, SOCKET__WRITE);
3939} 3881}
3940 3882
3941static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg, 3883static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
3942 int size, int flags) 3884 int size, int flags)
3943{ 3885{
3944 return socket_has_perm(current, sock, SOCKET__READ); 3886 return sock_has_perm(current, sock->sk, SOCKET__READ);
3945} 3887}
3946 3888
3947static int selinux_socket_getsockname(struct socket *sock) 3889static int selinux_socket_getsockname(struct socket *sock)
3948{ 3890{
3949 return socket_has_perm(current, sock, SOCKET__GETATTR); 3891 return sock_has_perm(current, sock->sk, SOCKET__GETATTR);
3950} 3892}
3951 3893
3952static int selinux_socket_getpeername(struct socket *sock) 3894static int selinux_socket_getpeername(struct socket *sock)
3953{ 3895{
3954 return socket_has_perm(current, sock, SOCKET__GETATTR); 3896 return sock_has_perm(current, sock->sk, SOCKET__GETATTR);
3955} 3897}
3956 3898
3957static int selinux_socket_setsockopt(struct socket *sock, int level, int optname) 3899static int selinux_socket_setsockopt(struct socket *sock, int level, int optname)
3958{ 3900{
3959 int err; 3901 int err;
3960 3902
3961 err = socket_has_perm(current, sock, SOCKET__SETOPT); 3903 err = sock_has_perm(current, sock->sk, SOCKET__SETOPT);
3962 if (err) 3904 if (err)
3963 return err; 3905 return err;
3964 3906
@@ -3968,68 +3910,58 @@ static int selinux_socket_setsockopt(struct socket *sock, int level, int optname
3968static int selinux_socket_getsockopt(struct socket *sock, int level, 3910static int selinux_socket_getsockopt(struct socket *sock, int level,
3969 int optname) 3911 int optname)
3970{ 3912{
3971 return socket_has_perm(current, sock, SOCKET__GETOPT); 3913 return sock_has_perm(current, sock->sk, SOCKET__GETOPT);
3972} 3914}
3973 3915
3974static int selinux_socket_shutdown(struct socket *sock, int how) 3916static int selinux_socket_shutdown(struct socket *sock, int how)
3975{ 3917{
3976 return socket_has_perm(current, sock, SOCKET__SHUTDOWN); 3918 return sock_has_perm(current, sock->sk, SOCKET__SHUTDOWN);
3977} 3919}
3978 3920
3979static int selinux_socket_unix_stream_connect(struct socket *sock, 3921static int selinux_socket_unix_stream_connect(struct socket *sock,
3980 struct socket *other, 3922 struct socket *other,
3981 struct sock *newsk) 3923 struct sock *newsk)
3982{ 3924{
3983 struct sk_security_struct *sksec; 3925 struct sk_security_struct *sksec_sock = sock->sk->sk_security;
3984 struct inode_security_struct *isec; 3926 struct sk_security_struct *sksec_other = other->sk->sk_security;
3985 struct inode_security_struct *other_isec; 3927 struct sk_security_struct *sksec_new = newsk->sk_security;
3986 struct common_audit_data ad; 3928 struct common_audit_data ad;
3987 int err; 3929 int err;
3988 3930
3989 isec = SOCK_INODE(sock)->i_security;
3990 other_isec = SOCK_INODE(other)->i_security;
3991
3992 COMMON_AUDIT_DATA_INIT(&ad, NET); 3931 COMMON_AUDIT_DATA_INIT(&ad, NET);
3993 ad.u.net.sk = other->sk; 3932 ad.u.net.sk = other->sk;
3994 3933
3995 err = avc_has_perm(isec->sid, other_isec->sid, 3934 err = avc_has_perm(sksec_sock->sid, sksec_other->sid,
3996 isec->sclass, 3935 sksec_other->sclass,
3997 UNIX_STREAM_SOCKET__CONNECTTO, &ad); 3936 UNIX_STREAM_SOCKET__CONNECTTO, &ad);
3998 if (err) 3937 if (err)
3999 return err; 3938 return err;
4000 3939
4001 /* connecting socket */
4002 sksec = sock->sk->sk_security;
4003 sksec->peer_sid = other_isec->sid;
4004
4005 /* server child socket */ 3940 /* server child socket */
4006 sksec = newsk->sk_security; 3941 sksec_new->peer_sid = sksec_sock->sid;
4007 sksec->peer_sid = isec->sid; 3942 err = security_sid_mls_copy(sksec_other->sid, sksec_sock->sid,
4008 err = security_sid_mls_copy(other_isec->sid, sksec->peer_sid, &sksec->sid); 3943 &sksec_new->sid);
3944 if (err)
3945 return err;
4009 3946
4010 return err; 3947 /* connecting socket */
3948 sksec_sock->peer_sid = sksec_new->sid;
3949
3950 return 0;
4011} 3951}
4012 3952
4013static int selinux_socket_unix_may_send(struct socket *sock, 3953static int selinux_socket_unix_may_send(struct socket *sock,
4014 struct socket *other) 3954 struct socket *other)
4015{ 3955{
4016 struct inode_security_struct *isec; 3956 struct sk_security_struct *ssec = sock->sk->sk_security;
4017 struct inode_security_struct *other_isec; 3957 struct sk_security_struct *osec = other->sk->sk_security;
4018 struct common_audit_data ad; 3958 struct common_audit_data ad;
4019 int err;
4020
4021 isec = SOCK_INODE(sock)->i_security;
4022 other_isec = SOCK_INODE(other)->i_security;
4023 3959
4024 COMMON_AUDIT_DATA_INIT(&ad, NET); 3960 COMMON_AUDIT_DATA_INIT(&ad, NET);
4025 ad.u.net.sk = other->sk; 3961 ad.u.net.sk = other->sk;
4026 3962
4027 err = avc_has_perm(isec->sid, other_isec->sid, 3963 return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
4028 isec->sclass, SOCKET__SENDTO, &ad); 3964 &ad);
4029 if (err)
4030 return err;
4031
4032 return 0;
4033} 3965}
4034 3966
4035static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family, 3967static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family,
@@ -4168,26 +4100,18 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
4168 int err = 0; 4100 int err = 0;
4169 char *scontext; 4101 char *scontext;
4170 u32 scontext_len; 4102 u32 scontext_len;
4171 struct sk_security_struct *sksec; 4103 struct sk_security_struct *sksec = sock->sk->sk_security;
4172 struct inode_security_struct *isec;
4173 u32 peer_sid = SECSID_NULL; 4104 u32 peer_sid = SECSID_NULL;
4174 4105
4175 isec = SOCK_INODE(sock)->i_security; 4106 if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
4176 4107 sksec->sclass == SECCLASS_TCP_SOCKET)
4177 if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
4178 isec->sclass == SECCLASS_TCP_SOCKET) {
4179 sksec = sock->sk->sk_security;
4180 peer_sid = sksec->peer_sid; 4108 peer_sid = sksec->peer_sid;
4181 } 4109 if (peer_sid == SECSID_NULL)
4182 if (peer_sid == SECSID_NULL) { 4110 return -ENOPROTOOPT;
4183 err = -ENOPROTOOPT;
4184 goto out;
4185 }
4186 4111
4187 err = security_sid_to_context(peer_sid, &scontext, &scontext_len); 4112 err = security_sid_to_context(peer_sid, &scontext, &scontext_len);
4188
4189 if (err) 4113 if (err)
4190 goto out; 4114 return err;
4191 4115
4192 if (scontext_len > len) { 4116 if (scontext_len > len) {
4193 err = -ERANGE; 4117 err = -ERANGE;
@@ -4200,9 +4124,7 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
4200out_len: 4124out_len:
4201 if (put_user(scontext_len, optlen)) 4125 if (put_user(scontext_len, optlen))
4202 err = -EFAULT; 4126 err = -EFAULT;
4203
4204 kfree(scontext); 4127 kfree(scontext);
4205out:
4206 return err; 4128 return err;
4207} 4129}
4208 4130
@@ -4234,12 +4156,27 @@ out:
4234 4156
4235static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority) 4157static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
4236{ 4158{
4237 return sk_alloc_security(sk, family, priority); 4159 struct sk_security_struct *sksec;
4160
4161 sksec = kzalloc(sizeof(*sksec), priority);
4162 if (!sksec)
4163 return -ENOMEM;
4164
4165 sksec->peer_sid = SECINITSID_UNLABELED;
4166 sksec->sid = SECINITSID_UNLABELED;
4167 selinux_netlbl_sk_security_reset(sksec);
4168 sk->sk_security = sksec;
4169
4170 return 0;
4238} 4171}
4239 4172
4240static void selinux_sk_free_security(struct sock *sk) 4173static void selinux_sk_free_security(struct sock *sk)
4241{ 4174{
4242 sk_free_security(sk); 4175 struct sk_security_struct *sksec = sk->sk_security;
4176
4177 sk->sk_security = NULL;
4178 selinux_netlbl_sk_security_free(sksec);
4179 kfree(sksec);
4243} 4180}
4244 4181
4245static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) 4182static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
@@ -4399,8 +4336,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
4399 int err = 0; 4336 int err = 0;
4400 u32 perm; 4337 u32 perm;
4401 struct nlmsghdr *nlh; 4338 struct nlmsghdr *nlh;
4402 struct socket *sock = sk->sk_socket; 4339 struct sk_security_struct *sksec = sk->sk_security;
4403 struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
4404 4340
4405 if (skb->len < NLMSG_SPACE(0)) { 4341 if (skb->len < NLMSG_SPACE(0)) {
4406 err = -EINVAL; 4342 err = -EINVAL;
@@ -4408,13 +4344,13 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
4408 } 4344 }
4409 nlh = nlmsg_hdr(skb); 4345 nlh = nlmsg_hdr(skb);
4410 4346
4411 err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm); 4347 err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm);
4412 if (err) { 4348 if (err) {
4413 if (err == -EINVAL) { 4349 if (err == -EINVAL) {
4414 audit_log(current->audit_context, GFP_KERNEL, AUDIT_SELINUX_ERR, 4350 audit_log(current->audit_context, GFP_KERNEL, AUDIT_SELINUX_ERR,
4415 "SELinux: unrecognized netlink message" 4351 "SELinux: unrecognized netlink message"
4416 " type=%hu for sclass=%hu\n", 4352 " type=%hu for sclass=%hu\n",
4417 nlh->nlmsg_type, isec->sclass); 4353 nlh->nlmsg_type, sksec->sclass);
4418 if (!selinux_enforcing || security_get_allow_unknown()) 4354 if (!selinux_enforcing || security_get_allow_unknown())
4419 err = 0; 4355 err = 0;
4420 } 4356 }
@@ -4425,7 +4361,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
4425 goto out; 4361 goto out;
4426 } 4362 }
4427 4363
4428 err = socket_has_perm(current, sock, perm); 4364 err = sock_has_perm(current, sk, perm);
4429out: 4365out:
4430 return err; 4366 return err;
4431} 4367}