aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorDavid P. Quigley <dpquigl@tycho.nsa.gov>2009-01-16 09:22:03 -0500
committerJames Morris <jmorris@macbook.localdomain>2009-01-18 17:47:06 -0500
commit11689d47f0957121920c9ec646eb5d838755853a (patch)
tree187b4179c0b7b9430bb9e62f6bba474a2d011235 /security/selinux/hooks.c
parent0d90a7ec48c704025307b129413bc62451b20ab3 (diff)
SELinux: Add new security mount option to indicate security label support.
There is no easy way to tell if a file system supports SELinux security labeling. Because of this a new flag is being added to the super block security structure to indicate that the particular super block supports labeling. This flag is set for file systems using the xattr, task, and transition labeling methods unless that behavior is overridden by context mounts. Signed-off-by: David P. Quigley <dpquigl@tycho.nsa.gov> Acked-by: Eric Paris <eparis@redhat.com> Signed-off-by: James Morris <jmorris@macbook.localdomain>
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c39
1 files changed, 34 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)