aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c39
-rw-r--r--security/selinux/include/security.h2
2 files changed, 36 insertions, 5 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 473adc5f4f9a..1a9768a8b644 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -89,7 +89,7 @@
89#define XATTR_SELINUX_SUFFIX "selinux" 89#define XATTR_SELINUX_SUFFIX "selinux"
90#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX 90#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
91 91
92#define NUM_SEL_MNT_OPTS 4 92#define NUM_SEL_MNT_OPTS 5
93 93
94extern unsigned int policydb_loaded_version; 94extern unsigned int policydb_loaded_version;
95extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); 95extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
@@ -353,6 +353,7 @@ enum {
353 Opt_fscontext = 2, 353 Opt_fscontext = 2,
354 Opt_defcontext = 3, 354 Opt_defcontext = 3,
355 Opt_rootcontext = 4, 355 Opt_rootcontext = 4,
356 Opt_labelsupport = 5,
356}; 357};
357 358
358static const match_table_t tokens = { 359static const match_table_t tokens = {
@@ -360,6 +361,7 @@ static const match_table_t tokens = {
360 {Opt_fscontext, FSCONTEXT_STR "%s"}, 361 {Opt_fscontext, FSCONTEXT_STR "%s"},
361 {Opt_defcontext, DEFCONTEXT_STR "%s"}, 362 {Opt_defcontext, DEFCONTEXT_STR "%s"},
362 {Opt_rootcontext, ROOTCONTEXT_STR "%s"}, 363 {Opt_rootcontext, ROOTCONTEXT_STR "%s"},
364 {Opt_labelsupport, LABELSUPP_STR},
363 {Opt_error, NULL}, 365 {Opt_error, NULL},
364}; 366};
365 367
@@ -431,7 +433,7 @@ static int sb_finish_set_opts(struct super_block *sb)
431 } 433 }
432 } 434 }
433 435
434 sbsec->flags |= SE_SBINITIALIZED; 436 sbsec->flags |= (SE_SBINITIALIZED | SE_SBLABELSUPP);
435 437
436 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) 438 if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
437 printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n", 439 printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",
@@ -441,6 +443,12 @@ static int sb_finish_set_opts(struct super_block *sb)
441 sb->s_id, sb->s_type->name, 443 sb->s_id, sb->s_type->name,
442 labeling_behaviors[sbsec->behavior-1]); 444 labeling_behaviors[sbsec->behavior-1]);
443 445
446 if (sbsec->behavior == SECURITY_FS_USE_GENFS ||
447 sbsec->behavior == SECURITY_FS_USE_MNTPOINT ||
448 sbsec->behavior == SECURITY_FS_USE_NONE ||
449 sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
450 sbsec->flags &= ~SE_SBLABELSUPP;
451
444 /* Initialize the root inode. */ 452 /* Initialize the root inode. */
445 rc = inode_doinit_with_dentry(root_inode, root); 453 rc = inode_doinit_with_dentry(root_inode, root);
446 454
@@ -500,6 +508,9 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
500 opts->num_mnt_opts++; 508 opts->num_mnt_opts++;
501 tmp >>= 1; 509 tmp >>= 1;
502 } 510 }
511 /* Check if the Label support flag is set */
512 if (sbsec->flags & SE_SBLABELSUPP)
513 opts->num_mnt_opts++;
503 514
504 opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC); 515 opts->mnt_opts = kcalloc(opts->num_mnt_opts, sizeof(char *), GFP_ATOMIC);
505 if (!opts->mnt_opts) { 516 if (!opts->mnt_opts) {
@@ -545,6 +556,10 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
545 opts->mnt_opts[i] = context; 556 opts->mnt_opts[i] = context;
546 opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT; 557 opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT;
547 } 558 }
559 if (sbsec->flags & SE_SBLABELSUPP) {
560 opts->mnt_opts[i] = NULL;
561 opts->mnt_opts_flags[i++] = SE_SBLABELSUPP;
562 }
548 563
549 BUG_ON(i != opts->num_mnt_opts); 564 BUG_ON(i != opts->num_mnt_opts);
550 565
@@ -635,6 +650,9 @@ static int selinux_set_mnt_opts(struct super_block *sb,
635 */ 650 */
636 for (i = 0; i < num_opts; i++) { 651 for (i = 0; i < num_opts; i++) {
637 u32 sid; 652 u32 sid;
653
654 if (flags[i] == SE_SBLABELSUPP)
655 continue;
638 rc = security_context_to_sid(mount_options[i], 656 rc = security_context_to_sid(mount_options[i],
639 strlen(mount_options[i]), &sid); 657 strlen(mount_options[i]), &sid);
640 if (rc) { 658 if (rc) {
@@ -915,7 +933,8 @@ static int selinux_parse_opts_str(char *options,
915 goto out_err; 933 goto out_err;
916 } 934 }
917 break; 935 break;
918 936 case Opt_labelsupport:
937 break;
919 default: 938 default:
920 rc = -EINVAL; 939 rc = -EINVAL;
921 printk(KERN_WARNING "SELinux: unknown mount option\n"); 940 printk(KERN_WARNING "SELinux: unknown mount option\n");
@@ -997,7 +1016,12 @@ static void selinux_write_opts(struct seq_file *m,
997 char *prefix; 1016 char *prefix;
998 1017
999 for (i = 0; i < opts->num_mnt_opts; i++) { 1018 for (i = 0; i < opts->num_mnt_opts; i++) {
1000 char *has_comma = strchr(opts->mnt_opts[i], ','); 1019 char *has_comma;
1020
1021 if (opts->mnt_opts[i])
1022 has_comma = strchr(opts->mnt_opts[i], ',');
1023 else
1024 has_comma = NULL;
1001 1025
1002 switch (opts->mnt_opts_flags[i]) { 1026 switch (opts->mnt_opts_flags[i]) {
1003 case CONTEXT_MNT: 1027 case CONTEXT_MNT:
@@ -1012,6 +1036,10 @@ static void selinux_write_opts(struct seq_file *m,
1012 case DEFCONTEXT_MNT: 1036 case DEFCONTEXT_MNT:
1013 prefix = DEFCONTEXT_STR; 1037 prefix = DEFCONTEXT_STR;
1014 break; 1038 break;
1039 case SE_SBLABELSUPP:
1040 seq_putc(m, ',');
1041 seq_puts(m, LABELSUPP_STR);
1042 continue;
1015 default: 1043 default:
1016 BUG(); 1044 BUG();
1017 }; 1045 };
@@ -2398,7 +2426,8 @@ static inline int selinux_option(char *option, int len)
2398 return (match_prefix(CONTEXT_STR, sizeof(CONTEXT_STR)-1, option, len) || 2426 return (match_prefix(CONTEXT_STR, sizeof(CONTEXT_STR)-1, option, len) ||
2399 match_prefix(FSCONTEXT_STR, sizeof(FSCONTEXT_STR)-1, option, len) || 2427 match_prefix(FSCONTEXT_STR, sizeof(FSCONTEXT_STR)-1, option, len) ||
2400 match_prefix(DEFCONTEXT_STR, sizeof(DEFCONTEXT_STR)-1, option, len) || 2428 match_prefix(DEFCONTEXT_STR, sizeof(DEFCONTEXT_STR)-1, option, len) ||
2401 match_prefix(ROOTCONTEXT_STR, sizeof(ROOTCONTEXT_STR)-1, option, len)); 2429 match_prefix(ROOTCONTEXT_STR, sizeof(ROOTCONTEXT_STR)-1, option, len) ||
2430 match_prefix(LABELSUPP_STR, sizeof(LABELSUPP_STR)-1, option, len));
2402} 2431}
2403 2432
2404static inline void take_option(char **to, char *from, int *first, int len) 2433static inline void take_option(char **to, char *from, int *first, int len)
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index ff4e19ccd8f8..e1d9db779983 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -47,11 +47,13 @@
47/* Non-mount related flags */ 47/* Non-mount related flags */
48#define SE_SBINITIALIZED 0x10 48#define SE_SBINITIALIZED 0x10
49#define SE_SBPROC 0x20 49#define SE_SBPROC 0x20
50#define SE_SBLABELSUPP 0x40
50 51
51#define CONTEXT_STR "context=" 52#define CONTEXT_STR "context="
52#define FSCONTEXT_STR "fscontext=" 53#define FSCONTEXT_STR "fscontext="
53#define ROOTCONTEXT_STR "rootcontext=" 54#define ROOTCONTEXT_STR "rootcontext="
54#define DEFCONTEXT_STR "defcontext=" 55#define DEFCONTEXT_STR "defcontext="
56#define LABELSUPP_STR "seclabel"
55 57
56struct netlbl_lsm_secattr; 58struct netlbl_lsm_secattr;
57 59