aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2013-12-17 09:27:08 -0500
committerIngo Molnar <mingo@kernel.org>2013-12-17 09:27:08 -0500
commitbb799d3b980eb803ca2da4a4eefbd9308f8d988a (patch)
tree69fbe0cd6d47b23a50f5e1d87bf7489532fae149 /security/selinux
parent919fc6e34831d1c2b58bfb5ae261dc3facc9b269 (diff)
parent319e2e3f63c348a9b66db4667efa73178e18b17d (diff)
Merge tag 'v3.13-rc4' into core/locking
Merge Linux 3.13-rc4, to refresh this rather old tree with the latest fixes. Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c241
-rw-r--r--security/selinux/include/objsec.h4
-rw-r--r--security/selinux/include/security.h13
-rw-r--r--security/selinux/include/xfrm.h49
-rw-r--r--security/selinux/netlabel.c6
-rw-r--r--security/selinux/netnode.c2
-rw-r--r--security/selinux/nlmsgtab.c2
-rw-r--r--security/selinux/selinuxfs.c4
-rw-r--r--security/selinux/ss/ebitmap.c20
-rw-r--r--security/selinux/ss/ebitmap.h10
-rw-r--r--security/selinux/ss/mls.c22
-rw-r--r--security/selinux/ss/mls_types.h2
-rw-r--r--security/selinux/ss/policydb.c3
-rw-r--r--security/selinux/ss/services.c24
-rw-r--r--security/selinux/xfrm.c481
15 files changed, 504 insertions, 379 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c540795fb3f2..419491d8e7d2 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -53,6 +53,7 @@
53#include <net/ip.h> /* for local_port_range[] */ 53#include <net/ip.h> /* for local_port_range[] */
54#include <net/sock.h> 54#include <net/sock.h>
55#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */ 55#include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */
56#include <net/inet_connection_sock.h>
56#include <net/net_namespace.h> 57#include <net/net_namespace.h>
57#include <net/netlabel.h> 58#include <net/netlabel.h>
58#include <linux/uaccess.h> 59#include <linux/uaccess.h>
@@ -95,8 +96,6 @@
95#include "audit.h" 96#include "audit.h"
96#include "avc_ss.h" 97#include "avc_ss.h"
97 98
98#define NUM_SEL_MNT_OPTS 5
99
100extern struct security_operations *security_ops; 99extern struct security_operations *security_ops;
101 100
102/* SECMARK reference count */ 101/* SECMARK reference count */
@@ -139,12 +138,28 @@ static struct kmem_cache *sel_inode_cache;
139 * This function checks the SECMARK reference counter to see if any SECMARK 138 * This function checks the SECMARK reference counter to see if any SECMARK
140 * targets are currently configured, if the reference counter is greater than 139 * targets are currently configured, if the reference counter is greater than
141 * zero SECMARK is considered to be enabled. Returns true (1) if SECMARK is 140 * zero SECMARK is considered to be enabled. Returns true (1) if SECMARK is
142 * enabled, false (0) if SECMARK is disabled. 141 * enabled, false (0) if SECMARK is disabled. If the always_check_network
142 * policy capability is enabled, SECMARK is always considered enabled.
143 * 143 *
144 */ 144 */
145static int selinux_secmark_enabled(void) 145static int selinux_secmark_enabled(void)
146{ 146{
147 return (atomic_read(&selinux_secmark_refcount) > 0); 147 return (selinux_policycap_alwaysnetwork || atomic_read(&selinux_secmark_refcount));
148}
149
150/**
151 * selinux_peerlbl_enabled - Check to see if peer labeling is currently enabled
152 *
153 * Description:
154 * This function checks if NetLabel or labeled IPSEC is enabled. Returns true
155 * (1) if any are enabled or false (0) if neither are enabled. If the
156 * always_check_network policy capability is enabled, peer labeling
157 * is always considered enabled.
158 *
159 */
160static int selinux_peerlbl_enabled(void)
161{
162 return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
148} 163}
149 164
150/* 165/*
@@ -309,8 +324,11 @@ enum {
309 Opt_defcontext = 3, 324 Opt_defcontext = 3,
310 Opt_rootcontext = 4, 325 Opt_rootcontext = 4,
311 Opt_labelsupport = 5, 326 Opt_labelsupport = 5,
327 Opt_nextmntopt = 6,
312}; 328};
313 329
330#define NUM_SEL_MNT_OPTS (Opt_nextmntopt - 1)
331
314static const match_table_t tokens = { 332static const match_table_t tokens = {
315 {Opt_context, CONTEXT_STR "%s"}, 333 {Opt_context, CONTEXT_STR "%s"},
316 {Opt_fscontext, FSCONTEXT_STR "%s"}, 334 {Opt_fscontext, FSCONTEXT_STR "%s"},
@@ -355,6 +373,29 @@ static int may_context_mount_inode_relabel(u32 sid,
355 return rc; 373 return rc;
356} 374}
357 375
376static int selinux_is_sblabel_mnt(struct super_block *sb)
377{
378 struct superblock_security_struct *sbsec = sb->s_security;
379
380 if (sbsec->behavior == SECURITY_FS_USE_XATTR ||
381 sbsec->behavior == SECURITY_FS_USE_TRANS ||
382 sbsec->behavior == SECURITY_FS_USE_TASK)
383 return 1;
384
385 /* Special handling for sysfs. Is genfs but also has setxattr handler*/
386 if (strncmp(sb->s_type->name, "sysfs", sizeof("sysfs")) == 0)
387 return 1;
388
389 /*
390 * Special handling for rootfs. Is genfs but supports
391 * setting SELinux context on in-core inodes.
392 */
393 if (strncmp(sb->s_type->name, "rootfs", sizeof("rootfs")) == 0)
394 return 1;
395
396 return 0;
397}
398
358static int sb_finish_set_opts(struct super_block *sb) 399static int sb_finish_set_opts(struct super_block *sb)
359{ 400{
360 struct superblock_security_struct *sbsec = sb->s_security; 401 struct superblock_security_struct *sbsec = sb->s_security;
@@ -388,8 +429,6 @@ static int sb_finish_set_opts(struct super_block *sb)
388 } 429 }
389 } 430 }
390 431
391 sbsec->flags |= (SE_SBINITIALIZED | SE_SBLABELSUPP);
392
393 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) 432 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
394 printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n", 433 printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",
395 sb->s_id, sb->s_type->name); 434 sb->s_id, sb->s_type->name);
@@ -398,15 +437,9 @@ static int sb_finish_set_opts(struct super_block *sb)
398 sb->s_id, sb->s_type->name, 437 sb->s_id, sb->s_type->name,
399 labeling_behaviors[sbsec->behavior-1]); 438 labeling_behaviors[sbsec->behavior-1]);
400 439
401 if (sbsec->behavior == SECURITY_FS_USE_GENFS || 440 sbsec->flags |= SE_SBINITIALIZED;
402 sbsec->behavior == SECURITY_FS_USE_MNTPOINT || 441 if (selinux_is_sblabel_mnt(sb))
403 sbsec->behavior == SECURITY_FS_USE_NONE || 442 sbsec->flags |= SBLABEL_MNT;
404 sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
405 sbsec->flags &= ~SE_SBLABELSUPP;
406
407 /* Special handling for sysfs. Is genfs but also has setxattr handler*/
408 if (strncmp(sb->s_type->name, "sysfs", sizeof("sysfs")) == 0)
409 sbsec->flags |= SE_SBLABELSUPP;
410 443
411 /* Initialize the root inode. */ 444 /* Initialize the root inode. */
412 rc = inode_doinit_with_dentry(root_inode, root); 445 rc = inode_doinit_with_dentry(root_inode, root);
@@ -460,15 +493,18 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
460 if (!ss_initialized) 493 if (!ss_initialized)
461 return -EINVAL; 494 return -EINVAL;
462 495
496 /* make sure we always check enough bits to cover the mask */
497 BUILD_BUG_ON(SE_MNTMASK >= (1 << NUM_SEL_MNT_OPTS));
498
463 tmp = sbsec->flags & SE_MNTMASK; 499 tmp = sbsec->flags & SE_MNTMASK;
464 /* count the number of mount options for this sb */ 500 /* count the number of mount options for this sb */
465 for (i = 0; i < 8; i++) { 501 for (i = 0; i < NUM_SEL_MNT_OPTS; i++) {
466 if (tmp & 0x01) 502 if (tmp & 0x01)
467 opts->num_mnt_opts++; 503 opts->num_mnt_opts++;
468 tmp >>= 1; 504 tmp >>= 1;
469 } 505 }
470 /* Check if the Label support flag is set */ 506 /* Check if the Label support flag is set */
471 if (sbsec->flags & SE_SBLABELSUPP) 507 if (sbsec->flags & SBLABEL_MNT)
472 opts->num_mnt_opts++; 508 opts->num_mnt_opts++;
473 509
474 opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC); 510 opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC);
@@ -515,9 +551,9 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
515 opts->mnt_opts[i] = context; 551 opts->mnt_opts[i] = context;
516 opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT; 552 opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT;
517 } 553 }
518 if (sbsec->flags & SE_SBLABELSUPP) { 554 if (sbsec->flags & SBLABEL_MNT) {
519 opts->mnt_opts[i] = NULL; 555 opts->mnt_opts[i] = NULL;
520 opts->mnt_opts_flags[i++] = SE_SBLABELSUPP; 556 opts->mnt_opts_flags[i++] = SBLABEL_MNT;
521 } 557 }
522 558
523 BUG_ON(i != opts->num_mnt_opts); 559 BUG_ON(i != opts->num_mnt_opts);
@@ -614,7 +650,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
614 for (i = 0; i < num_opts; i++) { 650 for (i = 0; i < num_opts; i++) {
615 u32 sid; 651 u32 sid;
616 652
617 if (flags[i] == SE_SBLABELSUPP) 653 if (flags[i] == SBLABEL_MNT)
618 continue; 654 continue;
619 rc = security_context_to_sid(mount_options[i], 655 rc = security_context_to_sid(mount_options[i],
620 strlen(mount_options[i]), &sid); 656 strlen(mount_options[i]), &sid);
@@ -685,9 +721,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
685 * Determine the labeling behavior to use for this 721 * Determine the labeling behavior to use for this
686 * filesystem type. 722 * filesystem type.
687 */ 723 */
688 rc = security_fs_use((sbsec->flags & SE_SBPROC) ? 724 rc = security_fs_use(sb);
689 "proc" : sb->s_type->name,
690 &sbsec->behavior, &sbsec->sid);
691 if (rc) { 725 if (rc) {
692 printk(KERN_WARNING 726 printk(KERN_WARNING
693 "%s: security_fs_use(%s) returned %d\n", 727 "%s: security_fs_use(%s) returned %d\n",
@@ -1037,7 +1071,7 @@ static void selinux_write_opts(struct seq_file *m,
1037 case DEFCONTEXT_MNT: 1071 case DEFCONTEXT_MNT:
1038 prefix = DEFCONTEXT_STR; 1072 prefix = DEFCONTEXT_STR;
1039 break; 1073 break;
1040 case SE_SBLABELSUPP: 1074 case SBLABEL_MNT:
1041 seq_putc(m, ','); 1075 seq_putc(m, ',');
1042 seq_puts(m, LABELSUPP_STR); 1076 seq_puts(m, LABELSUPP_STR);
1043 continue; 1077 continue;
@@ -1649,7 +1683,7 @@ static int may_create(struct inode *dir,
1649 if (rc) 1683 if (rc)
1650 return rc; 1684 return rc;
1651 1685
1652 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { 1686 if (!newsid || !(sbsec->flags & SBLABEL_MNT)) {
1653 rc = security_transition_sid(sid, dsec->sid, tclass, 1687 rc = security_transition_sid(sid, dsec->sid, tclass,
1654 &dentry->d_name, &newsid); 1688 &dentry->d_name, &newsid);
1655 if (rc) 1689 if (rc)
@@ -2437,7 +2471,7 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
2437 u32 sid; 2471 u32 sid;
2438 size_t len; 2472 size_t len;
2439 2473
2440 if (flags[i] == SE_SBLABELSUPP) 2474 if (flags[i] == SBLABEL_MNT)
2441 continue; 2475 continue;
2442 len = strlen(mount_options[i]); 2476 len = strlen(mount_options[i]);
2443 rc = security_context_to_sid(mount_options[i], len, &sid); 2477 rc = security_context_to_sid(mount_options[i], len, &sid);
@@ -2606,7 +2640,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2606 if ((sbsec->flags & SE_SBINITIALIZED) && 2640 if ((sbsec->flags & SE_SBINITIALIZED) &&
2607 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) 2641 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT))
2608 newsid = sbsec->mntpoint_sid; 2642 newsid = sbsec->mntpoint_sid;
2609 else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { 2643 else if (!newsid || !(sbsec->flags & SBLABEL_MNT)) {
2610 rc = security_transition_sid(sid, dsec->sid, 2644 rc = security_transition_sid(sid, dsec->sid,
2611 inode_mode_to_security_class(inode->i_mode), 2645 inode_mode_to_security_class(inode->i_mode),
2612 qstr, &newsid); 2646 qstr, &newsid);
@@ -2628,7 +2662,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2628 isec->initialized = 1; 2662 isec->initialized = 1;
2629 } 2663 }
2630 2664
2631 if (!ss_initialized || !(sbsec->flags & SE_SBLABELSUPP)) 2665 if (!ss_initialized || !(sbsec->flags & SBLABEL_MNT))
2632 return -EOPNOTSUPP; 2666 return -EOPNOTSUPP;
2633 2667
2634 if (name) 2668 if (name)
@@ -2830,7 +2864,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2830 return selinux_inode_setotherxattr(dentry, name); 2864 return selinux_inode_setotherxattr(dentry, name);
2831 2865
2832 sbsec = inode->i_sb->s_security; 2866 sbsec = inode->i_sb->s_security;
2833 if (!(sbsec->flags & SE_SBLABELSUPP)) 2867 if (!(sbsec->flags & SBLABEL_MNT))
2834 return -EOPNOTSUPP; 2868 return -EOPNOTSUPP;
2835 2869
2836 if (!inode_owner_or_capable(inode)) 2870 if (!inode_owner_or_capable(inode))
@@ -3791,8 +3825,12 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
3791 u32 nlbl_sid; 3825 u32 nlbl_sid;
3792 u32 nlbl_type; 3826 u32 nlbl_type;
3793 3827
3794 selinux_skb_xfrm_sid(skb, &xfrm_sid); 3828 err = selinux_xfrm_skb_sid(skb, &xfrm_sid);
3795 selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid); 3829 if (unlikely(err))
3830 return -EACCES;
3831 err = selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
3832 if (unlikely(err))
3833 return -EACCES;
3796 3834
3797 err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid); 3835 err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid);
3798 if (unlikely(err)) { 3836 if (unlikely(err)) {
@@ -3805,6 +3843,30 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
3805 return 0; 3843 return 0;
3806} 3844}
3807 3845
3846/**
3847 * selinux_conn_sid - Determine the child socket label for a connection
3848 * @sk_sid: the parent socket's SID
3849 * @skb_sid: the packet's SID
3850 * @conn_sid: the resulting connection SID
3851 *
3852 * If @skb_sid is valid then the user:role:type information from @sk_sid is
3853 * combined with the MLS information from @skb_sid in order to create
3854 * @conn_sid. If @skb_sid is not valid then then @conn_sid is simply a copy
3855 * of @sk_sid. Returns zero on success, negative values on failure.
3856 *
3857 */
3858static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid)
3859{
3860 int err = 0;
3861
3862 if (skb_sid != SECSID_NULL)
3863 err = security_sid_mls_copy(sk_sid, skb_sid, conn_sid);
3864 else
3865 *conn_sid = sk_sid;
3866
3867 return err;
3868}
3869
3808/* socket security operations */ 3870/* socket security operations */
3809 3871
3810static int socket_sockcreate_sid(const struct task_security_struct *tsec, 3872static int socket_sockcreate_sid(const struct task_security_struct *tsec,
@@ -4246,7 +4308,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4246 return selinux_sock_rcv_skb_compat(sk, skb, family); 4308 return selinux_sock_rcv_skb_compat(sk, skb, family);
4247 4309
4248 secmark_active = selinux_secmark_enabled(); 4310 secmark_active = selinux_secmark_enabled();
4249 peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled(); 4311 peerlbl_active = selinux_peerlbl_enabled();
4250 if (!secmark_active && !peerlbl_active) 4312 if (!secmark_active && !peerlbl_active)
4251 return 0; 4313 return 0;
4252 4314
@@ -4411,7 +4473,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
4411 struct sk_security_struct *sksec = sk->sk_security; 4473 struct sk_security_struct *sksec = sk->sk_security;
4412 int err; 4474 int err;
4413 u16 family = sk->sk_family; 4475 u16 family = sk->sk_family;
4414 u32 newsid; 4476 u32 connsid;
4415 u32 peersid; 4477 u32 peersid;
4416 4478
4417 /* handle mapped IPv4 packets arriving via IPv6 sockets */ 4479 /* handle mapped IPv4 packets arriving via IPv6 sockets */
@@ -4421,16 +4483,11 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
4421 err = selinux_skb_peerlbl_sid(skb, family, &peersid); 4483 err = selinux_skb_peerlbl_sid(skb, family, &peersid);
4422 if (err) 4484 if (err)
4423 return err; 4485 return err;
4424 if (peersid == SECSID_NULL) { 4486 err = selinux_conn_sid(sksec->sid, peersid, &connsid);
4425 req->secid = sksec->sid; 4487 if (err)
4426 req->peer_secid = SECSID_NULL; 4488 return err;
4427 } else { 4489 req->secid = connsid;
4428 err = security_sid_mls_copy(sksec->sid, peersid, &newsid); 4490 req->peer_secid = peersid;
4429 if (err)
4430 return err;
4431 req->secid = newsid;
4432 req->peer_secid = peersid;
4433 }
4434 4491
4435 return selinux_netlbl_inet_conn_request(req, family); 4492 return selinux_netlbl_inet_conn_request(req, family);
4436} 4493}
@@ -4628,7 +4685,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
4628 4685
4629 secmark_active = selinux_secmark_enabled(); 4686 secmark_active = selinux_secmark_enabled();
4630 netlbl_active = netlbl_enabled(); 4687 netlbl_active = netlbl_enabled();
4631 peerlbl_active = netlbl_active || selinux_xfrm_enabled(); 4688 peerlbl_active = selinux_peerlbl_enabled();
4632 if (!secmark_active && !peerlbl_active) 4689 if (!secmark_active && !peerlbl_active)
4633 return NF_ACCEPT; 4690 return NF_ACCEPT;
4634 4691
@@ -4690,6 +4747,7 @@ static unsigned int selinux_ipv6_forward(const struct nf_hook_ops *ops,
4690static unsigned int selinux_ip_output(struct sk_buff *skb, 4747static unsigned int selinux_ip_output(struct sk_buff *skb,
4691 u16 family) 4748 u16 family)
4692{ 4749{
4750 struct sock *sk;
4693 u32 sid; 4751 u32 sid;
4694 4752
4695 if (!netlbl_enabled()) 4753 if (!netlbl_enabled())
@@ -4698,8 +4756,27 @@ static unsigned int selinux_ip_output(struct sk_buff *skb,
4698 /* we do this in the LOCAL_OUT path and not the POST_ROUTING path 4756 /* we do this in the LOCAL_OUT path and not the POST_ROUTING path
4699 * because we want to make sure we apply the necessary labeling 4757 * because we want to make sure we apply the necessary labeling
4700 * before IPsec is applied so we can leverage AH protection */ 4758 * before IPsec is applied so we can leverage AH protection */
4701 if (skb->sk) { 4759 sk = skb->sk;
4702 struct sk_security_struct *sksec = skb->sk->sk_security; 4760 if (sk) {
4761 struct sk_security_struct *sksec;
4762
4763 if (sk->sk_state == TCP_LISTEN)
4764 /* if the socket is the listening state then this
4765 * packet is a SYN-ACK packet which means it needs to
4766 * be labeled based on the connection/request_sock and
4767 * not the parent socket. unfortunately, we can't
4768 * lookup the request_sock yet as it isn't queued on
4769 * the parent socket until after the SYN-ACK is sent.
4770 * the "solution" is to simply pass the packet as-is
4771 * as any IP option based labeling should be copied
4772 * from the initial connection request (in the IP
4773 * layer). it is far from ideal, but until we get a
4774 * security label in the packet itself this is the
4775 * best we can do. */
4776 return NF_ACCEPT;
4777
4778 /* standard practice, label using the parent socket */
4779 sksec = sk->sk_security;
4703 sid = sksec->sid; 4780 sid = sksec->sid;
4704 } else 4781 } else
4705 sid = SECINITSID_KERNEL; 4782 sid = SECINITSID_KERNEL;
@@ -4769,27 +4846,36 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4769 * as fast and as clean as possible. */ 4846 * as fast and as clean as possible. */
4770 if (!selinux_policycap_netpeer) 4847 if (!selinux_policycap_netpeer)
4771 return selinux_ip_postroute_compat(skb, ifindex, family); 4848 return selinux_ip_postroute_compat(skb, ifindex, family);
4849
4850 secmark_active = selinux_secmark_enabled();
4851 peerlbl_active = selinux_peerlbl_enabled();
4852 if (!secmark_active && !peerlbl_active)
4853 return NF_ACCEPT;
4854
4855 sk = skb->sk;
4856
4772#ifdef CONFIG_XFRM 4857#ifdef CONFIG_XFRM
4773 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec 4858 /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
4774 * packet transformation so allow the packet to pass without any checks 4859 * packet transformation so allow the packet to pass without any checks
4775 * since we'll have another chance to perform access control checks 4860 * since we'll have another chance to perform access control checks
4776 * when the packet is on it's final way out. 4861 * when the packet is on it's final way out.
4777 * NOTE: there appear to be some IPv6 multicast cases where skb->dst 4862 * NOTE: there appear to be some IPv6 multicast cases where skb->dst
4778 * is NULL, in this case go ahead and apply access control. */ 4863 * is NULL, in this case go ahead and apply access control.
4779 if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL) 4864 * NOTE: if this is a local socket (skb->sk != NULL) that is in the
4865 * TCP listening state we cannot wait until the XFRM processing
4866 * is done as we will miss out on the SA label if we do;
4867 * unfortunately, this means more work, but it is only once per
4868 * connection. */
4869 if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
4870 !(sk != NULL && sk->sk_state == TCP_LISTEN))
4780 return NF_ACCEPT; 4871 return NF_ACCEPT;
4781#endif 4872#endif
4782 secmark_active = selinux_secmark_enabled();
4783 peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
4784 if (!secmark_active && !peerlbl_active)
4785 return NF_ACCEPT;
4786 4873
4787 /* if the packet is being forwarded then get the peer label from the
4788 * packet itself; otherwise check to see if it is from a local
4789 * application or the kernel, if from an application get the peer label
4790 * from the sending socket, otherwise use the kernel's sid */
4791 sk = skb->sk;
4792 if (sk == NULL) { 4874 if (sk == NULL) {
4875 /* Without an associated socket the packet is either coming
4876 * from the kernel or it is being forwarded; check the packet
4877 * to determine which and if the packet is being forwarded
4878 * query the packet directly to determine the security label. */
4793 if (skb->skb_iif) { 4879 if (skb->skb_iif) {
4794 secmark_perm = PACKET__FORWARD_OUT; 4880 secmark_perm = PACKET__FORWARD_OUT;
4795 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid)) 4881 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
@@ -4798,7 +4884,45 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4798 secmark_perm = PACKET__SEND; 4884 secmark_perm = PACKET__SEND;
4799 peer_sid = SECINITSID_KERNEL; 4885 peer_sid = SECINITSID_KERNEL;
4800 } 4886 }
4887 } else if (sk->sk_state == TCP_LISTEN) {
4888 /* Locally generated packet but the associated socket is in the
4889 * listening state which means this is a SYN-ACK packet. In
4890 * this particular case the correct security label is assigned
4891 * to the connection/request_sock but unfortunately we can't
4892 * query the request_sock as it isn't queued on the parent
4893 * socket until after the SYN-ACK packet is sent; the only
4894 * viable choice is to regenerate the label like we do in
4895 * selinux_inet_conn_request(). See also selinux_ip_output()
4896 * for similar problems. */
4897 u32 skb_sid;
4898 struct sk_security_struct *sksec = sk->sk_security;
4899 if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
4900 return NF_DROP;
4901 /* At this point, if the returned skb peerlbl is SECSID_NULL
4902 * and the packet has been through at least one XFRM
4903 * transformation then we must be dealing with the "final"
4904 * form of labeled IPsec packet; since we've already applied
4905 * all of our access controls on this packet we can safely
4906 * pass the packet. */
4907 if (skb_sid == SECSID_NULL) {
4908 switch (family) {
4909 case PF_INET:
4910 if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
4911 return NF_ACCEPT;
4912 break;
4913 case PF_INET6:
4914 if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
4915 return NF_ACCEPT;
4916 default:
4917 return NF_DROP_ERR(-ECONNREFUSED);
4918 }
4919 }
4920 if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid))
4921 return NF_DROP;
4922 secmark_perm = PACKET__SEND;
4801 } else { 4923 } else {
4924 /* Locally generated packet, fetch the security label from the
4925 * associated socket. */
4802 struct sk_security_struct *sksec = sk->sk_security; 4926 struct sk_security_struct *sksec = sk->sk_security;
4803 peer_sid = sksec->sid; 4927 peer_sid = sksec->sid;
4804 secmark_perm = PACKET__SEND; 4928 secmark_perm = PACKET__SEND;
@@ -5784,7 +5908,8 @@ static struct security_operations selinux_ops = {
5784 .xfrm_policy_clone_security = selinux_xfrm_policy_clone, 5908 .xfrm_policy_clone_security = selinux_xfrm_policy_clone,
5785 .xfrm_policy_free_security = selinux_xfrm_policy_free, 5909 .xfrm_policy_free_security = selinux_xfrm_policy_free,
5786 .xfrm_policy_delete_security = selinux_xfrm_policy_delete, 5910 .xfrm_policy_delete_security = selinux_xfrm_policy_delete,
5787 .xfrm_state_alloc_security = selinux_xfrm_state_alloc, 5911 .xfrm_state_alloc = selinux_xfrm_state_alloc,
5912 .xfrm_state_alloc_acquire = selinux_xfrm_state_alloc_acquire,
5788 .xfrm_state_free_security = selinux_xfrm_state_free, 5913 .xfrm_state_free_security = selinux_xfrm_state_free,
5789 .xfrm_state_delete_security = selinux_xfrm_state_delete, 5914 .xfrm_state_delete_security = selinux_xfrm_state_delete,
5790 .xfrm_policy_lookup = selinux_xfrm_policy_lookup, 5915 .xfrm_policy_lookup = selinux_xfrm_policy_lookup,
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index aa47bcabb5f6..b1dfe1049450 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -58,8 +58,8 @@ struct superblock_security_struct {
58 u32 sid; /* SID of file system superblock */ 58 u32 sid; /* SID of file system superblock */
59 u32 def_sid; /* default SID for labeling */ 59 u32 def_sid; /* default SID for labeling */
60 u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ 60 u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */
61 unsigned int behavior; /* labeling behavior */ 61 unsigned short behavior; /* labeling behavior */
62 unsigned char flags; /* which mount options were specified */ 62 unsigned short flags; /* which mount options were specified */
63 struct mutex lock; 63 struct mutex lock;
64 struct list_head isec_head; 64 struct list_head isec_head;
65 spinlock_t isec_lock; 65 spinlock_t isec_lock;
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 8fd8e18ea340..fe341ae37004 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -45,14 +45,15 @@
45/* Mask for just the mount related flags */ 45/* Mask for just the mount related flags */
46#define SE_MNTMASK 0x0f 46#define SE_MNTMASK 0x0f
47/* Super block security struct flags for mount options */ 47/* Super block security struct flags for mount options */
48/* BE CAREFUL, these need to be the low order bits for selinux_get_mnt_opts */
48#define CONTEXT_MNT 0x01 49#define CONTEXT_MNT 0x01
49#define FSCONTEXT_MNT 0x02 50#define FSCONTEXT_MNT 0x02
50#define ROOTCONTEXT_MNT 0x04 51#define ROOTCONTEXT_MNT 0x04
51#define DEFCONTEXT_MNT 0x08 52#define DEFCONTEXT_MNT 0x08
53#define SBLABEL_MNT 0x10
52/* Non-mount related flags */ 54/* Non-mount related flags */
53#define SE_SBINITIALIZED 0x10 55#define SE_SBINITIALIZED 0x0100
54#define SE_SBPROC 0x20 56#define SE_SBPROC 0x0200
55#define SE_SBLABELSUPP 0x40
56 57
57#define CONTEXT_STR "context=" 58#define CONTEXT_STR "context="
58#define FSCONTEXT_STR "fscontext=" 59#define FSCONTEXT_STR "fscontext="
@@ -68,12 +69,15 @@ extern int selinux_enabled;
68enum { 69enum {
69 POLICYDB_CAPABILITY_NETPEER, 70 POLICYDB_CAPABILITY_NETPEER,
70 POLICYDB_CAPABILITY_OPENPERM, 71 POLICYDB_CAPABILITY_OPENPERM,
72 POLICYDB_CAPABILITY_REDHAT1,
73 POLICYDB_CAPABILITY_ALWAYSNETWORK,
71 __POLICYDB_CAPABILITY_MAX 74 __POLICYDB_CAPABILITY_MAX
72}; 75};
73#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) 76#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
74 77
75extern int selinux_policycap_netpeer; 78extern int selinux_policycap_netpeer;
76extern int selinux_policycap_openperm; 79extern int selinux_policycap_openperm;
80extern int selinux_policycap_alwaysnetwork;
77 81
78/* 82/*
79 * type_datum properties 83 * type_datum properties
@@ -172,8 +176,7 @@ int security_get_allow_unknown(void);
172#define SECURITY_FS_USE_NATIVE 7 /* use native label support */ 176#define SECURITY_FS_USE_NATIVE 7 /* use native label support */
173#define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */ 177#define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */
174 178
175int security_fs_use(const char *fstype, unsigned int *behavior, 179int security_fs_use(struct super_block *sb);
176 u32 *sid);
177 180
178int security_genfs_sid(const char *fstype, char *name, u16 sclass, 181int security_genfs_sid(const char *fstype, char *name, u16 sclass,
179 u32 *sid); 182 u32 *sid);
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 6713f04e30ba..48c3cc94c168 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -10,29 +10,21 @@
10#include <net/flow.h> 10#include <net/flow.h>
11 11
12int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, 12int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
13 struct xfrm_user_sec_ctx *sec_ctx); 13 struct xfrm_user_sec_ctx *uctx);
14int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, 14int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
15 struct xfrm_sec_ctx **new_ctxp); 15 struct xfrm_sec_ctx **new_ctxp);
16void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx); 16void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx);
17int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx); 17int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx);
18int selinux_xfrm_state_alloc(struct xfrm_state *x, 18int selinux_xfrm_state_alloc(struct xfrm_state *x,
19 struct xfrm_user_sec_ctx *sec_ctx, u32 secid); 19 struct xfrm_user_sec_ctx *uctx);
20int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
21 struct xfrm_sec_ctx *polsec, u32 secid);
20void selinux_xfrm_state_free(struct xfrm_state *x); 22void selinux_xfrm_state_free(struct xfrm_state *x);
21int selinux_xfrm_state_delete(struct xfrm_state *x); 23int selinux_xfrm_state_delete(struct xfrm_state *x);
22int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir); 24int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);
23int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, 25int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
24 struct xfrm_policy *xp, const struct flowi *fl); 26 struct xfrm_policy *xp,
25 27 const struct flowi *fl);
26/*
27 * Extract the security blob from the sock (it's actually on the socket)
28 */
29static inline struct inode_security_struct *get_sock_isec(struct sock *sk)
30{
31 if (!sk->sk_socket)
32 return NULL;
33
34 return SOCK_INODE(sk->sk_socket)->i_security;
35}
36 28
37#ifdef CONFIG_SECURITY_NETWORK_XFRM 29#ifdef CONFIG_SECURITY_NETWORK_XFRM
38extern atomic_t selinux_xfrm_refcount; 30extern atomic_t selinux_xfrm_refcount;
@@ -42,11 +34,12 @@ static inline int selinux_xfrm_enabled(void)
42 return (atomic_read(&selinux_xfrm_refcount) > 0); 34 return (atomic_read(&selinux_xfrm_refcount) > 0);
43} 35}
44 36
45int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb, 37int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
46 struct common_audit_data *ad); 38 struct common_audit_data *ad);
47int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, 39int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
48 struct common_audit_data *ad, u8 proto); 40 struct common_audit_data *ad, u8 proto);
49int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall); 41int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
42int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid);
50 43
51static inline void selinux_xfrm_notify_policyload(void) 44static inline void selinux_xfrm_notify_policyload(void)
52{ 45{
@@ -64,19 +57,21 @@ static inline int selinux_xfrm_enabled(void)
64 return 0; 57 return 0;
65} 58}
66 59
67static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, 60static inline int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
68 struct common_audit_data *ad) 61 struct common_audit_data *ad)
69{ 62{
70 return 0; 63 return 0;
71} 64}
72 65
73static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, 66static inline int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
74 struct common_audit_data *ad, u8 proto) 67 struct common_audit_data *ad,
68 u8 proto)
75{ 69{
76 return 0; 70 return 0;
77} 71}
78 72
79static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall) 73static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid,
74 int ckall)
80{ 75{
81 *sid = SECSID_NULL; 76 *sid = SECSID_NULL;
82 return 0; 77 return 0;
@@ -85,12 +80,12 @@ static inline int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int
85static inline void selinux_xfrm_notify_policyload(void) 80static inline void selinux_xfrm_notify_policyload(void)
86{ 81{
87} 82}
88#endif
89 83
90static inline void selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid) 84static inline int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
91{ 85{
92 int err = selinux_xfrm_decode_session(skb, sid, 0); 86 *sid = SECSID_NULL;
93 BUG_ON(err); 87 return 0;
94} 88}
89#endif
95 90
96#endif /* _SELINUX_XFRM_H_ */ 91#endif /* _SELINUX_XFRM_H_ */
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index da4b8b233280..6235d052338b 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -442,8 +442,7 @@ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr)
442 sksec->nlbl_state != NLBL_CONNLABELED) 442 sksec->nlbl_state != NLBL_CONNLABELED)
443 return 0; 443 return 0;
444 444
445 local_bh_disable(); 445 lock_sock(sk);
446 bh_lock_sock_nested(sk);
447 446
448 /* connected sockets are allowed to disconnect when the address family 447 /* connected sockets are allowed to disconnect when the address family
449 * is set to AF_UNSPEC, if that is what is happening we want to reset 448 * is set to AF_UNSPEC, if that is what is happening we want to reset
@@ -464,7 +463,6 @@ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr)
464 sksec->nlbl_state = NLBL_CONNLABELED; 463 sksec->nlbl_state = NLBL_CONNLABELED;
465 464
466socket_connect_return: 465socket_connect_return:
467 bh_unlock_sock(sk); 466 release_sock(sk);
468 local_bh_enable();
469 return rc; 467 return rc;
470} 468}
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index c5454c0477c3..03a72c32afd7 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -166,6 +166,7 @@ static void sel_netnode_insert(struct sel_netnode *node)
166 break; 166 break;
167 default: 167 default:
168 BUG(); 168 BUG();
169 return;
169 } 170 }
170 171
171 /* we need to impose a limit on the growth of the hash table so check 172 /* we need to impose a limit on the growth of the hash table so check
@@ -225,6 +226,7 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
225 break; 226 break;
226 default: 227 default:
227 BUG(); 228 BUG();
229 ret = -EINVAL;
228 } 230 }
229 if (ret != 0) 231 if (ret != 0)
230 goto out; 232 goto out;
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 855e464e92ef..332ac8a80cf5 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -116,6 +116,8 @@ static struct nlmsg_perm nlmsg_audit_perms[] =
116 { AUDIT_MAKE_EQUIV, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, 116 { AUDIT_MAKE_EQUIV, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
117 { AUDIT_TTY_GET, NETLINK_AUDIT_SOCKET__NLMSG_READ }, 117 { AUDIT_TTY_GET, NETLINK_AUDIT_SOCKET__NLMSG_READ },
118 { AUDIT_TTY_SET, NETLINK_AUDIT_SOCKET__NLMSG_TTY_AUDIT }, 118 { AUDIT_TTY_SET, NETLINK_AUDIT_SOCKET__NLMSG_TTY_AUDIT },
119 { AUDIT_GET_FEATURE, NETLINK_AUDIT_SOCKET__NLMSG_READ },
120 { AUDIT_SET_FEATURE, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
119}; 121};
120 122
121 123
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index ff427733c290..5122affe06a8 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -44,7 +44,9 @@
44/* Policy capability filenames */ 44/* Policy capability filenames */
45static char *policycap_names[] = { 45static char *policycap_names[] = {
46 "network_peer_controls", 46 "network_peer_controls",
47 "open_perms" 47 "open_perms",
48 "redhat1",
49 "always_check_network"
48}; 50};
49 51
50unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; 52unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 30f119b1d1ec..820313a04d49 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -213,7 +213,12 @@ netlbl_import_failure:
213} 213}
214#endif /* CONFIG_NETLABEL */ 214#endif /* CONFIG_NETLABEL */
215 215
216int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2) 216/*
217 * Check to see if all the bits set in e2 are also set in e1. Optionally,
218 * if last_e2bit is non-zero, the highest set bit in e2 cannot exceed
219 * last_e2bit.
220 */
221int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2, u32 last_e2bit)
217{ 222{
218 struct ebitmap_node *n1, *n2; 223 struct ebitmap_node *n1, *n2;
219 int i; 224 int i;
@@ -223,14 +228,25 @@ int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)
223 228
224 n1 = e1->node; 229 n1 = e1->node;
225 n2 = e2->node; 230 n2 = e2->node;
231
226 while (n1 && n2 && (n1->startbit <= n2->startbit)) { 232 while (n1 && n2 && (n1->startbit <= n2->startbit)) {
227 if (n1->startbit < n2->startbit) { 233 if (n1->startbit < n2->startbit) {
228 n1 = n1->next; 234 n1 = n1->next;
229 continue; 235 continue;
230 } 236 }
231 for (i = 0; i < EBITMAP_UNIT_NUMS; i++) { 237 for (i = EBITMAP_UNIT_NUMS - 1; (i >= 0) && !n2->maps[i]; )
238 i--; /* Skip trailing NULL map entries */
239 if (last_e2bit && (i >= 0)) {
240 u32 lastsetbit = n2->startbit + i * EBITMAP_UNIT_SIZE +
241 __fls(n2->maps[i]);
242 if (lastsetbit > last_e2bit)
243 return 0;
244 }
245
246 while (i >= 0) {
232 if ((n1->maps[i] & n2->maps[i]) != n2->maps[i]) 247 if ((n1->maps[i] & n2->maps[i]) != n2->maps[i])
233 return 0; 248 return 0;
249 i--;
234 } 250 }
235 251
236 n1 = n1->next; 252 n1 = n1->next;
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index 922f8afa89dd..712c8a7b8e8b 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -16,7 +16,13 @@
16 16
17#include <net/netlabel.h> 17#include <net/netlabel.h>
18 18
19#define EBITMAP_UNIT_NUMS ((32 - sizeof(void *) - sizeof(u32)) \ 19#ifdef CONFIG_64BIT
20#define EBITMAP_NODE_SIZE 64
21#else
22#define EBITMAP_NODE_SIZE 32
23#endif
24
25#define EBITMAP_UNIT_NUMS ((EBITMAP_NODE_SIZE-sizeof(void *)-sizeof(u32))\
20 / sizeof(unsigned long)) 26 / sizeof(unsigned long))
21#define EBITMAP_UNIT_SIZE BITS_PER_LONG 27#define EBITMAP_UNIT_SIZE BITS_PER_LONG
22#define EBITMAP_SIZE (EBITMAP_UNIT_NUMS * EBITMAP_UNIT_SIZE) 28#define EBITMAP_SIZE (EBITMAP_UNIT_NUMS * EBITMAP_UNIT_SIZE)
@@ -117,7 +123,7 @@ static inline void ebitmap_node_clr_bit(struct ebitmap_node *n,
117 123
118int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2); 124int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2);
119int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src); 125int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src);
120int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2); 126int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2, u32 last_e2bit);
121int ebitmap_get_bit(struct ebitmap *e, unsigned long bit); 127int ebitmap_get_bit(struct ebitmap *e, unsigned long bit);
122int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value); 128int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value);
123void ebitmap_destroy(struct ebitmap *e); 129void ebitmap_destroy(struct ebitmap *e);
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 40de8d3f208e..c85bc1ec040c 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -160,8 +160,6 @@ void mls_sid_to_context(struct context *context,
160int mls_level_isvalid(struct policydb *p, struct mls_level *l) 160int mls_level_isvalid(struct policydb *p, struct mls_level *l)
161{ 161{
162 struct level_datum *levdatum; 162 struct level_datum *levdatum;
163 struct ebitmap_node *node;
164 int i;
165 163
166 if (!l->sens || l->sens > p->p_levels.nprim) 164 if (!l->sens || l->sens > p->p_levels.nprim)
167 return 0; 165 return 0;
@@ -170,19 +168,13 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l)
170 if (!levdatum) 168 if (!levdatum)
171 return 0; 169 return 0;
172 170
173 ebitmap_for_each_positive_bit(&l->cat, node, i) { 171 /*
174 if (i > p->p_cats.nprim) 172 * Return 1 iff all the bits set in l->cat are also be set in
175 return 0; 173 * levdatum->level->cat and no bit in l->cat is larger than
176 if (!ebitmap_get_bit(&levdatum->level->cat, i)) { 174 * p->p_cats.nprim.
177 /* 175 */
178 * Category may not be associated with 176 return ebitmap_contains(&levdatum->level->cat, &l->cat,
179 * sensitivity. 177 p->p_cats.nprim);
180 */
181 return 0;
182 }
183 }
184
185 return 1;
186} 178}
187 179
188int mls_range_isvalid(struct policydb *p, struct mls_range *r) 180int mls_range_isvalid(struct policydb *p, struct mls_range *r)
diff --git a/security/selinux/ss/mls_types.h b/security/selinux/ss/mls_types.h
index 03bed52a8052..e93648774137 100644
--- a/security/selinux/ss/mls_types.h
+++ b/security/selinux/ss/mls_types.h
@@ -35,7 +35,7 @@ static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
35static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) 35static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
36{ 36{
37 return ((l1->sens >= l2->sens) && 37 return ((l1->sens >= l2->sens) &&
38 ebitmap_contains(&l1->cat, &l2->cat)); 38 ebitmap_contains(&l1->cat, &l2->cat, 0));
39} 39}
40 40
41#define mls_level_incomp(l1, l2) \ 41#define mls_level_incomp(l1, l2) \
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index c8adde3aff8f..f6195ebde3c9 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -3203,9 +3203,8 @@ static int range_write_helper(void *key, void *data, void *ptr)
3203 3203
3204static int range_write(struct policydb *p, void *fp) 3204static int range_write(struct policydb *p, void *fp)
3205{ 3205{
3206 size_t nel;
3207 __le32 buf[1]; 3206 __le32 buf[1];
3208 int rc; 3207 int rc, nel;
3209 struct policy_data pd; 3208 struct policy_data pd;
3210 3209
3211 pd.p = p; 3210 pd.p = p;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index b4feecc3fe01..d106733ad987 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -72,6 +72,7 @@
72 72
73int selinux_policycap_netpeer; 73int selinux_policycap_netpeer;
74int selinux_policycap_openperm; 74int selinux_policycap_openperm;
75int selinux_policycap_alwaysnetwork;
75 76
76static DEFINE_RWLOCK(policy_rwlock); 77static DEFINE_RWLOCK(policy_rwlock);
77 78
@@ -1812,6 +1813,8 @@ static void security_load_policycaps(void)
1812 POLICYDB_CAPABILITY_NETPEER); 1813 POLICYDB_CAPABILITY_NETPEER);
1813 selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps, 1814 selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps,
1814 POLICYDB_CAPABILITY_OPENPERM); 1815 POLICYDB_CAPABILITY_OPENPERM);
1816 selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps,
1817 POLICYDB_CAPABILITY_ALWAYSNETWORK);
1815} 1818}
1816 1819
1817static int security_preserve_bools(struct policydb *p); 1820static int security_preserve_bools(struct policydb *p);
@@ -2323,17 +2326,14 @@ out:
2323 2326
2324/** 2327/**
2325 * security_fs_use - Determine how to handle labeling for a filesystem. 2328 * security_fs_use - Determine how to handle labeling for a filesystem.
2326 * @fstype: filesystem type 2329 * @sb: superblock in question
2327 * @behavior: labeling behavior
2328 * @sid: SID for filesystem (superblock)
2329 */ 2330 */
2330int security_fs_use( 2331int security_fs_use(struct super_block *sb)
2331 const char *fstype,
2332 unsigned int *behavior,
2333 u32 *sid)
2334{ 2332{
2335 int rc = 0; 2333 int rc = 0;
2336 struct ocontext *c; 2334 struct ocontext *c;
2335 struct superblock_security_struct *sbsec = sb->s_security;
2336 const char *fstype = sb->s_type->name;
2337 2337
2338 read_lock(&policy_rwlock); 2338 read_lock(&policy_rwlock);
2339 2339
@@ -2345,21 +2345,21 @@ int security_fs_use(
2345 } 2345 }
2346 2346
2347 if (c) { 2347 if (c) {
2348 *behavior = c->v.behavior; 2348 sbsec->behavior = c->v.behavior;
2349 if (!c->sid[0]) { 2349 if (!c->sid[0]) {
2350 rc = sidtab_context_to_sid(&sidtab, &c->context[0], 2350 rc = sidtab_context_to_sid(&sidtab, &c->context[0],
2351 &c->sid[0]); 2351 &c->sid[0]);
2352 if (rc) 2352 if (rc)
2353 goto out; 2353 goto out;
2354 } 2354 }
2355 *sid = c->sid[0]; 2355 sbsec->sid = c->sid[0];
2356 } else { 2356 } else {
2357 rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, sid); 2357 rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, &sbsec->sid);
2358 if (rc) { 2358 if (rc) {
2359 *behavior = SECURITY_FS_USE_NONE; 2359 sbsec->behavior = SECURITY_FS_USE_NONE;
2360 rc = 0; 2360 rc = 0;
2361 } else { 2361 } else {
2362 *behavior = SECURITY_FS_USE_GENFS; 2362 sbsec->behavior = SECURITY_FS_USE_GENFS;
2363 } 2363 }
2364 } 2364 }
2365 2365
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index d03081886214..0462cb3ff0a7 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -56,7 +56,7 @@
56atomic_t selinux_xfrm_refcount = ATOMIC_INIT(0); 56atomic_t selinux_xfrm_refcount = ATOMIC_INIT(0);
57 57
58/* 58/*
59 * Returns true if an LSM/SELinux context 59 * Returns true if the context is an LSM/SELinux context.
60 */ 60 */
61static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx) 61static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx)
62{ 62{
@@ -66,7 +66,7 @@ static inline int selinux_authorizable_ctx(struct xfrm_sec_ctx *ctx)
66} 66}
67 67
68/* 68/*
69 * Returns true if the xfrm contains a security blob for SELinux 69 * Returns true if the xfrm contains a security blob for SELinux.
70 */ 70 */
71static inline int selinux_authorizable_xfrm(struct xfrm_state *x) 71static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
72{ 72{
@@ -74,48 +74,111 @@ static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
74} 74}
75 75
76/* 76/*
77 * LSM hook implementation that authorizes that a flow can use 77 * Allocates a xfrm_sec_state and populates it using the supplied security
78 * a xfrm policy rule. 78 * xfrm_user_sec_ctx context.
79 */ 79 */
80int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir) 80static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp,
81 struct xfrm_user_sec_ctx *uctx)
81{ 82{
82 int rc; 83 int rc;
83 u32 sel_sid; 84 const struct task_security_struct *tsec = current_security();
85 struct xfrm_sec_ctx *ctx = NULL;
86 u32 str_len;
84 87
85 /* Context sid is either set to label or ANY_ASSOC */ 88 if (ctxp == NULL || uctx == NULL ||
86 if (ctx) { 89 uctx->ctx_doi != XFRM_SC_DOI_LSM ||
87 if (!selinux_authorizable_ctx(ctx)) 90 uctx->ctx_alg != XFRM_SC_ALG_SELINUX)
88 return -EINVAL; 91 return -EINVAL;
89 92
90 sel_sid = ctx->ctx_sid; 93 str_len = uctx->ctx_len;
91 } else 94 if (str_len >= PAGE_SIZE)
92 /* 95 return -ENOMEM;
93 * All flows should be treated as polmatch'ing an 96
94 * otherwise applicable "non-labeled" policy. This 97 ctx = kmalloc(sizeof(*ctx) + str_len + 1, GFP_KERNEL);
95 * would prevent inadvertent "leaks". 98 if (!ctx)
96 */ 99 return -ENOMEM;
97 return 0;
98 100
99 rc = avc_has_perm(fl_secid, sel_sid, SECCLASS_ASSOCIATION, 101 ctx->ctx_doi = XFRM_SC_DOI_LSM;
100 ASSOCIATION__POLMATCH, 102 ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
101 NULL); 103 ctx->ctx_len = str_len;
104 memcpy(ctx->ctx_str, &uctx[1], str_len);
105 ctx->ctx_str[str_len] = '\0';
106 rc = security_context_to_sid(ctx->ctx_str, str_len, &ctx->ctx_sid);
107 if (rc)
108 goto err;
102 109
103 if (rc == -EACCES) 110 rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
104 return -ESRCH; 111 SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, NULL);
112 if (rc)
113 goto err;
105 114
115 *ctxp = ctx;
116 atomic_inc(&selinux_xfrm_refcount);
117 return 0;
118
119err:
120 kfree(ctx);
106 return rc; 121 return rc;
107} 122}
108 123
109/* 124/*
125 * Free the xfrm_sec_ctx structure.
126 */
127static void selinux_xfrm_free(struct xfrm_sec_ctx *ctx)
128{
129 if (!ctx)
130 return;
131
132 atomic_dec(&selinux_xfrm_refcount);
133 kfree(ctx);
134}
135
136/*
137 * Authorize the deletion of a labeled SA or policy rule.
138 */
139static int selinux_xfrm_delete(struct xfrm_sec_ctx *ctx)
140{
141 const struct task_security_struct *tsec = current_security();
142
143 if (!ctx)
144 return 0;
145
146 return avc_has_perm(tsec->sid, ctx->ctx_sid,
147 SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT,
148 NULL);
149}
150
151/*
152 * LSM hook implementation that authorizes that a flow can use a xfrm policy
153 * rule.
154 */
155int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir)
156{
157 int rc;
158
159 /* All flows should be treated as polmatch'ing an otherwise applicable
160 * "non-labeled" policy. This would prevent inadvertent "leaks". */
161 if (!ctx)
162 return 0;
163
164 /* Context sid is either set to label or ANY_ASSOC */
165 if (!selinux_authorizable_ctx(ctx))
166 return -EINVAL;
167
168 rc = avc_has_perm(fl_secid, ctx->ctx_sid,
169 SECCLASS_ASSOCIATION, ASSOCIATION__POLMATCH, NULL);
170 return (rc == -EACCES ? -ESRCH : rc);
171}
172
173/*
110 * LSM hook implementation that authorizes that a state matches 174 * LSM hook implementation that authorizes that a state matches
111 * the given policy, flow combo. 175 * the given policy, flow combo.
112 */ 176 */
113 177int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
114int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *xp, 178 struct xfrm_policy *xp,
115 const struct flowi *fl) 179 const struct flowi *fl)
116{ 180{
117 u32 state_sid; 181 u32 state_sid;
118 int rc;
119 182
120 if (!xp->security) 183 if (!xp->security)
121 if (x->security) 184 if (x->security)
@@ -138,187 +201,111 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
138 if (fl->flowi_secid != state_sid) 201 if (fl->flowi_secid != state_sid)
139 return 0; 202 return 0;
140 203
141 rc = avc_has_perm(fl->flowi_secid, state_sid, SECCLASS_ASSOCIATION, 204 /* We don't need a separate SA Vs. policy polmatch check since the SA
142 ASSOCIATION__SENDTO, 205 * is now of the same label as the flow and a flow Vs. policy polmatch
143 NULL)? 0:1; 206 * check had already happened in selinux_xfrm_policy_lookup() above. */
144 207 return (avc_has_perm(fl->flowi_secid, state_sid,
145 /* 208 SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO,
146 * We don't need a separate SA Vs. policy polmatch check 209 NULL) ? 0 : 1);
147 * since the SA is now of the same label as the flow and
148 * a flow Vs. policy polmatch check had already happened
149 * in selinux_xfrm_policy_lookup() above.
150 */
151
152 return rc;
153} 210}
154 211
155/* 212static u32 selinux_xfrm_skb_sid_egress(struct sk_buff *skb)
156 * LSM hook implementation that checks and/or returns the xfrm sid for the
157 * incoming packet.
158 */
159
160int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
161{ 213{
162 struct sec_path *sp; 214 struct dst_entry *dst = skb_dst(skb);
215 struct xfrm_state *x;
163 216
164 *sid = SECSID_NULL; 217 if (dst == NULL)
218 return SECSID_NULL;
219 x = dst->xfrm;
220 if (x == NULL || !selinux_authorizable_xfrm(x))
221 return SECSID_NULL;
165 222
166 if (skb == NULL) 223 return x->security->ctx_sid;
167 return 0; 224}
225
226static int selinux_xfrm_skb_sid_ingress(struct sk_buff *skb,
227 u32 *sid, int ckall)
228{
229 u32 sid_session = SECSID_NULL;
230 struct sec_path *sp = skb->sp;
168 231
169 sp = skb->sp;
170 if (sp) { 232 if (sp) {
171 int i, sid_set = 0; 233 int i;
172 234
173 for (i = sp->len-1; i >= 0; i--) { 235 for (i = sp->len - 1; i >= 0; i--) {
174 struct xfrm_state *x = sp->xvec[i]; 236 struct xfrm_state *x = sp->xvec[i];
175 if (selinux_authorizable_xfrm(x)) { 237 if (selinux_authorizable_xfrm(x)) {
176 struct xfrm_sec_ctx *ctx = x->security; 238 struct xfrm_sec_ctx *ctx = x->security;
177 239
178 if (!sid_set) { 240 if (sid_session == SECSID_NULL) {
179 *sid = ctx->ctx_sid; 241 sid_session = ctx->ctx_sid;
180 sid_set = 1;
181
182 if (!ckall) 242 if (!ckall)
183 break; 243 goto out;
184 } else if (*sid != ctx->ctx_sid) 244 } else if (sid_session != ctx->ctx_sid) {
245 *sid = SECSID_NULL;
185 return -EINVAL; 246 return -EINVAL;
247 }
186 } 248 }
187 } 249 }
188 } 250 }
189 251
252out:
253 *sid = sid_session;
190 return 0; 254 return 0;
191} 255}
192 256
193/* 257/*
194 * Security blob allocation for xfrm_policy and xfrm_state 258 * LSM hook implementation that checks and/or returns the xfrm sid for the
195 * CTX does not have a meaningful value on input 259 * incoming packet.
196 */ 260 */
197static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, 261int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
198 struct xfrm_user_sec_ctx *uctx, u32 sid)
199{ 262{
200 int rc = 0; 263 if (skb == NULL) {
201 const struct task_security_struct *tsec = current_security(); 264 *sid = SECSID_NULL;
202 struct xfrm_sec_ctx *ctx = NULL; 265 return 0;
203 char *ctx_str = NULL;
204 u32 str_len;
205
206 BUG_ON(uctx && sid);
207
208 if (!uctx)
209 goto not_from_user;
210
211 if (uctx->ctx_alg != XFRM_SC_ALG_SELINUX)
212 return -EINVAL;
213
214 str_len = uctx->ctx_len;
215 if (str_len >= PAGE_SIZE)
216 return -ENOMEM;
217
218 *ctxp = ctx = kmalloc(sizeof(*ctx) +
219 str_len + 1,
220 GFP_KERNEL);
221
222 if (!ctx)
223 return -ENOMEM;
224
225 ctx->ctx_doi = uctx->ctx_doi;
226 ctx->ctx_len = str_len;
227 ctx->ctx_alg = uctx->ctx_alg;
228
229 memcpy(ctx->ctx_str,
230 uctx+1,
231 str_len);
232 ctx->ctx_str[str_len] = 0;
233 rc = security_context_to_sid(ctx->ctx_str,
234 str_len,
235 &ctx->ctx_sid);
236
237 if (rc)
238 goto out;
239
240 /*
241 * Does the subject have permission to set security context?
242 */
243 rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
244 SECCLASS_ASSOCIATION,
245 ASSOCIATION__SETCONTEXT, NULL);
246 if (rc)
247 goto out;
248
249 return rc;
250
251not_from_user:
252 rc = security_sid_to_context(sid, &ctx_str, &str_len);
253 if (rc)
254 goto out;
255
256 *ctxp = ctx = kmalloc(sizeof(*ctx) +
257 str_len,
258 GFP_ATOMIC);
259
260 if (!ctx) {
261 rc = -ENOMEM;
262 goto out;
263 } 266 }
267 return selinux_xfrm_skb_sid_ingress(skb, sid, ckall);
268}
264 269
265 ctx->ctx_doi = XFRM_SC_DOI_LSM; 270int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
266 ctx->ctx_alg = XFRM_SC_ALG_SELINUX; 271{
267 ctx->ctx_sid = sid; 272 int rc;
268 ctx->ctx_len = str_len;
269 memcpy(ctx->ctx_str,
270 ctx_str,
271 str_len);
272 273
273 goto out2; 274 rc = selinux_xfrm_skb_sid_ingress(skb, sid, 0);
275 if (rc == 0 && *sid == SECSID_NULL)
276 *sid = selinux_xfrm_skb_sid_egress(skb);
274 277
275out:
276 *ctxp = NULL;
277 kfree(ctx);
278out2:
279 kfree(ctx_str);
280 return rc; 278 return rc;
281} 279}
282 280
283/* 281/*
284 * LSM hook implementation that allocs and transfers uctx spec to 282 * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy.
285 * xfrm_policy.
286 */ 283 */
287int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, 284int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
288 struct xfrm_user_sec_ctx *uctx) 285 struct xfrm_user_sec_ctx *uctx)
289{ 286{
290 int err; 287 return selinux_xfrm_alloc_user(ctxp, uctx);
291
292 BUG_ON(!uctx);
293
294 err = selinux_xfrm_sec_ctx_alloc(ctxp, uctx, 0);
295 if (err == 0)
296 atomic_inc(&selinux_xfrm_refcount);
297
298 return err;
299} 288}
300 289
301
302/* 290/*
303 * LSM hook implementation that copies security data structure from old to 291 * LSM hook implementation that copies security data structure from old to new
304 * new for policy cloning. 292 * for policy cloning.
305 */ 293 */
306int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, 294int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
307 struct xfrm_sec_ctx **new_ctxp) 295 struct xfrm_sec_ctx **new_ctxp)
308{ 296{
309 struct xfrm_sec_ctx *new_ctx; 297 struct xfrm_sec_ctx *new_ctx;
310 298
311 if (old_ctx) { 299 if (!old_ctx)
312 new_ctx = kmalloc(sizeof(*old_ctx) + old_ctx->ctx_len, 300 return 0;
313 GFP_ATOMIC); 301
314 if (!new_ctx) 302 new_ctx = kmemdup(old_ctx, sizeof(*old_ctx) + old_ctx->ctx_len,
315 return -ENOMEM; 303 GFP_ATOMIC);
304 if (!new_ctx)
305 return -ENOMEM;
306 atomic_inc(&selinux_xfrm_refcount);
307 *new_ctxp = new_ctx;
316 308
317 memcpy(new_ctx, old_ctx, sizeof(*new_ctx));
318 memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len);
319 atomic_inc(&selinux_xfrm_refcount);
320 *new_ctxp = new_ctx;
321 }
322 return 0; 309 return 0;
323} 310}
324 311
@@ -327,8 +314,7 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
327 */ 314 */
328void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx) 315void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
329{ 316{
330 atomic_dec(&selinux_xfrm_refcount); 317 selinux_xfrm_free(ctx);
331 kfree(ctx);
332} 318}
333 319
334/* 320/*
@@ -336,31 +322,58 @@ void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
336 */ 322 */
337int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) 323int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
338{ 324{
339 const struct task_security_struct *tsec = current_security(); 325 return selinux_xfrm_delete(ctx);
340 326}
341 if (!ctx)
342 return 0;
343 327
344 return avc_has_perm(tsec->sid, ctx->ctx_sid, 328/*
345 SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, 329 * LSM hook implementation that allocates a xfrm_sec_state, populates it using
346 NULL); 330 * the supplied security context, and assigns it to the xfrm_state.
331 */
332int selinux_xfrm_state_alloc(struct xfrm_state *x,
333 struct xfrm_user_sec_ctx *uctx)
334{
335 return selinux_xfrm_alloc_user(&x->security, uctx);
347} 336}
348 337
349/* 338/*
350 * LSM hook implementation that allocs and transfers sec_ctx spec to 339 * LSM hook implementation that allocates a xfrm_sec_state and populates based
351 * xfrm_state. 340 * on a secid.
352 */ 341 */
353int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uctx, 342int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
354 u32 secid) 343 struct xfrm_sec_ctx *polsec, u32 secid)
355{ 344{
356 int err; 345 int rc;
346 struct xfrm_sec_ctx *ctx;
347 char *ctx_str = NULL;
348 int str_len;
349
350 if (!polsec)
351 return 0;
352
353 if (secid == 0)
354 return -EINVAL;
355
356 rc = security_sid_to_context(secid, &ctx_str, &str_len);
357 if (rc)
358 return rc;
357 359
358 BUG_ON(!x); 360 ctx = kmalloc(sizeof(*ctx) + str_len, GFP_ATOMIC);
361 if (!ctx) {
362 rc = -ENOMEM;
363 goto out;
364 }
359 365
360 err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx, secid); 366 ctx->ctx_doi = XFRM_SC_DOI_LSM;
361 if (err == 0) 367 ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
362 atomic_inc(&selinux_xfrm_refcount); 368 ctx->ctx_sid = secid;
363 return err; 369 ctx->ctx_len = str_len;
370 memcpy(ctx->ctx_str, ctx_str, str_len);
371
372 x->security = ctx;
373 atomic_inc(&selinux_xfrm_refcount);
374out:
375 kfree(ctx_str);
376 return rc;
364} 377}
365 378
366/* 379/*
@@ -368,24 +381,15 @@ int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uct
368 */ 381 */
369void selinux_xfrm_state_free(struct xfrm_state *x) 382void selinux_xfrm_state_free(struct xfrm_state *x)
370{ 383{
371 atomic_dec(&selinux_xfrm_refcount); 384 selinux_xfrm_free(x->security);
372 kfree(x->security);
373} 385}
374 386
375 /* 387/*
376 * LSM hook implementation that authorizes deletion of labeled SAs. 388 * LSM hook implementation that authorizes deletion of labeled SAs.
377 */ 389 */
378int selinux_xfrm_state_delete(struct xfrm_state *x) 390int selinux_xfrm_state_delete(struct xfrm_state *x)
379{ 391{
380 const struct task_security_struct *tsec = current_security(); 392 return selinux_xfrm_delete(x->security);
381 struct xfrm_sec_ctx *ctx = x->security;
382
383 if (!ctx)
384 return 0;
385
386 return avc_has_perm(tsec->sid, ctx->ctx_sid,
387 SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT,
388 NULL);
389} 393}
390 394
391/* 395/*
@@ -395,14 +399,12 @@ int selinux_xfrm_state_delete(struct xfrm_state *x)
395 * we need to check for unlabelled access since this may not have 399 * we need to check for unlabelled access since this may not have
396 * gone thru the IPSec process. 400 * gone thru the IPSec process.
397 */ 401 */
398int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, 402int selinux_xfrm_sock_rcv_skb(u32 sk_sid, struct sk_buff *skb,
399 struct common_audit_data *ad) 403 struct common_audit_data *ad)
400{ 404{
401 int i, rc = 0; 405 int i;
402 struct sec_path *sp; 406 struct sec_path *sp = skb->sp;
403 u32 sel_sid = SECINITSID_UNLABELED; 407 u32 peer_sid = SECINITSID_UNLABELED;
404
405 sp = skb->sp;
406 408
407 if (sp) { 409 if (sp) {
408 for (i = 0; i < sp->len; i++) { 410 for (i = 0; i < sp->len; i++) {
@@ -410,23 +412,17 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
410 412
411 if (x && selinux_authorizable_xfrm(x)) { 413 if (x && selinux_authorizable_xfrm(x)) {
412 struct xfrm_sec_ctx *ctx = x->security; 414 struct xfrm_sec_ctx *ctx = x->security;
413 sel_sid = ctx->ctx_sid; 415 peer_sid = ctx->ctx_sid;
414 break; 416 break;
415 } 417 }
416 } 418 }
417 } 419 }
418 420
419 /* 421 /* This check even when there's no association involved is intended,
420 * This check even when there's no association involved is 422 * according to Trent Jaeger, to make sure a process can't engage in
421 * intended, according to Trent Jaeger, to make sure a 423 * non-IPsec communication unless explicitly allowed by policy. */
422 * process can't engage in non-ipsec communication unless 424 return avc_has_perm(sk_sid, peer_sid,
423 * explicitly allowed by policy. 425 SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, ad);
424 */
425
426 rc = avc_has_perm(isec_sid, sel_sid, SECCLASS_ASSOCIATION,
427 ASSOCIATION__RECVFROM, ad);
428
429 return rc;
430} 426}
431 427
432/* 428/*
@@ -436,49 +432,38 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb,
436 * If we do have a authorizable security association, then it has already been 432 * If we do have a authorizable security association, then it has already been
437 * checked in the selinux_xfrm_state_pol_flow_match hook above. 433 * checked in the selinux_xfrm_state_pol_flow_match hook above.
438 */ 434 */
439int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, 435int selinux_xfrm_postroute_last(u32 sk_sid, struct sk_buff *skb,
440 struct common_audit_data *ad, u8 proto) 436 struct common_audit_data *ad, u8 proto)
441{ 437{
442 struct dst_entry *dst; 438 struct dst_entry *dst;
443 int rc = 0;
444
445 dst = skb_dst(skb);
446
447 if (dst) {
448 struct dst_entry *dst_test;
449
450 for (dst_test = dst; dst_test != NULL;
451 dst_test = dst_test->child) {
452 struct xfrm_state *x = dst_test->xfrm;
453
454 if (x && selinux_authorizable_xfrm(x))
455 goto out;
456 }
457 }
458 439
459 switch (proto) { 440 switch (proto) {
460 case IPPROTO_AH: 441 case IPPROTO_AH:
461 case IPPROTO_ESP: 442 case IPPROTO_ESP:
462 case IPPROTO_COMP: 443 case IPPROTO_COMP:
463 /* 444 /* We should have already seen this packet once before it
464 * We should have already seen this packet once before 445 * underwent xfrm(s). No need to subject it to the unlabeled
465 * it underwent xfrm(s). No need to subject it to the 446 * check. */
466 * unlabeled check. 447 return 0;
467 */
468 goto out;
469 default: 448 default:
470 break; 449 break;
471 } 450 }
472 451
473 /* 452 dst = skb_dst(skb);
474 * This check even when there's no association involved is 453 if (dst) {
475 * intended, according to Trent Jaeger, to make sure a 454 struct dst_entry *iter;
476 * process can't engage in non-ipsec communication unless
477 * explicitly allowed by policy.
478 */
479 455
480 rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION, 456 for (iter = dst; iter != NULL; iter = iter->child) {
481 ASSOCIATION__SENDTO, ad); 457 struct xfrm_state *x = iter->xfrm;
482out: 458
483 return rc; 459 if (x && selinux_authorizable_xfrm(x))
460 return 0;
461 }
462 }
463
464 /* This check even when there's no association involved is intended,
465 * according to Trent Jaeger, to make sure a process can't engage in
466 * non-IPsec communication unless explicitly allowed by policy. */
467 return avc_has_perm(sk_sid, SECINITSID_UNLABELED,
468 SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, ad);
484} 469}