aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2010-08-15 01:06:31 -0400
committerLen Brown <len.brown@intel.com>2010-08-15 01:06:31 -0400
commit95ee46aa8698f2000647dfb362400fadbb5807cf (patch)
treee5a05c7297f997e191c73091934e42e3195c0e40 /security/selinux/hooks.c
parentcfa806f059801dbe7e435745eb2e187c8bfe1e7f (diff)
parent92fa5bd9a946b6e7aab6764e7312e4e3d9bed295 (diff)
Merge branch 'linus' into release
Conflicts: drivers/acpi/debug.c Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c304
1 files changed, 122 insertions, 182 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 5c9f25ba1c95..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
@@ -2333,12 +2284,15 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
2333 rc = avc_has_perm(new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS, 2284 rc = avc_has_perm(new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS,
2334 PROCESS__RLIMITINH, NULL); 2285 PROCESS__RLIMITINH, NULL);
2335 if (rc) { 2286 if (rc) {
2287 /* protect against do_prlimit() */
2288 task_lock(current);
2336 for (i = 0; i < RLIM_NLIMITS; i++) { 2289 for (i = 0; i < RLIM_NLIMITS; i++) {
2337 rlim = current->signal->rlim + i; 2290 rlim = current->signal->rlim + i;
2338 initrlim = init_task.signal->rlim + i; 2291 initrlim = init_task.signal->rlim + i;
2339 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur); 2292 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
2340 } 2293 }
2341 update_rlimit_cpu(current->signal->rlim[RLIMIT_CPU].rlim_cur); 2294 task_unlock(current);
2295 update_rlimit_cpu(current, rlimit(RLIMIT_CPU));
2342 } 2296 }
2343} 2297}
2344 2298
@@ -2559,8 +2513,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2559 char **name, void **value, 2513 char **name, void **value,
2560 size_t *len) 2514 size_t *len)
2561{ 2515{
2562 const struct cred *cred = current_cred(); 2516 const struct task_security_struct *tsec = current_security();
2563 const struct task_security_struct *tsec = cred->security;
2564 struct inode_security_struct *dsec; 2517 struct inode_security_struct *dsec;
2565 struct superblock_security_struct *sbsec; 2518 struct superblock_security_struct *sbsec;
2566 u32 sid, newsid, clen; 2519 u32 sid, newsid, clen;
@@ -2676,14 +2629,26 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na
2676static int selinux_inode_permission(struct inode *inode, int mask) 2629static int selinux_inode_permission(struct inode *inode, int mask)
2677{ 2630{
2678 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;
2679 2635
2680 if (!mask) { 2636 from_access = mask & MAY_ACCESS;
2681 /* 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)
2682 return 0; 2641 return 0;
2683 }
2684 2642
2685 return inode_has_perm(cred, inode, 2643 COMMON_AUDIT_DATA_INIT(&ad, FS);
2686 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);
2687} 2652}
2688 2653
2689static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) 2654static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
@@ -3371,16 +3336,17 @@ static int selinux_task_getioprio(struct task_struct *p)
3371 return current_has_perm(p, PROCESS__GETSCHED); 3336 return current_has_perm(p, PROCESS__GETSCHED);
3372} 3337}
3373 3338
3374static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) 3339static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
3340 struct rlimit *new_rlim)
3375{ 3341{
3376 struct rlimit *old_rlim = current->signal->rlim + resource; 3342 struct rlimit *old_rlim = p->signal->rlim + resource;
3377 3343
3378 /* Control the ability to change the hard limit (whether 3344 /* Control the ability to change the hard limit (whether
3379 lowering or raising it), so that the hard limit can 3345 lowering or raising it), so that the hard limit can
3380 later be used as a safe reset point for the soft limit 3346 later be used as a safe reset point for the soft limit
3381 upon context transitions. See selinux_bprm_committing_creds. */ 3347 upon context transitions. See selinux_bprm_committing_creds. */
3382 if (old_rlim->rlim_max != new_rlim->rlim_max) 3348 if (old_rlim->rlim_max != new_rlim->rlim_max)
3383 return current_has_perm(current, PROCESS__SETRLIMIT); 3349 return current_has_perm(p, PROCESS__SETRLIMIT);
3384 3350
3385 return 0; 3351 return 0;
3386} 3352}
@@ -3671,71 +3637,54 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
3671} 3637}
3672 3638
3673/* socket security operations */ 3639/* socket security operations */
3674static int socket_has_perm(struct task_struct *task, struct socket *sock, 3640
3675 u32 perms) 3641static u32 socket_sockcreate_sid(const struct task_security_struct *tsec)
3676{ 3642{
3677 struct inode_security_struct *isec; 3643 return tsec->sockcreate_sid ? : tsec->sid;
3678 struct common_audit_data ad; 3644}
3679 u32 sid;
3680 int err = 0;
3681 3645
3682 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);
3683 3651
3684 if (isec->sid == SECINITSID_KERNEL) 3652 if (sksec->sid == SECINITSID_KERNEL)
3685 goto out; 3653 return 0;
3686 sid = task_sid(task);
3687 3654
3688 COMMON_AUDIT_DATA_INIT(&ad, NET); 3655 COMMON_AUDIT_DATA_INIT(&ad, NET);
3689 ad.u.net.sk = sock->sk; 3656 ad.u.net.sk = sk;
3690 err = avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad);
3691 3657
3692out: 3658 return avc_has_perm(tsid, sksec->sid, sksec->sclass, perms, &ad);
3693 return err;
3694} 3659}
3695 3660
3696static int selinux_socket_create(int family, int type, 3661static int selinux_socket_create(int family, int type,
3697 int protocol, int kern) 3662 int protocol, int kern)
3698{ 3663{
3699 const struct cred *cred = current_cred(); 3664 const struct task_security_struct *tsec = current_security();
3700 const struct task_security_struct *tsec = cred->security; 3665 u32 newsid;
3701 u32 sid, newsid;
3702 u16 secclass; 3666 u16 secclass;
3703 int err = 0;
3704 3667
3705 if (kern) 3668 if (kern)
3706 goto out; 3669 return 0;
3707
3708 sid = tsec->sid;
3709 newsid = tsec->sockcreate_sid ?: sid;
3710 3670
3671 newsid = socket_sockcreate_sid(tsec);
3711 secclass = socket_type_to_security_class(family, type, protocol); 3672 secclass = socket_type_to_security_class(family, type, protocol);
3712 err = avc_has_perm(sid, newsid, secclass, SOCKET__CREATE, NULL); 3673 return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
3713
3714out:
3715 return err;
3716} 3674}
3717 3675
3718static int selinux_socket_post_create(struct socket *sock, int family, 3676static int selinux_socket_post_create(struct socket *sock, int family,
3719 int type, int protocol, int kern) 3677 int type, int protocol, int kern)
3720{ 3678{
3721 const struct cred *cred = current_cred(); 3679 const struct task_security_struct *tsec = current_security();
3722 const struct task_security_struct *tsec = cred->security; 3680 struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
3723 struct inode_security_struct *isec;
3724 struct sk_security_struct *sksec; 3681 struct sk_security_struct *sksec;
3725 u32 sid, newsid;
3726 int err = 0; 3682 int err = 0;
3727 3683
3728 sid = tsec->sid;
3729 newsid = tsec->sockcreate_sid;
3730
3731 isec = SOCK_INODE(sock)->i_security;
3732
3733 if (kern) 3684 if (kern)
3734 isec->sid = SECINITSID_KERNEL; 3685 isec->sid = SECINITSID_KERNEL;
3735 else if (newsid)
3736 isec->sid = newsid;
3737 else 3686 else
3738 isec->sid = sid; 3687 isec->sid = socket_sockcreate_sid(tsec);
3739 3688
3740 isec->sclass = socket_type_to_security_class(family, type, protocol); 3689 isec->sclass = socket_type_to_security_class(family, type, protocol);
3741 isec->initialized = 1; 3690 isec->initialized = 1;
@@ -3756,10 +3705,11 @@ static int selinux_socket_post_create(struct socket *sock, int family,
3756 3705
3757static 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)
3758{ 3707{
3708 struct sock *sk = sock->sk;
3759 u16 family; 3709 u16 family;
3760 int err; 3710 int err;
3761 3711
3762 err = socket_has_perm(current, sock, SOCKET__BIND); 3712 err = sock_has_perm(current, sk, SOCKET__BIND);
3763 if (err) 3713 if (err)
3764 goto out; 3714 goto out;
3765 3715
@@ -3768,19 +3718,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 3718 * Multiple address binding for SCTP is not supported yet: we just
3769 * check the first address now. 3719 * check the first address now.
3770 */ 3720 */
3771 family = sock->sk->sk_family; 3721 family = sk->sk_family;
3772 if (family == PF_INET || family == PF_INET6) { 3722 if (family == PF_INET || family == PF_INET6) {
3773 char *addrp; 3723 char *addrp;
3774 struct inode_security_struct *isec; 3724 struct sk_security_struct *sksec = sk->sk_security;
3775 struct common_audit_data ad; 3725 struct common_audit_data ad;
3776 struct sockaddr_in *addr4 = NULL; 3726 struct sockaddr_in *addr4 = NULL;
3777 struct sockaddr_in6 *addr6 = NULL; 3727 struct sockaddr_in6 *addr6 = NULL;
3778 unsigned short snum; 3728 unsigned short snum;
3779 struct sock *sk = sock->sk;
3780 u32 sid, node_perm; 3729 u32 sid, node_perm;
3781 3730
3782 isec = SOCK_INODE(sock)->i_security;
3783
3784 if (family == PF_INET) { 3731 if (family == PF_INET) {
3785 addr4 = (struct sockaddr_in *)address; 3732 addr4 = (struct sockaddr_in *)address;
3786 snum = ntohs(addr4->sin_port); 3733 snum = ntohs(addr4->sin_port);
@@ -3804,15 +3751,15 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
3804 COMMON_AUDIT_DATA_INIT(&ad, NET); 3751 COMMON_AUDIT_DATA_INIT(&ad, NET);
3805 ad.u.net.sport = htons(snum); 3752 ad.u.net.sport = htons(snum);
3806 ad.u.net.family = family; 3753 ad.u.net.family = family;
3807 err = avc_has_perm(isec->sid, sid, 3754 err = avc_has_perm(sksec->sid, sid,
3808 isec->sclass, 3755 sksec->sclass,
3809 SOCKET__NAME_BIND, &ad); 3756 SOCKET__NAME_BIND, &ad);
3810 if (err) 3757 if (err)
3811 goto out; 3758 goto out;
3812 } 3759 }
3813 } 3760 }
3814 3761
3815 switch (isec->sclass) { 3762 switch (sksec->sclass) {
3816 case SECCLASS_TCP_SOCKET: 3763 case SECCLASS_TCP_SOCKET:
3817 node_perm = TCP_SOCKET__NODE_BIND; 3764 node_perm = TCP_SOCKET__NODE_BIND;
3818 break; 3765 break;
@@ -3843,8 +3790,8 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
3843 else 3790 else
3844 ipv6_addr_copy(&ad.u.net.v6info.saddr, &addr6->sin6_addr); 3791 ipv6_addr_copy(&ad.u.net.v6info.saddr, &addr6->sin6_addr);
3845 3792
3846 err = avc_has_perm(isec->sid, sid, 3793 err = avc_has_perm(sksec->sid, sid,
3847 isec->sclass, node_perm, &ad); 3794 sksec->sclass, node_perm, &ad);
3848 if (err) 3795 if (err)
3849 goto out; 3796 goto out;
3850 } 3797 }
@@ -3855,19 +3802,18 @@ out:
3855static 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)
3856{ 3803{
3857 struct sock *sk = sock->sk; 3804 struct sock *sk = sock->sk;
3858 struct inode_security_struct *isec; 3805 struct sk_security_struct *sksec = sk->sk_security;
3859 int err; 3806 int err;
3860 3807
3861 err = socket_has_perm(current, sock, SOCKET__CONNECT); 3808 err = sock_has_perm(current, sk, SOCKET__CONNECT);
3862 if (err) 3809 if (err)
3863 return err; 3810 return err;
3864 3811
3865 /* 3812 /*
3866 * 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.
3867 */ 3814 */
3868 isec = SOCK_INODE(sock)->i_security; 3815 if (sksec->sclass == SECCLASS_TCP_SOCKET ||
3869 if (isec->sclass == SECCLASS_TCP_SOCKET || 3816 sksec->sclass == SECCLASS_DCCP_SOCKET) {
3870 isec->sclass == SECCLASS_DCCP_SOCKET) {
3871 struct common_audit_data ad; 3817 struct common_audit_data ad;
3872 struct sockaddr_in *addr4 = NULL; 3818 struct sockaddr_in *addr4 = NULL;
3873 struct sockaddr_in6 *addr6 = NULL; 3819 struct sockaddr_in6 *addr6 = NULL;
@@ -3890,13 +3836,13 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address,
3890 if (err) 3836 if (err)
3891 goto out; 3837 goto out;
3892 3838
3893 perm = (isec->sclass == SECCLASS_TCP_SOCKET) ? 3839 perm = (sksec->sclass == SECCLASS_TCP_SOCKET) ?
3894 TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; 3840 TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT;
3895 3841
3896 COMMON_AUDIT_DATA_INIT(&ad, NET); 3842 COMMON_AUDIT_DATA_INIT(&ad, NET);
3897 ad.u.net.dport = htons(snum); 3843 ad.u.net.dport = htons(snum);
3898 ad.u.net.family = sk->sk_family; 3844 ad.u.net.family = sk->sk_family;
3899 err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad); 3845 err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad);
3900 if (err) 3846 if (err)
3901 goto out; 3847 goto out;
3902 } 3848 }
@@ -3909,7 +3855,7 @@ out:
3909 3855
3910static int selinux_socket_listen(struct socket *sock, int backlog) 3856static int selinux_socket_listen(struct socket *sock, int backlog)
3911{ 3857{
3912 return socket_has_perm(current, sock, SOCKET__LISTEN); 3858 return sock_has_perm(current, sock->sk, SOCKET__LISTEN);
3913} 3859}
3914 3860
3915static int selinux_socket_accept(struct socket *sock, struct socket *newsock) 3861static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
@@ -3918,7 +3864,7 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
3918 struct inode_security_struct *isec; 3864 struct inode_security_struct *isec;
3919 struct inode_security_struct *newisec; 3865 struct inode_security_struct *newisec;
3920 3866
3921 err = socket_has_perm(current, sock, SOCKET__ACCEPT); 3867 err = sock_has_perm(current, sock->sk, SOCKET__ACCEPT);
3922 if (err) 3868 if (err)
3923 return err; 3869 return err;
3924 3870
@@ -3935,30 +3881,30 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
3935static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, 3881static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
3936 int size) 3882 int size)
3937{ 3883{
3938 return socket_has_perm(current, sock, SOCKET__WRITE); 3884 return sock_has_perm(current, sock->sk, SOCKET__WRITE);
3939} 3885}
3940 3886
3941static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg, 3887static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
3942 int size, int flags) 3888 int size, int flags)
3943{ 3889{
3944 return socket_has_perm(current, sock, SOCKET__READ); 3890 return sock_has_perm(current, sock->sk, SOCKET__READ);
3945} 3891}
3946 3892
3947static int selinux_socket_getsockname(struct socket *sock) 3893static int selinux_socket_getsockname(struct socket *sock)
3948{ 3894{
3949 return socket_has_perm(current, sock, SOCKET__GETATTR); 3895 return sock_has_perm(current, sock->sk, SOCKET__GETATTR);
3950} 3896}
3951 3897
3952static int selinux_socket_getpeername(struct socket *sock) 3898static int selinux_socket_getpeername(struct socket *sock)
3953{ 3899{
3954 return socket_has_perm(current, sock, SOCKET__GETATTR); 3900 return sock_has_perm(current, sock->sk, SOCKET__GETATTR);
3955} 3901}
3956 3902
3957static int selinux_socket_setsockopt(struct socket *sock, int level, int optname) 3903static int selinux_socket_setsockopt(struct socket *sock, int level, int optname)
3958{ 3904{
3959 int err; 3905 int err;
3960 3906
3961 err = socket_has_perm(current, sock, SOCKET__SETOPT); 3907 err = sock_has_perm(current, sock->sk, SOCKET__SETOPT);
3962 if (err) 3908 if (err)
3963 return err; 3909 return err;
3964 3910
@@ -3968,68 +3914,58 @@ static int selinux_socket_setsockopt(struct socket *sock, int level, int optname
3968static int selinux_socket_getsockopt(struct socket *sock, int level, 3914static int selinux_socket_getsockopt(struct socket *sock, int level,
3969 int optname) 3915 int optname)
3970{ 3916{
3971 return socket_has_perm(current, sock, SOCKET__GETOPT); 3917 return sock_has_perm(current, sock->sk, SOCKET__GETOPT);
3972} 3918}
3973 3919
3974static int selinux_socket_shutdown(struct socket *sock, int how) 3920static int selinux_socket_shutdown(struct socket *sock, int how)
3975{ 3921{
3976 return socket_has_perm(current, sock, SOCKET__SHUTDOWN); 3922 return sock_has_perm(current, sock->sk, SOCKET__SHUTDOWN);
3977} 3923}
3978 3924
3979static int selinux_socket_unix_stream_connect(struct socket *sock, 3925static int selinux_socket_unix_stream_connect(struct socket *sock,
3980 struct socket *other, 3926 struct socket *other,
3981 struct sock *newsk) 3927 struct sock *newsk)
3982{ 3928{
3983 struct sk_security_struct *sksec; 3929 struct sk_security_struct *sksec_sock = sock->sk->sk_security;
3984 struct inode_security_struct *isec; 3930 struct sk_security_struct *sksec_other = other->sk->sk_security;
3985 struct inode_security_struct *other_isec; 3931 struct sk_security_struct *sksec_new = newsk->sk_security;
3986 struct common_audit_data ad; 3932 struct common_audit_data ad;
3987 int err; 3933 int err;
3988 3934
3989 isec = SOCK_INODE(sock)->i_security;
3990 other_isec = SOCK_INODE(other)->i_security;
3991
3992 COMMON_AUDIT_DATA_INIT(&ad, NET); 3935 COMMON_AUDIT_DATA_INIT(&ad, NET);
3993 ad.u.net.sk = other->sk; 3936 ad.u.net.sk = other->sk;
3994 3937
3995 err = avc_has_perm(isec->sid, other_isec->sid, 3938 err = avc_has_perm(sksec_sock->sid, sksec_other->sid,
3996 isec->sclass, 3939 sksec_other->sclass,
3997 UNIX_STREAM_SOCKET__CONNECTTO, &ad); 3940 UNIX_STREAM_SOCKET__CONNECTTO, &ad);
3998 if (err) 3941 if (err)
3999 return err; 3942 return err;
4000 3943
4001 /* connecting socket */
4002 sksec = sock->sk->sk_security;
4003 sksec->peer_sid = other_isec->sid;
4004
4005 /* server child socket */ 3944 /* server child socket */
4006 sksec = newsk->sk_security; 3945 sksec_new->peer_sid = sksec_sock->sid;
4007 sksec->peer_sid = isec->sid; 3946 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); 3947 &sksec_new->sid);
3948 if (err)
3949 return err;
4009 3950
4010 return err; 3951 /* connecting socket */
3952 sksec_sock->peer_sid = sksec_new->sid;
3953
3954 return 0;
4011} 3955}
4012 3956
4013static int selinux_socket_unix_may_send(struct socket *sock, 3957static int selinux_socket_unix_may_send(struct socket *sock,
4014 struct socket *other) 3958 struct socket *other)
4015{ 3959{
4016 struct inode_security_struct *isec; 3960 struct sk_security_struct *ssec = sock->sk->sk_security;
4017 struct inode_security_struct *other_isec; 3961 struct sk_security_struct *osec = other->sk->sk_security;
4018 struct common_audit_data ad; 3962 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 3963
4024 COMMON_AUDIT_DATA_INIT(&ad, NET); 3964 COMMON_AUDIT_DATA_INIT(&ad, NET);
4025 ad.u.net.sk = other->sk; 3965 ad.u.net.sk = other->sk;
4026 3966
4027 err = avc_has_perm(isec->sid, other_isec->sid, 3967 return avc_has_perm(ssec->sid, osec->sid, osec->sclass, SOCKET__SENDTO,
4028 isec->sclass, SOCKET__SENDTO, &ad); 3968 &ad);
4029 if (err)
4030 return err;
4031
4032 return 0;
4033} 3969}
4034 3970
4035static 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,
@@ -4168,26 +4104,18 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
4168 int err = 0; 4104 int err = 0;
4169 char *scontext; 4105 char *scontext;
4170 u32 scontext_len; 4106 u32 scontext_len;
4171 struct sk_security_struct *sksec; 4107 struct sk_security_struct *sksec = sock->sk->sk_security;
4172 struct inode_security_struct *isec;
4173 u32 peer_sid = SECSID_NULL; 4108 u32 peer_sid = SECSID_NULL;
4174 4109
4175 isec = SOCK_INODE(sock)->i_security; 4110 if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
4176 4111 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; 4112 peer_sid = sksec->peer_sid;
4181 } 4113 if (peer_sid == SECSID_NULL)
4182 if (peer_sid == SECSID_NULL) { 4114 return -ENOPROTOOPT;
4183 err = -ENOPROTOOPT;
4184 goto out;
4185 }
4186 4115
4187 err = security_sid_to_context(peer_sid, &scontext, &scontext_len); 4116 err = security_sid_to_context(peer_sid, &scontext, &scontext_len);
4188
4189 if (err) 4117 if (err)
4190 goto out; 4118 return err;
4191 4119
4192 if (scontext_len > len) { 4120 if (scontext_len > len) {
4193 err = -ERANGE; 4121 err = -ERANGE;
@@ -4200,9 +4128,7 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
4200out_len: 4128out_len:
4201 if (put_user(scontext_len, optlen)) 4129 if (put_user(scontext_len, optlen))
4202 err = -EFAULT; 4130 err = -EFAULT;
4203
4204 kfree(scontext); 4131 kfree(scontext);
4205out:
4206 return err; 4132 return err;
4207} 4133}
4208 4134
@@ -4234,12 +4160,27 @@ out:
4234 4160
4235static 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)
4236{ 4162{
4237 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;
4238} 4175}
4239 4176
4240static void selinux_sk_free_security(struct sock *sk) 4177static void selinux_sk_free_security(struct sock *sk)
4241{ 4178{
4242 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);
4243} 4184}
4244 4185
4245static 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)
@@ -4399,8 +4340,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
4399 int err = 0; 4340 int err = 0;
4400 u32 perm; 4341 u32 perm;
4401 struct nlmsghdr *nlh; 4342 struct nlmsghdr *nlh;
4402 struct socket *sock = sk->sk_socket; 4343 struct sk_security_struct *sksec = sk->sk_security;
4403 struct inode_security_struct *isec = SOCK_INODE(sock)->i_security;
4404 4344
4405 if (skb->len < NLMSG_SPACE(0)) { 4345 if (skb->len < NLMSG_SPACE(0)) {
4406 err = -EINVAL; 4346 err = -EINVAL;
@@ -4408,13 +4348,13 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
4408 } 4348 }
4409 nlh = nlmsg_hdr(skb); 4349 nlh = nlmsg_hdr(skb);
4410 4350
4411 err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm); 4351 err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm);
4412 if (err) { 4352 if (err) {
4413 if (err == -EINVAL) { 4353 if (err == -EINVAL) {
4414 audit_log(current->audit_context, GFP_KERNEL, AUDIT_SELINUX_ERR, 4354 audit_log(current->audit_context, GFP_KERNEL, AUDIT_SELINUX_ERR,
4415 "SELinux: unrecognized netlink message" 4355 "SELinux: unrecognized netlink message"
4416 " type=%hu for sclass=%hu\n", 4356 " type=%hu for sclass=%hu\n",
4417 nlh->nlmsg_type, isec->sclass); 4357 nlh->nlmsg_type, sksec->sclass);
4418 if (!selinux_enforcing || security_get_allow_unknown()) 4358 if (!selinux_enforcing || security_get_allow_unknown())
4419 err = 0; 4359 err = 0;
4420 } 4360 }
@@ -4425,7 +4365,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
4425 goto out; 4365 goto out;
4426 } 4366 }
4427 4367
4428 err = socket_has_perm(current, sock, perm); 4368 err = sock_has_perm(current, sk, perm);
4429out: 4369out:
4430 return err; 4370 return err;
4431} 4371}