aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c253
1 files changed, 189 insertions, 64 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 5b5231068516..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,
@@ -3928,7 +3990,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
3928 if (snum) { 3990 if (snum) {
3929 int low, high; 3991 int low, high;
3930 3992
3931 inet_get_local_port_range(&low, &high); 3993 inet_get_local_port_range(sock_net(sk), &low, &high);
3932 3994
3933 if (snum < max(PROT_SOCK, low) || snum > high) { 3995 if (snum < max(PROT_SOCK, low) || snum > high) {
3934 err = sel_netport_sid(sk->sk_protocol, 3996 err = sel_netport_sid(sk->sk_protocol,
@@ -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
@@ -4667,7 +4724,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
4667 return NF_ACCEPT; 4724 return NF_ACCEPT;
4668} 4725}
4669 4726
4670static unsigned int selinux_ipv4_forward(unsigned int hooknum, 4727static unsigned int selinux_ipv4_forward(const struct nf_hook_ops *ops,
4671 struct sk_buff *skb, 4728 struct sk_buff *skb,
4672 const struct net_device *in, 4729 const struct net_device *in,
4673 const struct net_device *out, 4730 const struct net_device *out,
@@ -4677,7 +4734,7 @@ static unsigned int selinux_ipv4_forward(unsigned int hooknum,
4677} 4734}
4678 4735
4679#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 4736#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
4680static unsigned int selinux_ipv6_forward(unsigned int hooknum, 4737static unsigned int selinux_ipv6_forward(const struct nf_hook_ops *ops,
4681 struct sk_buff *skb, 4738 struct sk_buff *skb,
4682 const struct net_device *in, 4739 const struct net_device *in,
4683 const struct net_device *out, 4740 const struct net_device *out,
@@ -4690,6 +4747,7 @@ static unsigned int selinux_ipv6_forward(unsigned int hooknum,
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;
@@ -4709,7 +4786,7 @@ static unsigned int selinux_ip_output(struct sk_buff *skb,
4709 return NF_ACCEPT; 4786 return NF_ACCEPT;
4710} 4787}
4711 4788
4712static unsigned int selinux_ipv4_output(unsigned int hooknum, 4789static unsigned int selinux_ipv4_output(const struct nf_hook_ops *ops,
4713 struct sk_buff *skb, 4790 struct sk_buff *skb,
4714 const struct net_device *in, 4791 const struct net_device *in,
4715 const struct net_device *out, 4792 const struct net_device *out,
@@ -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;
@@ -4836,7 +4960,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4836 return NF_ACCEPT; 4960 return NF_ACCEPT;
4837} 4961}
4838 4962
4839static unsigned int selinux_ipv4_postroute(unsigned int hooknum, 4963static unsigned int selinux_ipv4_postroute(const struct nf_hook_ops *ops,
4840 struct sk_buff *skb, 4964 struct sk_buff *skb,
4841 const struct net_device *in, 4965 const struct net_device *in,
4842 const struct net_device *out, 4966 const struct net_device *out,
@@ -4846,7 +4970,7 @@ static unsigned int selinux_ipv4_postroute(unsigned int hooknum,
4846} 4970}
4847 4971
4848#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 4972#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
4849static unsigned int selinux_ipv6_postroute(unsigned int hooknum, 4973static unsigned int selinux_ipv6_postroute(const struct nf_hook_ops *ops,
4850 struct sk_buff *skb, 4974 struct sk_buff *skb,
4851 const struct net_device *in, 4975 const struct net_device *in,
4852 const struct net_device *out, 4976 const struct net_device *out,
@@ -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,