aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/capability.c19
-rw-r--r--security/security.c24
-rw-r--r--security/selinux/hooks.c92
-rw-r--r--security/selinux/include/security.h2
-rw-r--r--security/selinux/ss/policydb.c5
-rw-r--r--security/smack/smack_lsm.c11
6 files changed, 138 insertions, 15 deletions
diff --git a/security/capability.c b/security/capability.c
index 1728d4e375db..d32e16e3c6ae 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -91,7 +91,10 @@ static int cap_sb_pivotroot(struct path *old_path, struct path *new_path)
91} 91}
92 92
93static int cap_sb_set_mnt_opts(struct super_block *sb, 93static int cap_sb_set_mnt_opts(struct super_block *sb,
94 struct security_mnt_opts *opts) 94 struct security_mnt_opts *opts,
95 unsigned long kern_flags,
96 unsigned long *set_kern_flags)
97
95{ 98{
96 if (unlikely(opts->num_mnt_opts)) 99 if (unlikely(opts->num_mnt_opts))
97 return -EOPNOTSUPP; 100 return -EOPNOTSUPP;
@@ -109,6 +112,13 @@ static int cap_sb_parse_opts_str(char *options, struct security_mnt_opts *opts)
109 return 0; 112 return 0;
110} 113}
111 114
115static int cap_dentry_init_security(struct dentry *dentry, int mode,
116 struct qstr *name, void **ctx,
117 u32 *ctxlen)
118{
119 return 0;
120}
121
112static int cap_inode_alloc_security(struct inode *inode) 122static int cap_inode_alloc_security(struct inode *inode)
113{ 123{
114 return 0; 124 return 0;
@@ -816,6 +826,11 @@ static int cap_setprocattr(struct task_struct *p, char *name, void *value,
816 return -EINVAL; 826 return -EINVAL;
817} 827}
818 828
829static int cap_ismaclabel(const char *name)
830{
831 return 0;
832}
833
819static int cap_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 834static int cap_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
820{ 835{
821 return -EOPNOTSUPP; 836 return -EOPNOTSUPP;
@@ -931,6 +946,7 @@ void __init security_fixup_ops(struct security_operations *ops)
931 set_to_cap_if_null(ops, sb_set_mnt_opts); 946 set_to_cap_if_null(ops, sb_set_mnt_opts);
932 set_to_cap_if_null(ops, sb_clone_mnt_opts); 947 set_to_cap_if_null(ops, sb_clone_mnt_opts);
933 set_to_cap_if_null(ops, sb_parse_opts_str); 948 set_to_cap_if_null(ops, sb_parse_opts_str);
949 set_to_cap_if_null(ops, dentry_init_security);
934 set_to_cap_if_null(ops, inode_alloc_security); 950 set_to_cap_if_null(ops, inode_alloc_security);
935 set_to_cap_if_null(ops, inode_free_security); 951 set_to_cap_if_null(ops, inode_free_security);
936 set_to_cap_if_null(ops, inode_init_security); 952 set_to_cap_if_null(ops, inode_init_security);
@@ -1034,6 +1050,7 @@ void __init security_fixup_ops(struct security_operations *ops)
1034 set_to_cap_if_null(ops, d_instantiate); 1050 set_to_cap_if_null(ops, d_instantiate);
1035 set_to_cap_if_null(ops, getprocattr); 1051 set_to_cap_if_null(ops, getprocattr);
1036 set_to_cap_if_null(ops, setprocattr); 1052 set_to_cap_if_null(ops, setprocattr);
1053 set_to_cap_if_null(ops, ismaclabel);
1037 set_to_cap_if_null(ops, secid_to_secctx); 1054 set_to_cap_if_null(ops, secid_to_secctx);
1038 set_to_cap_if_null(ops, secctx_to_secid); 1055 set_to_cap_if_null(ops, secctx_to_secid);
1039 set_to_cap_if_null(ops, release_secctx); 1056 set_to_cap_if_null(ops, release_secctx);
diff --git a/security/security.c b/security/security.c
index a3dce87d1aef..94b35aef6871 100644
--- a/security/security.c
+++ b/security/security.c
@@ -12,6 +12,7 @@
12 */ 12 */
13 13
14#include <linux/capability.h> 14#include <linux/capability.h>
15#include <linux/dcache.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/kernel.h> 18#include <linux/kernel.h>
@@ -293,9 +294,12 @@ int security_sb_pivotroot(struct path *old_path, struct path *new_path)
293} 294}
294 295
295int security_sb_set_mnt_opts(struct super_block *sb, 296int security_sb_set_mnt_opts(struct super_block *sb,
296 struct security_mnt_opts *opts) 297 struct security_mnt_opts *opts,
298 unsigned long kern_flags,
299 unsigned long *set_kern_flags)
297{ 300{
298 return security_ops->sb_set_mnt_opts(sb, opts); 301 return security_ops->sb_set_mnt_opts(sb, opts, kern_flags,
302 set_kern_flags);
299} 303}
300EXPORT_SYMBOL(security_sb_set_mnt_opts); 304EXPORT_SYMBOL(security_sb_set_mnt_opts);
301 305
@@ -324,6 +328,15 @@ void security_inode_free(struct inode *inode)
324 security_ops->inode_free_security(inode); 328 security_ops->inode_free_security(inode);
325} 329}
326 330
331int security_dentry_init_security(struct dentry *dentry, int mode,
332 struct qstr *name, void **ctx,
333 u32 *ctxlen)
334{
335 return security_ops->dentry_init_security(dentry, mode, name,
336 ctx, ctxlen);
337}
338EXPORT_SYMBOL(security_dentry_init_security);
339
327int security_inode_init_security(struct inode *inode, struct inode *dir, 340int security_inode_init_security(struct inode *inode, struct inode *dir,
328 const struct qstr *qstr, 341 const struct qstr *qstr,
329 const initxattrs initxattrs, void *fs_data) 342 const initxattrs initxattrs, void *fs_data)
@@ -647,6 +660,7 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer
647 return 0; 660 return 0;
648 return security_ops->inode_listsecurity(inode, buffer, buffer_size); 661 return security_ops->inode_listsecurity(inode, buffer, buffer_size);
649} 662}
663EXPORT_SYMBOL(security_inode_listsecurity);
650 664
651void security_inode_getsecid(const struct inode *inode, u32 *secid) 665void security_inode_getsecid(const struct inode *inode, u32 *secid)
652{ 666{
@@ -1047,6 +1061,12 @@ int security_netlink_send(struct sock *sk, struct sk_buff *skb)
1047 return security_ops->netlink_send(sk, skb); 1061 return security_ops->netlink_send(sk, skb);
1048} 1062}
1049 1063
1064int security_ismaclabel(const char *name)
1065{
1066 return security_ops->ismaclabel(name);
1067}
1068EXPORT_SYMBOL(security_ismaclabel);
1069
1050int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 1070int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
1051{ 1071{
1052 return security_ops->secid_to_secctx(secid, secdata, seclen); 1072 return security_ops->secid_to_secctx(secid, secdata, seclen);
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,
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;
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 6a083303501d..3f7682a387b7 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -3640,6 +3640,16 @@ static void smack_audit_rule_free(void *vrule)
3640#endif /* CONFIG_AUDIT */ 3640#endif /* CONFIG_AUDIT */
3641 3641
3642/** 3642/**
3643 * smack_ismaclabel - check if xattr @name references a smack MAC label
3644 * @name: Full xattr name to check.
3645 */
3646static int smack_ismaclabel(const char *name)
3647{
3648 return (strcmp(name, XATTR_SMACK_SUFFIX) == 0);
3649}
3650
3651
3652/**
3643 * smack_secid_to_secctx - return the smack label for a secid 3653 * smack_secid_to_secctx - return the smack label for a secid
3644 * @secid: incoming integer 3654 * @secid: incoming integer
3645 * @secdata: destination 3655 * @secdata: destination
@@ -3836,6 +3846,7 @@ struct security_operations smack_ops = {
3836 .audit_rule_free = smack_audit_rule_free, 3846 .audit_rule_free = smack_audit_rule_free,
3837#endif /* CONFIG_AUDIT */ 3847#endif /* CONFIG_AUDIT */
3838 3848
3849 .ismaclabel = smack_ismaclabel,
3839 .secid_to_secctx = smack_secid_to_secctx, 3850 .secid_to_secctx = smack_secid_to_secctx,
3840 .secctx_to_secid = smack_secctx_to_secid, 3851 .secctx_to_secid = smack_secctx_to_secid,
3841 .release_secctx = smack_release_secctx, 3852 .release_secctx = smack_release_secctx,