aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/commoncap.c6
-rw-r--r--security/dummy.c6
-rw-r--r--security/keys/key.c2
-rw-r--r--security/keys/request_key.c3
-rw-r--r--security/selinux/avc.c17
-rw-r--r--security/selinux/hooks.c74
-rw-r--r--security/selinux/netif.c4
-rw-r--r--security/selinux/netlabel.c61
-rw-r--r--security/selinux/netlink.c5
-rw-r--r--security/selinux/ss/avtab.c2
-rw-r--r--security/selinux/ss/services.c8
-rw-r--r--security/selinux/xfrm.c3
12 files changed, 113 insertions, 78 deletions
diff --git a/security/commoncap.c b/security/commoncap.c
index 384379ede4fd..7520361663e8 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -148,7 +148,7 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
148 148
149 if (bprm->e_uid != current->uid || bprm->e_gid != current->gid || 149 if (bprm->e_uid != current->uid || bprm->e_gid != current->gid ||
150 !cap_issubset (new_permitted, current->cap_permitted)) { 150 !cap_issubset (new_permitted, current->cap_permitted)) {
151 current->mm->dumpable = suid_dumpable; 151 set_dumpable(current->mm, suid_dumpable);
152 152
153 if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) { 153 if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
154 if (!capable(CAP_SETUID)) { 154 if (!capable(CAP_SETUID)) {
@@ -315,13 +315,13 @@ int cap_syslog (int type)
315 return 0; 315 return 0;
316} 316}
317 317
318int cap_vm_enough_memory(long pages) 318int cap_vm_enough_memory(struct mm_struct *mm, long pages)
319{ 319{
320 int cap_sys_admin = 0; 320 int cap_sys_admin = 0;
321 321
322 if (cap_capable(current, CAP_SYS_ADMIN) == 0) 322 if (cap_capable(current, CAP_SYS_ADMIN) == 0)
323 cap_sys_admin = 1; 323 cap_sys_admin = 1;
324 return __vm_enough_memory(pages, cap_sys_admin); 324 return __vm_enough_memory(mm, pages, cap_sys_admin);
325} 325}
326 326
327EXPORT_SYMBOL(cap_capable); 327EXPORT_SYMBOL(cap_capable);
diff --git a/security/dummy.c b/security/dummy.c
index d6a112ce2975..853ec2292798 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -108,13 +108,13 @@ static int dummy_settime(struct timespec *ts, struct timezone *tz)
108 return 0; 108 return 0;
109} 109}
110 110
111static int dummy_vm_enough_memory(long pages) 111static int dummy_vm_enough_memory(struct mm_struct *mm, long pages)
112{ 112{
113 int cap_sys_admin = 0; 113 int cap_sys_admin = 0;
114 114
115 if (dummy_capable(current, CAP_SYS_ADMIN) == 0) 115 if (dummy_capable(current, CAP_SYS_ADMIN) == 0)
116 cap_sys_admin = 1; 116 cap_sys_admin = 1;
117 return __vm_enough_memory(pages, cap_sys_admin); 117 return __vm_enough_memory(mm, pages, cap_sys_admin);
118} 118}
119 119
120static int dummy_bprm_alloc_security (struct linux_binprm *bprm) 120static int dummy_bprm_alloc_security (struct linux_binprm *bprm)
@@ -130,7 +130,7 @@ static void dummy_bprm_free_security (struct linux_binprm *bprm)
130static void dummy_bprm_apply_creds (struct linux_binprm *bprm, int unsafe) 130static void dummy_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
131{ 131{
132 if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) { 132 if (bprm->e_uid != current->uid || bprm->e_gid != current->gid) {
133 current->mm->dumpable = suid_dumpable; 133 set_dumpable(current->mm, suid_dumpable);
134 134
135 if ((unsafe & ~LSM_UNSAFE_PTRACE_CAP) && !capable(CAP_SETUID)) { 135 if ((unsafe & ~LSM_UNSAFE_PTRACE_CAP) && !capable(CAP_SETUID)) {
136 bprm->e_uid = current->uid; 136 bprm->e_uid = current->uid;
diff --git a/security/keys/key.c b/security/keys/key.c
index 700400d801dc..01bbc6d9d19b 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -1001,7 +1001,7 @@ void __init key_init(void)
1001{ 1001{
1002 /* allocate a slab in which we can store keys */ 1002 /* allocate a slab in which we can store keys */
1003 key_jar = kmem_cache_create("key_jar", sizeof(struct key), 1003 key_jar = kmem_cache_create("key_jar", sizeof(struct key),
1004 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); 1004 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
1005 1005
1006 /* add the special key types */ 1006 /* add the special key types */
1007 list_add_tail(&key_type_keyring.link, &key_types_list); 1007 list_add_tail(&key_type_keyring.link, &key_types_list);
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index f573ac189a0a..557500110a13 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -108,7 +108,8 @@ static int call_sbin_request_key(struct key *key,
108 argv[i] = NULL; 108 argv[i] = NULL;
109 109
110 /* do it */ 110 /* do it */
111 ret = call_usermodehelper_keys(argv[0], argv, envp, keyring, 1); 111 ret = call_usermodehelper_keys(argv[0], argv, envp, keyring,
112 UMH_WAIT_PROC);
112 113
113error_link: 114error_link:
114 key_put(keyring); 115 key_put(keyring);
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 78c408fd2b02..0e69adf63bdb 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -239,7 +239,7 @@ void __init avc_init(void)
239 atomic_set(&avc_cache.lru_hint, 0); 239 atomic_set(&avc_cache.lru_hint, 0);
240 240
241 avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node), 241 avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
242 0, SLAB_PANIC, NULL, NULL); 242 0, SLAB_PANIC, NULL);
243 243
244 audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n"); 244 audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n");
245} 245}
@@ -570,10 +570,12 @@ void avc_audit(u32 ssid, u32 tsid,
570 case AVC_AUDIT_DATA_FS: 570 case AVC_AUDIT_DATA_FS:
571 if (a->u.fs.dentry) { 571 if (a->u.fs.dentry) {
572 struct dentry *dentry = a->u.fs.dentry; 572 struct dentry *dentry = a->u.fs.dentry;
573 if (a->u.fs.mnt) 573 if (a->u.fs.mnt) {
574 audit_avc_path(dentry, a->u.fs.mnt); 574 audit_log_d_path(ab, "path=", dentry, a->u.fs.mnt);
575 audit_log_format(ab, " name="); 575 } else {
576 audit_log_untrustedstring(ab, dentry->d_name.name); 576 audit_log_format(ab, " name=");
577 audit_log_untrustedstring(ab, dentry->d_name.name);
578 }
577 inode = dentry->d_inode; 579 inode = dentry->d_inode;
578 } else if (a->u.fs.inode) { 580 } else if (a->u.fs.inode) {
579 struct dentry *dentry; 581 struct dentry *dentry;
@@ -624,9 +626,8 @@ void avc_audit(u32 ssid, u32 tsid,
624 case AF_UNIX: 626 case AF_UNIX:
625 u = unix_sk(sk); 627 u = unix_sk(sk);
626 if (u->dentry) { 628 if (u->dentry) {
627 audit_avc_path(u->dentry, u->mnt); 629 audit_log_d_path(ab, "path=",
628 audit_log_format(ab, " name="); 630 u->dentry, u->mnt);
629 audit_log_untrustedstring(ab, u->dentry->d_name.name);
630 break; 631 break;
631 } 632 }
632 if (!u->addr) 633 if (!u->addr)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 520b9998123e..3c3fff33d1ce 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -47,7 +47,7 @@
47#include <linux/netfilter_ipv6.h> 47#include <linux/netfilter_ipv6.h>
48#include <linux/tty.h> 48#include <linux/tty.h>
49#include <net/icmp.h> 49#include <net/icmp.h>
50#include <net/ip.h> /* for sysctl_local_port_range[] */ 50#include <net/ip.h> /* for local_port_range[] */
51#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */ 51#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */
52#include <asm/uaccess.h> 52#include <asm/uaccess.h>
53#include <asm/ioctls.h> 53#include <asm/ioctls.h>
@@ -316,6 +316,7 @@ static inline int inode_doinit(struct inode *inode)
316} 316}
317 317
318enum { 318enum {
319 Opt_error = -1,
319 Opt_context = 1, 320 Opt_context = 1,
320 Opt_fscontext = 2, 321 Opt_fscontext = 2,
321 Opt_defcontext = 4, 322 Opt_defcontext = 4,
@@ -327,6 +328,7 @@ static match_table_t tokens = {
327 {Opt_fscontext, "fscontext=%s"}, 328 {Opt_fscontext, "fscontext=%s"},
328 {Opt_defcontext, "defcontext=%s"}, 329 {Opt_defcontext, "defcontext=%s"},
329 {Opt_rootcontext, "rootcontext=%s"}, 330 {Opt_rootcontext, "rootcontext=%s"},
331 {Opt_error, NULL},
330}; 332};
331 333
332#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n" 334#define SEL_MOUNT_FAIL_MSG "SELinux: duplicate or incompatible mount options\n"
@@ -1584,7 +1586,7 @@ static int selinux_syslog(int type)
1584 * Do not audit the selinux permission check, as this is applied to all 1586 * Do not audit the selinux permission check, as this is applied to all
1585 * processes that allocate mappings. 1587 * processes that allocate mappings.
1586 */ 1588 */
1587static int selinux_vm_enough_memory(long pages) 1589static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
1588{ 1590{
1589 int rc, cap_sys_admin = 0; 1591 int rc, cap_sys_admin = 0;
1590 struct task_security_struct *tsec = current->security; 1592 struct task_security_struct *tsec = current->security;
@@ -1600,7 +1602,7 @@ static int selinux_vm_enough_memory(long pages)
1600 if (rc == 0) 1602 if (rc == 0)
1601 cap_sys_admin = 1; 1603 cap_sys_admin = 1;
1602 1604
1603 return __vm_enough_memory(pages, cap_sys_admin); 1605 return __vm_enough_memory(mm, pages, cap_sys_admin);
1604} 1606}
1605 1607
1606/* binprm security operations */ 1608/* binprm security operations */
@@ -1907,6 +1909,9 @@ static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm)
1907 spin_unlock_irq(&current->sighand->siglock); 1909 spin_unlock_irq(&current->sighand->siglock);
1908 } 1910 }
1909 1911
1912 /* Always clear parent death signal on SID transitions. */
1913 current->pdeath_signal = 0;
1914
1910 /* Check whether the new SID can inherit resource limits 1915 /* Check whether the new SID can inherit resource limits
1911 from the old SID. If not, reset all soft limits to 1916 from the old SID. If not, reset all soft limits to
1912 the lower of the current task's hard limit and the init 1917 the lower of the current task's hard limit and the init
@@ -3129,17 +3134,19 @@ static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad,
3129/** 3134/**
3130 * selinux_skb_extlbl_sid - Determine the external label of a packet 3135 * selinux_skb_extlbl_sid - Determine the external label of a packet
3131 * @skb: the packet 3136 * @skb: the packet
3132 * @base_sid: the SELinux SID to use as a context for MLS only external labels
3133 * @sid: the packet's SID 3137 * @sid: the packet's SID
3134 * 3138 *
3135 * Description: 3139 * Description:
3136 * Check the various different forms of external packet labeling and determine 3140 * Check the various different forms of external packet labeling and determine
3137 * the external SID for the packet. 3141 * the external SID for the packet. If only one form of external labeling is
3142 * present then it is used, if both labeled IPsec and NetLabel labels are
3143 * present then the SELinux type information is taken from the labeled IPsec
3144 * SA and the MLS sensitivity label information is taken from the NetLabel
3145 * security attributes. This bit of "magic" is done in the call to
3146 * selinux_netlbl_skbuff_getsid().
3138 * 3147 *
3139 */ 3148 */
3140static void selinux_skb_extlbl_sid(struct sk_buff *skb, 3149static void selinux_skb_extlbl_sid(struct sk_buff *skb, u32 *sid)
3141 u32 base_sid,
3142 u32 *sid)
3143{ 3150{
3144 u32 xfrm_sid; 3151 u32 xfrm_sid;
3145 u32 nlbl_sid; 3152 u32 nlbl_sid;
@@ -3147,10 +3154,9 @@ static void selinux_skb_extlbl_sid(struct sk_buff *skb,
3147 selinux_skb_xfrm_sid(skb, &xfrm_sid); 3154 selinux_skb_xfrm_sid(skb, &xfrm_sid);
3148 if (selinux_netlbl_skbuff_getsid(skb, 3155 if (selinux_netlbl_skbuff_getsid(skb,
3149 (xfrm_sid == SECSID_NULL ? 3156 (xfrm_sid == SECSID_NULL ?
3150 base_sid : xfrm_sid), 3157 SECINITSID_NETMSG : xfrm_sid),
3151 &nlbl_sid) != 0) 3158 &nlbl_sid) != 0)
3152 nlbl_sid = SECSID_NULL; 3159 nlbl_sid = SECSID_NULL;
3153
3154 *sid = (nlbl_sid == SECSID_NULL ? xfrm_sid : nlbl_sid); 3160 *sid = (nlbl_sid == SECSID_NULL ? xfrm_sid : nlbl_sid);
3155} 3161}
3156 3162
@@ -3226,8 +3232,6 @@ static int selinux_socket_post_create(struct socket *sock, int family,
3226/* Range of port numbers used to automatically bind. 3232/* Range of port numbers used to automatically bind.
3227 Need to determine whether we should perform a name_bind 3233 Need to determine whether we should perform a name_bind
3228 permission check between the socket and the port number. */ 3234 permission check between the socket and the port number. */
3229#define ip_local_port_range_0 sysctl_local_port_range[0]
3230#define ip_local_port_range_1 sysctl_local_port_range[1]
3231 3235
3232static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) 3236static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
3233{ 3237{
@@ -3270,20 +3274,27 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
3270 addrp = (char *)&addr6->sin6_addr.s6_addr; 3274 addrp = (char *)&addr6->sin6_addr.s6_addr;
3271 } 3275 }
3272 3276
3273 if (snum&&(snum < max(PROT_SOCK,ip_local_port_range_0) || 3277 if (snum) {
3274 snum > ip_local_port_range_1)) { 3278 int low, high;
3275 err = security_port_sid(sk->sk_family, sk->sk_type, 3279
3276 sk->sk_protocol, snum, &sid); 3280 inet_get_local_port_range(&low, &high);
3277 if (err) 3281
3278 goto out; 3282 if (snum < max(PROT_SOCK, low) || snum > high) {
3279 AVC_AUDIT_DATA_INIT(&ad,NET); 3283 err = security_port_sid(sk->sk_family,
3280 ad.u.net.sport = htons(snum); 3284 sk->sk_type,
3281 ad.u.net.family = family; 3285 sk->sk_protocol, snum,
3282 err = avc_has_perm(isec->sid, sid, 3286 &sid);
3283 isec->sclass, 3287 if (err)
3284 SOCKET__NAME_BIND, &ad); 3288 goto out;
3285 if (err) 3289 AVC_AUDIT_DATA_INIT(&ad,NET);
3286 goto out; 3290 ad.u.net.sport = htons(snum);
3291 ad.u.net.family = family;
3292 err = avc_has_perm(isec->sid, sid,
3293 isec->sclass,
3294 SOCKET__NAME_BIND, &ad);
3295 if (err)
3296 goto out;
3297 }
3287 } 3298 }
3288 3299
3289 switch(isec->sclass) { 3300 switch(isec->sclass) {
@@ -3695,7 +3706,7 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *
3695 if (sock && sock->sk->sk_family == PF_UNIX) 3706 if (sock && sock->sk->sk_family == PF_UNIX)
3696 selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid); 3707 selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
3697 else if (skb) 3708 else if (skb)
3698 selinux_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &peer_secid); 3709 selinux_skb_extlbl_sid(skb, &peer_secid);
3699 3710
3700 if (peer_secid == SECSID_NULL) 3711 if (peer_secid == SECSID_NULL)
3701 err = -EINVAL; 3712 err = -EINVAL;
@@ -3756,7 +3767,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3756 u32 newsid; 3767 u32 newsid;
3757 u32 peersid; 3768 u32 peersid;
3758 3769
3759 selinux_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &peersid); 3770 selinux_skb_extlbl_sid(skb, &peersid);
3760 if (peersid == SECSID_NULL) { 3771 if (peersid == SECSID_NULL) {
3761 req->secid = sksec->sid; 3772 req->secid = sksec->sid;
3762 req->peer_secid = SECSID_NULL; 3773 req->peer_secid = SECSID_NULL;
@@ -3794,7 +3805,7 @@ static void selinux_inet_conn_established(struct sock *sk,
3794{ 3805{
3795 struct sk_security_struct *sksec = sk->sk_security; 3806 struct sk_security_struct *sksec = sk->sk_security;
3796 3807
3797 selinux_skb_extlbl_sid(skb, SECINITSID_UNLABELED, &sksec->peer_sid); 3808 selinux_skb_extlbl_sid(skb, &sksec->peer_sid);
3798} 3809}
3799 3810
3800static void selinux_req_classify_flow(const struct request_sock *req, 3811static void selinux_req_classify_flow(const struct request_sock *req,
@@ -4657,8 +4668,7 @@ static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
4657 4668
4658static void selinux_release_secctx(char *secdata, u32 seclen) 4669static void selinux_release_secctx(char *secdata, u32 seclen)
4659{ 4670{
4660 if (secdata) 4671 kfree(secdata);
4661 kfree(secdata);
4662} 4672}
4663 4673
4664#ifdef CONFIG_KEYS 4674#ifdef CONFIG_KEYS
@@ -4912,7 +4922,7 @@ static __init int selinux_init(void)
4912 4922
4913 sel_inode_cache = kmem_cache_create("selinux_inode_security", 4923 sel_inode_cache = kmem_cache_create("selinux_inode_security",
4914 sizeof(struct inode_security_struct), 4924 sizeof(struct inode_security_struct),
4915 0, SLAB_PANIC, NULL, NULL); 4925 0, SLAB_PANIC, NULL);
4916 avc_init(); 4926 avc_init();
4917 4927
4918 original_ops = secondary_ops = security_ops; 4928 original_ops = secondary_ops = security_ops;
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index b10c34e8a743..e87ab948104c 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -20,6 +20,7 @@
20#include <linux/notifier.h> 20#include <linux/notifier.h>
21#include <linux/netdevice.h> 21#include <linux/netdevice.h>
22#include <linux/rcupdate.h> 22#include <linux/rcupdate.h>
23#include <net/net_namespace.h>
23 24
24#include "security.h" 25#include "security.h"
25#include "objsec.h" 26#include "objsec.h"
@@ -234,6 +235,9 @@ static int sel_netif_netdev_notifier_handler(struct notifier_block *this,
234{ 235{
235 struct net_device *dev = ptr; 236 struct net_device *dev = ptr;
236 237
238 if (dev->nd_net != &init_net)
239 return NOTIFY_DONE;
240
237 if (event == NETDEV_DOWN) 241 if (event == NETDEV_DOWN)
238 sel_netif_kill(dev); 242 sel_netif_kill(dev);
239 243
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index e64eca246f1a..d243ddc723a5 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -155,13 +155,20 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, u32 base_sid, u32 *sid)
155 int rc; 155 int rc;
156 struct netlbl_lsm_secattr secattr; 156 struct netlbl_lsm_secattr secattr;
157 157
158 if (!netlbl_enabled()) {
159 *sid = SECSID_NULL;
160 return 0;
161 }
162
158 netlbl_secattr_init(&secattr); 163 netlbl_secattr_init(&secattr);
159 rc = netlbl_skbuff_getattr(skb, &secattr); 164 rc = netlbl_skbuff_getattr(skb, &secattr);
160 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) 165 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) {
161 rc = security_netlbl_secattr_to_sid(&secattr, 166 rc = security_netlbl_secattr_to_sid(&secattr, base_sid, sid);
162 base_sid, 167 if (rc == 0 &&
163 sid); 168 (secattr.flags & NETLBL_SECATTR_CACHEABLE) &&
164 else 169 (secattr.flags & NETLBL_SECATTR_CACHE))
170 netlbl_cache_add(skb, &secattr);
171 } else
165 *sid = SECSID_NULL; 172 *sid = SECSID_NULL;
166 netlbl_secattr_destroy(&secattr); 173 netlbl_secattr_destroy(&secattr);
167 174
@@ -198,7 +205,7 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock)
198 if (netlbl_sock_getattr(sk, &secattr) == 0 && 205 if (netlbl_sock_getattr(sk, &secattr) == 0 &&
199 secattr.flags != NETLBL_SECATTR_NONE && 206 secattr.flags != NETLBL_SECATTR_NONE &&
200 security_netlbl_secattr_to_sid(&secattr, 207 security_netlbl_secattr_to_sid(&secattr,
201 SECINITSID_UNLABELED, 208 SECINITSID_NETMSG,
202 &nlbl_peer_sid) == 0) 209 &nlbl_peer_sid) == 0)
203 sksec->peer_sid = nlbl_peer_sid; 210 sksec->peer_sid = nlbl_peer_sid;
204 netlbl_secattr_destroy(&secattr); 211 netlbl_secattr_destroy(&secattr);
@@ -295,38 +302,46 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
295 struct avc_audit_data *ad) 302 struct avc_audit_data *ad)
296{ 303{
297 int rc; 304 int rc;
298 u32 netlbl_sid; 305 u32 nlbl_sid;
299 u32 recv_perm; 306 u32 perm;
307 struct netlbl_lsm_secattr secattr;
300 308
301 rc = selinux_netlbl_skbuff_getsid(skb, 309 if (!netlbl_enabled())
302 SECINITSID_UNLABELED, 310 return 0;
303 &netlbl_sid); 311
312 netlbl_secattr_init(&secattr);
313 rc = netlbl_skbuff_getattr(skb, &secattr);
314 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) {
315 rc = security_netlbl_secattr_to_sid(&secattr,
316 SECINITSID_NETMSG,
317 &nlbl_sid);
318 if (rc == 0 &&
319 (secattr.flags & NETLBL_SECATTR_CACHEABLE) &&
320 (secattr.flags & NETLBL_SECATTR_CACHE))
321 netlbl_cache_add(skb, &secattr);
322 } else
323 nlbl_sid = SECINITSID_UNLABELED;
324 netlbl_secattr_destroy(&secattr);
304 if (rc != 0) 325 if (rc != 0)
305 return rc; 326 return rc;
306 327
307 if (netlbl_sid == SECSID_NULL)
308 return 0;
309
310 switch (sksec->sclass) { 328 switch (sksec->sclass) {
311 case SECCLASS_UDP_SOCKET: 329 case SECCLASS_UDP_SOCKET:
312 recv_perm = UDP_SOCKET__RECVFROM; 330 perm = UDP_SOCKET__RECVFROM;
313 break; 331 break;
314 case SECCLASS_TCP_SOCKET: 332 case SECCLASS_TCP_SOCKET:
315 recv_perm = TCP_SOCKET__RECVFROM; 333 perm = TCP_SOCKET__RECVFROM;
316 break; 334 break;
317 default: 335 default:
318 recv_perm = RAWIP_SOCKET__RECVFROM; 336 perm = RAWIP_SOCKET__RECVFROM;
319 } 337 }
320 338
321 rc = avc_has_perm(sksec->sid, 339 rc = avc_has_perm(sksec->sid, nlbl_sid, sksec->sclass, perm, ad);
322 netlbl_sid,
323 sksec->sclass,
324 recv_perm,
325 ad);
326 if (rc == 0) 340 if (rc == 0)
327 return 0; 341 return 0;
328 342
329 netlbl_skbuff_err(skb, rc); 343 if (nlbl_sid != SECINITSID_UNLABELED)
344 netlbl_skbuff_err(skb, rc);
330 return rc; 345 return rc;
331} 346}
332 347
diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c
index f49046de63a2..b59871d74dad 100644
--- a/security/selinux/netlink.c
+++ b/security/selinux/netlink.c
@@ -17,6 +17,7 @@
17#include <linux/skbuff.h> 17#include <linux/skbuff.h>
18#include <linux/netlink.h> 18#include <linux/netlink.h>
19#include <linux/selinux_netlink.h> 19#include <linux/selinux_netlink.h>
20#include <net/net_namespace.h>
20 21
21static struct sock *selnl; 22static struct sock *selnl;
22 23
@@ -104,8 +105,8 @@ void selnl_notify_policyload(u32 seqno)
104 105
105static int __init selnl_init(void) 106static int __init selnl_init(void)
106{ 107{
107 selnl = netlink_kernel_create(NETLINK_SELINUX, SELNLGRP_MAX, NULL, NULL, 108 selnl = netlink_kernel_create(&init_net, NETLINK_SELINUX,
108 THIS_MODULE); 109 SELNLGRP_MAX, NULL, NULL, THIS_MODULE);
109 if (selnl == NULL) 110 if (selnl == NULL)
110 panic("SELinux: Cannot create netlink socket."); 111 panic("SELinux: Cannot create netlink socket.");
111 netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV); 112 netlink_set_nonroot(NETLINK_SELINUX, NL_NONROOT_RECV);
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index 3122908afdc1..85705eb289e0 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -445,7 +445,7 @@ void avtab_cache_init(void)
445{ 445{
446 avtab_node_cachep = kmem_cache_create("avtab_node", 446 avtab_node_cachep = kmem_cache_create("avtab_node",
447 sizeof(struct avtab_node), 447 sizeof(struct avtab_node),
448 0, SLAB_PANIC, NULL, NULL); 448 0, SLAB_PANIC, NULL);
449} 449}
450 450
451void avtab_cache_destroy(void) 451void avtab_cache_destroy(void)
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index b5f017f07a75..6100fc023055 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -792,7 +792,7 @@ int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)
792 * @scontext: security context 792 * @scontext: security context
793 * @scontext_len: length in bytes 793 * @scontext_len: length in bytes
794 * @sid: security identifier, SID 794 * @sid: security identifier, SID
795 * @def_sid: default SID to assign on errror 795 * @def_sid: default SID to assign on error
796 * 796 *
797 * Obtains a SID associated with the security context that 797 * Obtains a SID associated with the security context that
798 * has the string representation specified by @scontext. 798 * has the string representation specified by @scontext.
@@ -2127,7 +2127,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr,
2127 *rule = NULL; 2127 *rule = NULL;
2128 2128
2129 if (!ss_initialized) 2129 if (!ss_initialized)
2130 return -ENOTSUPP; 2130 return -EOPNOTSUPP;
2131 2131
2132 switch (field) { 2132 switch (field) {
2133 case AUDIT_SUBJ_USER: 2133 case AUDIT_SUBJ_USER:
@@ -2417,8 +2417,10 @@ static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr,
2417 2417
2418 cache->type = NETLBL_CACHE_T_MLS; 2418 cache->type = NETLBL_CACHE_T_MLS;
2419 if (ebitmap_cpy(&cache->data.mls_label.level[0].cat, 2419 if (ebitmap_cpy(&cache->data.mls_label.level[0].cat,
2420 &ctx->range.level[0].cat) != 0) 2420 &ctx->range.level[0].cat) != 0) {
2421 kfree(cache);
2421 return; 2422 return;
2423 }
2422 cache->data.mls_label.level[1].cat.highbit = 2424 cache->data.mls_label.level[1].cat.highbit =
2423 cache->data.mls_label.level[0].cat.highbit; 2425 cache->data.mls_label.level[0].cat.highbit;
2424 cache->data.mls_label.level[1].cat.node = 2426 cache->data.mls_label.level[1].cat.node =
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index bd8d1ef40a90..ba715f40b658 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -216,7 +216,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
216 return -ENOMEM; 216 return -ENOMEM;
217 217
218 *ctxp = ctx = kmalloc(sizeof(*ctx) + 218 *ctxp = ctx = kmalloc(sizeof(*ctx) +
219 uctx->ctx_len, 219 uctx->ctx_len + 1,
220 GFP_KERNEL); 220 GFP_KERNEL);
221 221
222 if (!ctx) 222 if (!ctx)
@@ -229,6 +229,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
229 memcpy(ctx->ctx_str, 229 memcpy(ctx->ctx_str,
230 uctx+1, 230 uctx+1,
231 ctx->ctx_len); 231 ctx->ctx_len);
232 ctx->ctx_str[ctx->ctx_len] = 0;
232 rc = security_context_to_sid(ctx->ctx_str, 233 rc = security_context_to_sid(ctx->ctx_str,
233 ctx->ctx_len, 234 ctx->ctx_len,
234 &ctx->ctx_sid); 235 &ctx->ctx_sid);