summaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c92
1 files changed, 81 insertions, 11 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index db1fca990a24..c956390a9136 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -81,6 +81,7 @@
81#include <linux/syslog.h> 81#include <linux/syslog.h>
82#include <linux/user_namespace.h> 82#include <linux/user_namespace.h>
83#include <linux/export.h> 83#include <linux/export.h>
84#include <linux/security.h>
84#include <linux/msg.h> 85#include <linux/msg.h>
85#include <linux/shm.h> 86#include <linux/shm.h>
86 87
@@ -284,13 +285,14 @@ static void superblock_free_security(struct super_block *sb)
284 285
285/* The file system's label must be initialized prior to use. */ 286/* The file system's label must be initialized prior to use. */
286 287
287static const char *labeling_behaviors[6] = { 288static const char *labeling_behaviors[7] = {
288 "uses xattr", 289 "uses xattr",
289 "uses transition SIDs", 290 "uses transition SIDs",
290 "uses task SIDs", 291 "uses task SIDs",
291 "uses genfs_contexts", 292 "uses genfs_contexts",
292 "not configured for labeling", 293 "not configured for labeling",
293 "uses mountpoint labeling", 294 "uses mountpoint labeling",
295 "uses native labeling",
294}; 296};
295 297
296static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry); 298static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
@@ -552,7 +554,9 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
552 * labeling information. 554 * labeling information.
553 */ 555 */
554static int selinux_set_mnt_opts(struct super_block *sb, 556static int selinux_set_mnt_opts(struct super_block *sb,
555 struct security_mnt_opts *opts) 557 struct security_mnt_opts *opts,
558 unsigned long kern_flags,
559 unsigned long *set_kern_flags)
556{ 560{
557 const struct cred *cred = current_cred(); 561 const struct cred *cred = current_cred();
558 int rc = 0, i; 562 int rc = 0, i;
@@ -580,6 +584,12 @@ static int selinux_set_mnt_opts(struct super_block *sb,
580 "before the security server is initialized\n"); 584 "before the security server is initialized\n");
581 goto out; 585 goto out;
582 } 586 }
587 if (kern_flags && !set_kern_flags) {
588 /* Specifying internal flags without providing a place to
589 * place the results is not allowed */
590 rc = -EINVAL;
591 goto out;
592 }
583 593
584 /* 594 /*
585 * Binary mount data FS will come through this function twice. Once 595 * Binary mount data FS will come through this function twice. Once
@@ -670,14 +680,21 @@ static int selinux_set_mnt_opts(struct super_block *sb,
670 if (strcmp(sb->s_type->name, "proc") == 0) 680 if (strcmp(sb->s_type->name, "proc") == 0)
671 sbsec->flags |= SE_SBPROC; 681 sbsec->flags |= SE_SBPROC;
672 682
673 /* Determine the labeling behavior to use for this filesystem type. */ 683 if (!sbsec->behavior) {
674 rc = security_fs_use((sbsec->flags & SE_SBPROC) ? "proc" : sb->s_type->name, &sbsec->behavior, &sbsec->sid); 684 /*
675 if (rc) { 685 * Determine the labeling behavior to use for this
676 printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", 686 * filesystem type.
677 __func__, sb->s_type->name, rc); 687 */
678 goto out; 688 rc = security_fs_use((sbsec->flags & SE_SBPROC) ?
689 "proc" : sb->s_type->name,
690 &sbsec->behavior, &sbsec->sid);
691 if (rc) {
692 printk(KERN_WARNING
693 "%s: security_fs_use(%s) returned %d\n",
694 __func__, sb->s_type->name, rc);
695 goto out;
696 }
679 } 697 }
680
681 /* sets the context of the superblock for the fs being mounted. */ 698 /* sets the context of the superblock for the fs being mounted. */
682 if (fscontext_sid) { 699 if (fscontext_sid) {
683 rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred); 700 rc = may_context_mount_sb_relabel(fscontext_sid, sbsec, cred);
@@ -692,6 +709,11 @@ static int selinux_set_mnt_opts(struct super_block *sb,
692 * sets the label used on all file below the mountpoint, and will set 709 * sets the label used on all file below the mountpoint, and will set
693 * the superblock context if not already set. 710 * the superblock context if not already set.
694 */ 711 */
712 if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !context_sid) {
713 sbsec->behavior = SECURITY_FS_USE_NATIVE;
714 *set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
715 }
716
695 if (context_sid) { 717 if (context_sid) {
696 if (!fscontext_sid) { 718 if (!fscontext_sid) {
697 rc = may_context_mount_sb_relabel(context_sid, sbsec, 719 rc = may_context_mount_sb_relabel(context_sid, sbsec,
@@ -723,7 +745,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
723 } 745 }
724 746
725 if (defcontext_sid) { 747 if (defcontext_sid) {
726 if (sbsec->behavior != SECURITY_FS_USE_XATTR) { 748 if (sbsec->behavior != SECURITY_FS_USE_XATTR &&
749 sbsec->behavior != SECURITY_FS_USE_NATIVE) {
727 rc = -EINVAL; 750 rc = -EINVAL;
728 printk(KERN_WARNING "SELinux: defcontext option is " 751 printk(KERN_WARNING "SELinux: defcontext option is "
729 "invalid for this filesystem type\n"); 752 "invalid for this filesystem type\n");
@@ -980,7 +1003,7 @@ static int superblock_doinit(struct super_block *sb, void *data)
980 goto out_err; 1003 goto out_err;
981 1004
982out: 1005out:
983 rc = selinux_set_mnt_opts(sb, &opts); 1006 rc = selinux_set_mnt_opts(sb, &opts, 0, NULL);
984 1007
985out_err: 1008out_err:
986 security_free_mnt_opts(&opts); 1009 security_free_mnt_opts(&opts);
@@ -1222,6 +1245,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1222 } 1245 }
1223 1246
1224 switch (sbsec->behavior) { 1247 switch (sbsec->behavior) {
1248 case SECURITY_FS_USE_NATIVE:
1249 break;
1225 case SECURITY_FS_USE_XATTR: 1250 case SECURITY_FS_USE_XATTR:
1226 if (!inode->i_op->getxattr) { 1251 if (!inode->i_op->getxattr) {
1227 isec->sid = sbsec->def_sid; 1252 isec->sid = sbsec->def_sid;
@@ -2527,6 +2552,40 @@ static void selinux_inode_free_security(struct inode *inode)
2527 inode_free_security(inode); 2552 inode_free_security(inode);
2528} 2553}
2529 2554
2555static int selinux_dentry_init_security(struct dentry *dentry, int mode,
2556 struct qstr *name, void **ctx,
2557 u32 *ctxlen)
2558{
2559 const struct cred *cred = current_cred();
2560 struct task_security_struct *tsec;
2561 struct inode_security_struct *dsec;
2562 struct superblock_security_struct *sbsec;
2563 struct inode *dir = dentry->d_parent->d_inode;
2564 u32 newsid;
2565 int rc;
2566
2567 tsec = cred->security;
2568 dsec = dir->i_security;
2569 sbsec = dir->i_sb->s_security;
2570
2571 if (tsec->create_sid && sbsec->behavior != SECURITY_FS_USE_MNTPOINT) {
2572 newsid = tsec->create_sid;
2573 } else {
2574 rc = security_transition_sid(tsec->sid, dsec->sid,
2575 inode_mode_to_security_class(mode),
2576 name,
2577 &newsid);
2578 if (rc) {
2579 printk(KERN_WARNING
2580 "%s: security_transition_sid failed, rc=%d\n",
2581 __func__, -rc);
2582 return rc;
2583 }
2584 }
2585
2586 return security_sid_to_context(newsid, (char **)ctx, ctxlen);
2587}
2588
2530static int selinux_inode_init_security(struct inode *inode, struct inode *dir, 2589static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2531 const struct qstr *qstr, char **name, 2590 const struct qstr *qstr, char **name,
2532 void **value, size_t *len) 2591 void **value, size_t *len)
@@ -2861,7 +2920,10 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
2861 return; 2920 return;
2862 } 2921 }
2863 2922
2923 isec->sclass = inode_mode_to_security_class(inode->i_mode);
2864 isec->sid = newsid; 2924 isec->sid = newsid;
2925 isec->initialized = 1;
2926
2865 return; 2927 return;
2866} 2928}
2867 2929
@@ -2949,6 +3011,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name,
2949 if (rc) 3011 if (rc)
2950 return rc; 3012 return rc;
2951 3013
3014 isec->sclass = inode_mode_to_security_class(inode->i_mode);
2952 isec->sid = newsid; 3015 isec->sid = newsid;
2953 isec->initialized = 1; 3016 isec->initialized = 1;
2954 return 0; 3017 return 0;
@@ -5432,6 +5495,11 @@ abort_change:
5432 return error; 5495 return error;
5433} 5496}
5434 5497
5498static int selinux_ismaclabel(const char *name)
5499{
5500 return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
5501}
5502
5435static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 5503static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
5436{ 5504{
5437 return security_sid_to_context(secid, secdata, seclen); 5505 return security_sid_to_context(secid, secdata, seclen);
@@ -5574,6 +5642,7 @@ static struct security_operations selinux_ops = {
5574 .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, 5642 .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts,
5575 .sb_parse_opts_str = selinux_parse_opts_str, 5643 .sb_parse_opts_str = selinux_parse_opts_str,
5576 5644
5645 .dentry_init_security = selinux_dentry_init_security,
5577 5646
5578 .inode_alloc_security = selinux_inode_alloc_security, 5647 .inode_alloc_security = selinux_inode_alloc_security,
5579 .inode_free_security = selinux_inode_free_security, 5648 .inode_free_security = selinux_inode_free_security,
@@ -5669,6 +5738,7 @@ static struct security_operations selinux_ops = {
5669 .getprocattr = selinux_getprocattr, 5738 .getprocattr = selinux_getprocattr,
5670 .setprocattr = selinux_setprocattr, 5739 .setprocattr = selinux_setprocattr,
5671 5740
5741 .ismaclabel = selinux_ismaclabel,
5672 .secid_to_secctx = selinux_secid_to_secctx, 5742 .secid_to_secctx = selinux_secid_to_secctx,
5673 .secctx_to_secid = selinux_secctx_to_secid, 5743 .secctx_to_secid = selinux_secctx_to_secid,
5674 .release_secctx = selinux_release_secctx, 5744 .release_secctx = selinux_release_secctx,