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.c146
1 files changed, 94 insertions, 52 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c540795fb3f2..794c3ca49eac 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -95,7 +95,9 @@
95#include "audit.h" 95#include "audit.h"
96#include "avc_ss.h" 96#include "avc_ss.h"
97 97
98#define NUM_SEL_MNT_OPTS 5 98#define SB_TYPE_FMT "%s%s%s"
99#define SB_SUBTYPE(sb) (sb->s_subtype && sb->s_subtype[0])
100#define SB_TYPE_ARGS(sb) sb->s_type->name, SB_SUBTYPE(sb) ? "." : "", SB_SUBTYPE(sb) ? sb->s_subtype : ""
99 101
100extern struct security_operations *security_ops; 102extern struct security_operations *security_ops;
101 103
@@ -139,12 +141,28 @@ static struct kmem_cache *sel_inode_cache;
139 * This function checks the SECMARK reference counter to see if any SECMARK 141 * This function checks the SECMARK reference counter to see if any SECMARK
140 * targets are currently configured, if the reference counter is greater than 142 * 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 143 * zero SECMARK is considered to be enabled. Returns true (1) if SECMARK is
142 * enabled, false (0) if SECMARK is disabled. 144 * enabled, false (0) if SECMARK is disabled. If the always_check_network
145 * policy capability is enabled, SECMARK is always considered enabled.
143 * 146 *
144 */ 147 */
145static int selinux_secmark_enabled(void) 148static int selinux_secmark_enabled(void)
146{ 149{
147 return (atomic_read(&selinux_secmark_refcount) > 0); 150 return (selinux_policycap_alwaysnetwork || atomic_read(&selinux_secmark_refcount));
151}
152
153/**
154 * selinux_peerlbl_enabled - Check to see if peer labeling is currently enabled
155 *
156 * Description:
157 * This function checks if NetLabel or labeled IPSEC is enabled. Returns true
158 * (1) if any are enabled or false (0) if neither are enabled. If the
159 * always_check_network policy capability is enabled, peer labeling
160 * is always considered enabled.
161 *
162 */
163static int selinux_peerlbl_enabled(void)
164{
165 return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
148} 166}
149 167
150/* 168/*
@@ -309,8 +327,11 @@ enum {
309 Opt_defcontext = 3, 327 Opt_defcontext = 3,
310 Opt_rootcontext = 4, 328 Opt_rootcontext = 4,
311 Opt_labelsupport = 5, 329 Opt_labelsupport = 5,
330 Opt_nextmntopt = 6,
312}; 331};
313 332
333#define NUM_SEL_MNT_OPTS (Opt_nextmntopt - 1)
334
314static const match_table_t tokens = { 335static const match_table_t tokens = {
315 {Opt_context, CONTEXT_STR "%s"}, 336 {Opt_context, CONTEXT_STR "%s"},
316 {Opt_fscontext, FSCONTEXT_STR "%s"}, 337 {Opt_fscontext, FSCONTEXT_STR "%s"},
@@ -355,6 +376,29 @@ static int may_context_mount_inode_relabel(u32 sid,
355 return rc; 376 return rc;
356} 377}
357 378
379static int selinux_is_sblabel_mnt(struct super_block *sb)
380{
381 struct superblock_security_struct *sbsec = sb->s_security;
382
383 if (sbsec->behavior == SECURITY_FS_USE_XATTR ||
384 sbsec->behavior == SECURITY_FS_USE_TRANS ||
385 sbsec->behavior == SECURITY_FS_USE_TASK)
386 return 1;
387
388 /* Special handling for sysfs. Is genfs but also has setxattr handler*/
389 if (strncmp(sb->s_type->name, "sysfs", sizeof("sysfs")) == 0)
390 return 1;
391
392 /*
393 * Special handling for rootfs. Is genfs but supports
394 * setting SELinux context on in-core inodes.
395 */
396 if (strncmp(sb->s_type->name, "rootfs", sizeof("rootfs")) == 0)
397 return 1;
398
399 return 0;
400}
401
358static int sb_finish_set_opts(struct super_block *sb) 402static int sb_finish_set_opts(struct super_block *sb)
359{ 403{
360 struct superblock_security_struct *sbsec = sb->s_security; 404 struct superblock_security_struct *sbsec = sb->s_security;
@@ -369,8 +413,8 @@ static int sb_finish_set_opts(struct super_block *sb)
369 the first boot of the SELinux kernel before we have 413 the first boot of the SELinux kernel before we have
370 assigned xattr values to the filesystem. */ 414 assigned xattr values to the filesystem. */
371 if (!root_inode->i_op->getxattr) { 415 if (!root_inode->i_op->getxattr) {
372 printk(KERN_WARNING "SELinux: (dev %s, type %s) has no " 416 printk(KERN_WARNING "SELinux: (dev %s, type "SB_TYPE_FMT") has no "
373 "xattr support\n", sb->s_id, sb->s_type->name); 417 "xattr support\n", sb->s_id, SB_TYPE_ARGS(sb));
374 rc = -EOPNOTSUPP; 418 rc = -EOPNOTSUPP;
375 goto out; 419 goto out;
376 } 420 }
@@ -378,35 +422,27 @@ static int sb_finish_set_opts(struct super_block *sb)
378 if (rc < 0 && rc != -ENODATA) { 422 if (rc < 0 && rc != -ENODATA) {
379 if (rc == -EOPNOTSUPP) 423 if (rc == -EOPNOTSUPP)
380 printk(KERN_WARNING "SELinux: (dev %s, type " 424 printk(KERN_WARNING "SELinux: (dev %s, type "
381 "%s) has no security xattr handler\n", 425 SB_TYPE_FMT") has no security xattr handler\n",
382 sb->s_id, sb->s_type->name); 426 sb->s_id, SB_TYPE_ARGS(sb));
383 else 427 else
384 printk(KERN_WARNING "SELinux: (dev %s, type " 428 printk(KERN_WARNING "SELinux: (dev %s, type "
385 "%s) getxattr errno %d\n", sb->s_id, 429 SB_TYPE_FMT") getxattr errno %d\n", sb->s_id,
386 sb->s_type->name, -rc); 430 SB_TYPE_ARGS(sb), -rc);
387 goto out; 431 goto out;
388 } 432 }
389 } 433 }
390 434
391 sbsec->flags |= (SE_SBINITIALIZED | SE_SBLABELSUPP);
392
393 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) 435 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
394 printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n", 436 printk(KERN_ERR "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), unknown behavior\n",
395 sb->s_id, sb->s_type->name); 437 sb->s_id, SB_TYPE_ARGS(sb));
396 else 438 else
397 printk(KERN_DEBUG "SELinux: initialized (dev %s, type %s), %s\n", 439 printk(KERN_DEBUG "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), %s\n",
398 sb->s_id, sb->s_type->name, 440 sb->s_id, SB_TYPE_ARGS(sb),
399 labeling_behaviors[sbsec->behavior-1]); 441 labeling_behaviors[sbsec->behavior-1]);
400 442
401 if (sbsec->behavior == SECURITY_FS_USE_GENFS || 443 sbsec->flags |= SE_SBINITIALIZED;
402 sbsec->behavior == SECURITY_FS_USE_MNTPOINT || 444 if (selinux_is_sblabel_mnt(sb))
403 sbsec->behavior == SECURITY_FS_USE_NONE || 445 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 446
411 /* Initialize the root inode. */ 447 /* Initialize the root inode. */
412 rc = inode_doinit_with_dentry(root_inode, root); 448 rc = inode_doinit_with_dentry(root_inode, root);
@@ -460,15 +496,18 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
460 if (!ss_initialized) 496 if (!ss_initialized)
461 return -EINVAL; 497 return -EINVAL;
462 498
499 /* make sure we always check enough bits to cover the mask */
500 BUILD_BUG_ON(SE_MNTMASK >= (1 << NUM_SEL_MNT_OPTS));
501
463 tmp = sbsec->flags & SE_MNTMASK; 502 tmp = sbsec->flags & SE_MNTMASK;
464 /* count the number of mount options for this sb */ 503 /* count the number of mount options for this sb */
465 for (i = 0; i < 8; i++) { 504 for (i = 0; i < NUM_SEL_MNT_OPTS; i++) {
466 if (tmp & 0x01) 505 if (tmp & 0x01)
467 opts->num_mnt_opts++; 506 opts->num_mnt_opts++;
468 tmp >>= 1; 507 tmp >>= 1;
469 } 508 }
470 /* Check if the Label support flag is set */ 509 /* Check if the Label support flag is set */
471 if (sbsec->flags & SE_SBLABELSUPP) 510 if (sbsec->flags & SBLABEL_MNT)
472 opts->num_mnt_opts++; 511 opts->num_mnt_opts++;
473 512
474 opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC); 513 opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC);
@@ -515,9 +554,9 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
515 opts->mnt_opts[i] = context; 554 opts->mnt_opts[i] = context;
516 opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT; 555 opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT;
517 } 556 }
518 if (sbsec->flags & SE_SBLABELSUPP) { 557 if (sbsec->flags & SBLABEL_MNT) {
519 opts->mnt_opts[i] = NULL; 558 opts->mnt_opts[i] = NULL;
520 opts->mnt_opts_flags[i++] = SE_SBLABELSUPP; 559 opts->mnt_opts_flags[i++] = SBLABEL_MNT;
521 } 560 }
522 561
523 BUG_ON(i != opts->num_mnt_opts); 562 BUG_ON(i != opts->num_mnt_opts);
@@ -561,7 +600,6 @@ static int selinux_set_mnt_opts(struct super_block *sb,
561 const struct cred *cred = current_cred(); 600 const struct cred *cred = current_cred();
562 int rc = 0, i; 601 int rc = 0, i;
563 struct superblock_security_struct *sbsec = sb->s_security; 602 struct superblock_security_struct *sbsec = sb->s_security;
564 const char *name = sb->s_type->name;
565 struct inode *inode = sbsec->sb->s_root->d_inode; 603 struct inode *inode = sbsec->sb->s_root->d_inode;
566 struct inode_security_struct *root_isec = inode->i_security; 604 struct inode_security_struct *root_isec = inode->i_security;
567 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; 605 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
@@ -614,14 +652,14 @@ static int selinux_set_mnt_opts(struct super_block *sb,
614 for (i = 0; i < num_opts; i++) { 652 for (i = 0; i < num_opts; i++) {
615 u32 sid; 653 u32 sid;
616 654
617 if (flags[i] == SE_SBLABELSUPP) 655 if (flags[i] == SBLABEL_MNT)
618 continue; 656 continue;
619 rc = security_context_to_sid(mount_options[i], 657 rc = security_context_to_sid(mount_options[i],
620 strlen(mount_options[i]), &sid); 658 strlen(mount_options[i]), &sid);
621 if (rc) { 659 if (rc) {
622 printk(KERN_WARNING "SELinux: security_context_to_sid" 660 printk(KERN_WARNING "SELinux: security_context_to_sid"
623 "(%s) failed for (dev %s, type %s) errno=%d\n", 661 "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n",
624 mount_options[i], sb->s_id, name, rc); 662 mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc);
625 goto out; 663 goto out;
626 } 664 }
627 switch (flags[i]) { 665 switch (flags[i]) {
@@ -685,9 +723,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
685 * Determine the labeling behavior to use for this 723 * Determine the labeling behavior to use for this
686 * filesystem type. 724 * filesystem type.
687 */ 725 */
688 rc = security_fs_use((sbsec->flags & SE_SBPROC) ? 726 rc = security_fs_use(sb);
689 "proc" : sb->s_type->name,
690 &sbsec->behavior, &sbsec->sid);
691 if (rc) { 727 if (rc) {
692 printk(KERN_WARNING 728 printk(KERN_WARNING
693 "%s: security_fs_use(%s) returned %d\n", 729 "%s: security_fs_use(%s) returned %d\n",
@@ -770,7 +806,8 @@ out:
770out_double_mount: 806out_double_mount:
771 rc = -EINVAL; 807 rc = -EINVAL;
772 printk(KERN_WARNING "SELinux: mount invalid. Same superblock, different " 808 printk(KERN_WARNING "SELinux: mount invalid. Same superblock, different "
773 "security settings for (dev %s, type %s)\n", sb->s_id, name); 809 "security settings for (dev %s, type "SB_TYPE_FMT")\n", sb->s_id,
810 SB_TYPE_ARGS(sb));
774 goto out; 811 goto out;
775} 812}
776 813
@@ -1037,7 +1074,7 @@ static void selinux_write_opts(struct seq_file *m,
1037 case DEFCONTEXT_MNT: 1074 case DEFCONTEXT_MNT:
1038 prefix = DEFCONTEXT_STR; 1075 prefix = DEFCONTEXT_STR;
1039 break; 1076 break;
1040 case SE_SBLABELSUPP: 1077 case SBLABEL_MNT:
1041 seq_putc(m, ','); 1078 seq_putc(m, ',');
1042 seq_puts(m, LABELSUPP_STR); 1079 seq_puts(m, LABELSUPP_STR);
1043 continue; 1080 continue;
@@ -1649,7 +1686,7 @@ static int may_create(struct inode *dir,
1649 if (rc) 1686 if (rc)
1650 return rc; 1687 return rc;
1651 1688
1652 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { 1689 if (!newsid || !(sbsec->flags & SBLABEL_MNT)) {
1653 rc = security_transition_sid(sid, dsec->sid, tclass, 1690 rc = security_transition_sid(sid, dsec->sid, tclass,
1654 &dentry->d_name, &newsid); 1691 &dentry->d_name, &newsid);
1655 if (rc) 1692 if (rc)
@@ -2437,14 +2474,14 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
2437 u32 sid; 2474 u32 sid;
2438 size_t len; 2475 size_t len;
2439 2476
2440 if (flags[i] == SE_SBLABELSUPP) 2477 if (flags[i] == SBLABEL_MNT)
2441 continue; 2478 continue;
2442 len = strlen(mount_options[i]); 2479 len = strlen(mount_options[i]);
2443 rc = security_context_to_sid(mount_options[i], len, &sid); 2480 rc = security_context_to_sid(mount_options[i], len, &sid);
2444 if (rc) { 2481 if (rc) {
2445 printk(KERN_WARNING "SELinux: security_context_to_sid" 2482 printk(KERN_WARNING "SELinux: security_context_to_sid"
2446 "(%s) failed for (dev %s, type %s) errno=%d\n", 2483 "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n",
2447 mount_options[i], sb->s_id, sb->s_type->name, rc); 2484 mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc);
2448 goto out_free_opts; 2485 goto out_free_opts;
2449 } 2486 }
2450 rc = -EINVAL; 2487 rc = -EINVAL;
@@ -2482,8 +2519,8 @@ out_free_secdata:
2482 return rc; 2519 return rc;
2483out_bad_option: 2520out_bad_option:
2484 printk(KERN_WARNING "SELinux: unable to change security options " 2521 printk(KERN_WARNING "SELinux: unable to change security options "
2485 "during remount (dev %s, type=%s)\n", sb->s_id, 2522 "during remount (dev %s, type "SB_TYPE_FMT")\n", sb->s_id,
2486 sb->s_type->name); 2523 SB_TYPE_ARGS(sb));
2487 goto out_free_opts; 2524 goto out_free_opts;
2488} 2525}
2489 2526
@@ -2606,7 +2643,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2606 if ((sbsec->flags & SE_SBINITIALIZED) && 2643 if ((sbsec->flags & SE_SBINITIALIZED) &&
2607 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) 2644 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT))
2608 newsid = sbsec->mntpoint_sid; 2645 newsid = sbsec->mntpoint_sid;
2609 else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { 2646 else if (!newsid || !(sbsec->flags & SBLABEL_MNT)) {
2610 rc = security_transition_sid(sid, dsec->sid, 2647 rc = security_transition_sid(sid, dsec->sid,
2611 inode_mode_to_security_class(inode->i_mode), 2648 inode_mode_to_security_class(inode->i_mode),
2612 qstr, &newsid); 2649 qstr, &newsid);
@@ -2628,7 +2665,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2628 isec->initialized = 1; 2665 isec->initialized = 1;
2629 } 2666 }
2630 2667
2631 if (!ss_initialized || !(sbsec->flags & SE_SBLABELSUPP)) 2668 if (!ss_initialized || !(sbsec->flags & SBLABEL_MNT))
2632 return -EOPNOTSUPP; 2669 return -EOPNOTSUPP;
2633 2670
2634 if (name) 2671 if (name)
@@ -2830,7 +2867,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2830 return selinux_inode_setotherxattr(dentry, name); 2867 return selinux_inode_setotherxattr(dentry, name);
2831 2868
2832 sbsec = inode->i_sb->s_security; 2869 sbsec = inode->i_sb->s_security;
2833 if (!(sbsec->flags & SE_SBLABELSUPP)) 2870 if (!(sbsec->flags & SBLABEL_MNT))
2834 return -EOPNOTSUPP; 2871 return -EOPNOTSUPP;
2835 2872
2836 if (!inode_owner_or_capable(inode)) 2873 if (!inode_owner_or_capable(inode))
@@ -3791,8 +3828,12 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
3791 u32 nlbl_sid; 3828 u32 nlbl_sid;
3792 u32 nlbl_type; 3829 u32 nlbl_type;
3793 3830
3794 selinux_skb_xfrm_sid(skb, &xfrm_sid); 3831 err = selinux_skb_xfrm_sid(skb, &xfrm_sid);
3795 selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid); 3832 if (unlikely(err))
3833 return -EACCES;
3834 err = selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
3835 if (unlikely(err))
3836 return -EACCES;
3796 3837
3797 err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid); 3838 err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid);
3798 if (unlikely(err)) { 3839 if (unlikely(err)) {
@@ -4246,7 +4287,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); 4287 return selinux_sock_rcv_skb_compat(sk, skb, family);
4247 4288
4248 secmark_active = selinux_secmark_enabled(); 4289 secmark_active = selinux_secmark_enabled();
4249 peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled(); 4290 peerlbl_active = selinux_peerlbl_enabled();
4250 if (!secmark_active && !peerlbl_active) 4291 if (!secmark_active && !peerlbl_active)
4251 return 0; 4292 return 0;
4252 4293
@@ -4628,7 +4669,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
4628 4669
4629 secmark_active = selinux_secmark_enabled(); 4670 secmark_active = selinux_secmark_enabled();
4630 netlbl_active = netlbl_enabled(); 4671 netlbl_active = netlbl_enabled();
4631 peerlbl_active = netlbl_active || selinux_xfrm_enabled(); 4672 peerlbl_active = selinux_peerlbl_enabled();
4632 if (!secmark_active && !peerlbl_active) 4673 if (!secmark_active && !peerlbl_active)
4633 return NF_ACCEPT; 4674 return NF_ACCEPT;
4634 4675
@@ -4780,7 +4821,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4780 return NF_ACCEPT; 4821 return NF_ACCEPT;
4781#endif 4822#endif
4782 secmark_active = selinux_secmark_enabled(); 4823 secmark_active = selinux_secmark_enabled();
4783 peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled(); 4824 peerlbl_active = selinux_peerlbl_enabled();
4784 if (!secmark_active && !peerlbl_active) 4825 if (!secmark_active && !peerlbl_active)
4785 return NF_ACCEPT; 4826 return NF_ACCEPT;
4786 4827
@@ -5784,7 +5825,8 @@ static struct security_operations selinux_ops = {
5784 .xfrm_policy_clone_security = selinux_xfrm_policy_clone, 5825 .xfrm_policy_clone_security = selinux_xfrm_policy_clone,
5785 .xfrm_policy_free_security = selinux_xfrm_policy_free, 5826 .xfrm_policy_free_security = selinux_xfrm_policy_free,
5786 .xfrm_policy_delete_security = selinux_xfrm_policy_delete, 5827 .xfrm_policy_delete_security = selinux_xfrm_policy_delete,
5787 .xfrm_state_alloc_security = selinux_xfrm_state_alloc, 5828 .xfrm_state_alloc = selinux_xfrm_state_alloc,
5829 .xfrm_state_alloc_acquire = selinux_xfrm_state_alloc_acquire,
5788 .xfrm_state_free_security = selinux_xfrm_state_free, 5830 .xfrm_state_free_security = selinux_xfrm_state_free,
5789 .xfrm_state_delete_security = selinux_xfrm_state_delete, 5831 .xfrm_state_delete_security = selinux_xfrm_state_delete,
5790 .xfrm_policy_lookup = selinux_xfrm_policy_lookup, 5832 .xfrm_policy_lookup = selinux_xfrm_policy_lookup,