aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c116
-rw-r--r--security/selinux/include/security.h2
-rw-r--r--security/selinux/ss/policydb.c5
3 files changed, 105 insertions, 18 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 5c6f2cd2d095..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;
@@ -1547,6 +1572,18 @@ static inline int path_has_perm(const struct cred *cred,
1547 return inode_has_perm(cred, inode, av, &ad, 0); 1572 return inode_has_perm(cred, inode, av, &ad, 0);
1548} 1573}
1549 1574
1575/* Same as path_has_perm, but uses the inode from the file struct. */
1576static inline int file_path_has_perm(const struct cred *cred,
1577 struct file *file,
1578 u32 av)
1579{
1580 struct common_audit_data ad;
1581
1582 ad.type = LSM_AUDIT_DATA_PATH;
1583 ad.u.path = file->f_path;
1584 return inode_has_perm(cred, file_inode(file), av, &ad, 0);
1585}
1586
1550/* Check whether a task can use an open file descriptor to 1587/* Check whether a task can use an open file descriptor to
1551 access an inode in a given way. Check access to the 1588 access an inode in a given way. Check access to the
1552 descriptor itself, and then use dentry_has_perm to 1589 descriptor itself, and then use dentry_has_perm to
@@ -2141,14 +2178,14 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2141 struct tty_file_private *file_priv; 2178 struct tty_file_private *file_priv;
2142 2179
2143 /* Revalidate access to controlling tty. 2180 /* Revalidate access to controlling tty.
2144 Use path_has_perm on the tty path directly rather 2181 Use file_path_has_perm on the tty path directly
2145 than using file_has_perm, as this particular open 2182 rather than using file_has_perm, as this particular
2146 file may belong to another process and we are only 2183 open file may belong to another process and we are
2147 interested in the inode-based check here. */ 2184 only interested in the inode-based check here. */
2148 file_priv = list_first_entry(&tty->tty_files, 2185 file_priv = list_first_entry(&tty->tty_files,
2149 struct tty_file_private, list); 2186 struct tty_file_private, list);
2150 file = file_priv->file; 2187 file = file_priv->file;
2151 if (path_has_perm(cred, &file->f_path, FILE__READ | FILE__WRITE)) 2188 if (file_path_has_perm(cred, file, FILE__READ | FILE__WRITE))
2152 drop_tty = 1; 2189 drop_tty = 1;
2153 } 2190 }
2154 spin_unlock(&tty_files_lock); 2191 spin_unlock(&tty_files_lock);
@@ -2515,6 +2552,40 @@ static void selinux_inode_free_security(struct inode *inode)
2515 inode_free_security(inode); 2552 inode_free_security(inode);
2516} 2553}
2517 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
2518static int selinux_inode_init_security(struct inode *inode, struct inode *dir, 2589static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2519 const struct qstr *qstr, char **name, 2590 const struct qstr *qstr, char **name,
2520 void **value, size_t *len) 2591 void **value, size_t *len)
@@ -2849,7 +2920,10 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
2849 return; 2920 return;
2850 } 2921 }
2851 2922
2923 isec->sclass = inode_mode_to_security_class(inode->i_mode);
2852 isec->sid = newsid; 2924 isec->sid = newsid;
2925 isec->initialized = 1;
2926
2853 return; 2927 return;
2854} 2928}
2855 2929
@@ -2937,6 +3011,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name,
2937 if (rc) 3011 if (rc)
2938 return rc; 3012 return rc;
2939 3013
3014 isec->sclass = inode_mode_to_security_class(inode->i_mode);
2940 isec->sid = newsid; 3015 isec->sid = newsid;
2941 isec->initialized = 1; 3016 isec->initialized = 1;
2942 return 0; 3017 return 0;
@@ -3259,7 +3334,7 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
3259 * new inode label or new policy. 3334 * new inode label or new policy.
3260 * This check is not redundant - do not remove. 3335 * This check is not redundant - do not remove.
3261 */ 3336 */
3262 return path_has_perm(cred, &file->f_path, open_file_to_av(file)); 3337 return file_path_has_perm(cred, file, open_file_to_av(file));
3263} 3338}
3264 3339
3265/* task security operations */ 3340/* task security operations */
@@ -5420,6 +5495,11 @@ abort_change:
5420 return error; 5495 return error;
5421} 5496}
5422 5497
5498static int selinux_ismaclabel(const char *name)
5499{
5500 return (strcmp(name, XATTR_SELINUX_SUFFIX) == 0);
5501}
5502
5423static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 5503static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
5424{ 5504{
5425 return security_sid_to_context(secid, secdata, seclen); 5505 return security_sid_to_context(secid, secdata, seclen);
@@ -5562,6 +5642,7 @@ static struct security_operations selinux_ops = {
5562 .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, 5642 .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts,
5563 .sb_parse_opts_str = selinux_parse_opts_str, 5643 .sb_parse_opts_str = selinux_parse_opts_str,
5564 5644
5645 .dentry_init_security = selinux_dentry_init_security,
5565 5646
5566 .inode_alloc_security = selinux_inode_alloc_security, 5647 .inode_alloc_security = selinux_inode_alloc_security,
5567 .inode_free_security = selinux_inode_free_security, 5648 .inode_free_security = selinux_inode_free_security,
@@ -5657,6 +5738,7 @@ static struct security_operations selinux_ops = {
5657 .getprocattr = selinux_getprocattr, 5738 .getprocattr = selinux_getprocattr,
5658 .setprocattr = selinux_setprocattr, 5739 .setprocattr = selinux_setprocattr,
5659 5740
5741 .ismaclabel = selinux_ismaclabel,
5660 .secid_to_secctx = selinux_secid_to_secctx, 5742 .secid_to_secctx = selinux_secid_to_secctx,
5661 .secctx_to_secid = selinux_secctx_to_secid, 5743 .secctx_to_secid = selinux_secctx_to_secid,
5662 .release_secctx = selinux_release_secctx, 5744 .release_secctx = selinux_release_secctx,
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 6d3885165d14..8fd8e18ea340 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -169,6 +169,8 @@ int security_get_allow_unknown(void);
169#define SECURITY_FS_USE_GENFS 4 /* use the genfs support */ 169#define SECURITY_FS_USE_GENFS 4 /* use the genfs support */
170#define SECURITY_FS_USE_NONE 5 /* no labeling support */ 170#define SECURITY_FS_USE_NONE 5 /* no labeling support */
171#define SECURITY_FS_USE_MNTPOINT 6 /* use mountpoint labeling */ 171#define SECURITY_FS_USE_MNTPOINT 6 /* use mountpoint labeling */
172#define SECURITY_FS_USE_NATIVE 7 /* use native label support */
173#define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */
172 174
173int security_fs_use(const char *fstype, unsigned int *behavior, 175int security_fs_use(const char *fstype, unsigned int *behavior,
174 u32 *sid); 176 u32 *sid);
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 9cd9b7c661ec..c8adde3aff8f 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -2168,7 +2168,10 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
2168 2168
2169 rc = -EINVAL; 2169 rc = -EINVAL;
2170 c->v.behavior = le32_to_cpu(buf[0]); 2170 c->v.behavior = le32_to_cpu(buf[0]);
2171 if (c->v.behavior > SECURITY_FS_USE_NONE) 2171 /* Determined at runtime, not in policy DB. */
2172 if (c->v.behavior == SECURITY_FS_USE_MNTPOINT)
2173 goto out;
2174 if (c->v.behavior > SECURITY_FS_USE_MAX)
2172 goto out; 2175 goto out;
2173 2176
2174 rc = -ENOMEM; 2177 rc = -ENOMEM;