diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/hooks.c | 38 | ||||
-rw-r--r-- | security/selinux/include/objsec.h | 2 | ||||
-rw-r--r-- | security/selinux/include/security.h | 6 |
3 files changed, 24 insertions, 22 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 00815973d412..473adc5f4f9a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -431,7 +431,7 @@ static int sb_finish_set_opts(struct super_block *sb) | |||
431 | } | 431 | } |
432 | } | 432 | } |
433 | 433 | ||
434 | sbsec->initialized = 1; | 434 | sbsec->flags |= SE_SBINITIALIZED; |
435 | 435 | ||
436 | if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) | 436 | if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) |
437 | printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n", | 437 | printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n", |
@@ -487,17 +487,13 @@ static int selinux_get_mnt_opts(const struct super_block *sb, | |||
487 | 487 | ||
488 | security_init_mnt_opts(opts); | 488 | security_init_mnt_opts(opts); |
489 | 489 | ||
490 | if (!sbsec->initialized) | 490 | if (!(sbsec->flags & SE_SBINITIALIZED)) |
491 | return -EINVAL; | 491 | return -EINVAL; |
492 | 492 | ||
493 | if (!ss_initialized) | 493 | if (!ss_initialized) |
494 | return -EINVAL; | 494 | return -EINVAL; |
495 | 495 | ||
496 | /* | 496 | tmp = sbsec->flags & SE_MNTMASK; |
497 | * if we ever use sbsec flags for anything other than tracking mount | ||
498 | * settings this is going to need a mask | ||
499 | */ | ||
500 | tmp = sbsec->flags; | ||
501 | /* count the number of mount options for this sb */ | 497 | /* count the number of mount options for this sb */ |
502 | for (i = 0; i < 8; i++) { | 498 | for (i = 0; i < 8; i++) { |
503 | if (tmp & 0x01) | 499 | if (tmp & 0x01) |
@@ -562,8 +558,10 @@ out_free: | |||
562 | static int bad_option(struct superblock_security_struct *sbsec, char flag, | 558 | static int bad_option(struct superblock_security_struct *sbsec, char flag, |
563 | u32 old_sid, u32 new_sid) | 559 | u32 old_sid, u32 new_sid) |
564 | { | 560 | { |
561 | char mnt_flags = sbsec->flags & SE_MNTMASK; | ||
562 | |||
565 | /* check if the old mount command had the same options */ | 563 | /* check if the old mount command had the same options */ |
566 | if (sbsec->initialized) | 564 | if (sbsec->flags & SE_SBINITIALIZED) |
567 | if (!(sbsec->flags & flag) || | 565 | if (!(sbsec->flags & flag) || |
568 | (old_sid != new_sid)) | 566 | (old_sid != new_sid)) |
569 | return 1; | 567 | return 1; |
@@ -571,8 +569,8 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag, | |||
571 | /* check if we were passed the same options twice, | 569 | /* check if we were passed the same options twice, |
572 | * aka someone passed context=a,context=b | 570 | * aka someone passed context=a,context=b |
573 | */ | 571 | */ |
574 | if (!sbsec->initialized) | 572 | if (!(sbsec->flags & SE_SBINITIALIZED)) |
575 | if (sbsec->flags & flag) | 573 | if (mnt_flags & flag) |
576 | return 1; | 574 | return 1; |
577 | return 0; | 575 | return 0; |
578 | } | 576 | } |
@@ -626,7 +624,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
626 | * this sb does not set any security options. (The first options | 624 | * this sb does not set any security options. (The first options |
627 | * will be used for both mounts) | 625 | * will be used for both mounts) |
628 | */ | 626 | */ |
629 | if (sbsec->initialized && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) | 627 | if ((sbsec->flags & SE_SBINITIALIZED) && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) |
630 | && (num_opts == 0)) | 628 | && (num_opts == 0)) |
631 | goto out; | 629 | goto out; |
632 | 630 | ||
@@ -690,19 +688,19 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
690 | } | 688 | } |
691 | } | 689 | } |
692 | 690 | ||
693 | if (sbsec->initialized) { | 691 | if (sbsec->flags & SE_SBINITIALIZED) { |
694 | /* previously mounted with options, but not on this attempt? */ | 692 | /* previously mounted with options, but not on this attempt? */ |
695 | if (sbsec->flags && !num_opts) | 693 | if ((sbsec->flags & SE_MNTMASK) && !num_opts) |
696 | goto out_double_mount; | 694 | goto out_double_mount; |
697 | rc = 0; | 695 | rc = 0; |
698 | goto out; | 696 | goto out; |
699 | } | 697 | } |
700 | 698 | ||
701 | if (strcmp(sb->s_type->name, "proc") == 0) | 699 | if (strcmp(sb->s_type->name, "proc") == 0) |
702 | sbsec->proc = 1; | 700 | sbsec->flags |= SE_SBPROC; |
703 | 701 | ||
704 | /* Determine the labeling behavior to use for this filesystem type. */ | 702 | /* Determine the labeling behavior to use for this filesystem type. */ |
705 | rc = security_fs_use(sbsec->proc ? "proc" : sb->s_type->name, &sbsec->behavior, &sbsec->sid); | 703 | rc = security_fs_use((sbsec->flags & SE_SBPROC) ? "proc" : sb->s_type->name, &sbsec->behavior, &sbsec->sid); |
706 | if (rc) { | 704 | if (rc) { |
707 | printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", | 705 | printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", |
708 | __func__, sb->s_type->name, rc); | 706 | __func__, sb->s_type->name, rc); |
@@ -806,10 +804,10 @@ static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb, | |||
806 | } | 804 | } |
807 | 805 | ||
808 | /* how can we clone if the old one wasn't set up?? */ | 806 | /* how can we clone if the old one wasn't set up?? */ |
809 | BUG_ON(!oldsbsec->initialized); | 807 | BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED)); |
810 | 808 | ||
811 | /* if fs is reusing a sb, just let its options stand... */ | 809 | /* if fs is reusing a sb, just let its options stand... */ |
812 | if (newsbsec->initialized) | 810 | if (newsbsec->flags & SE_SBINITIALIZED) |
813 | return; | 811 | return; |
814 | 812 | ||
815 | mutex_lock(&newsbsec->lock); | 813 | mutex_lock(&newsbsec->lock); |
@@ -1209,7 +1207,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1209 | goto out_unlock; | 1207 | goto out_unlock; |
1210 | 1208 | ||
1211 | sbsec = inode->i_sb->s_security; | 1209 | sbsec = inode->i_sb->s_security; |
1212 | if (!sbsec->initialized) { | 1210 | if (!(sbsec->flags & SE_SBINITIALIZED)) { |
1213 | /* Defer initialization until selinux_complete_init, | 1211 | /* Defer initialization until selinux_complete_init, |
1214 | after the initial policy is loaded and the security | 1212 | after the initial policy is loaded and the security |
1215 | server is ready to handle calls. */ | 1213 | server is ready to handle calls. */ |
@@ -1326,7 +1324,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1326 | /* Default to the fs superblock SID. */ | 1324 | /* Default to the fs superblock SID. */ |
1327 | isec->sid = sbsec->sid; | 1325 | isec->sid = sbsec->sid; |
1328 | 1326 | ||
1329 | if (sbsec->proc && !S_ISLNK(inode->i_mode)) { | 1327 | if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) { |
1330 | struct proc_inode *proci = PROC_I(inode); | 1328 | struct proc_inode *proci = PROC_I(inode); |
1331 | if (proci->pde) { | 1329 | if (proci->pde) { |
1332 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | 1330 | isec->sclass = inode_mode_to_security_class(inode->i_mode); |
@@ -2585,7 +2583,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
2585 | } | 2583 | } |
2586 | 2584 | ||
2587 | /* Possibly defer initialization to selinux_complete_init. */ | 2585 | /* Possibly defer initialization to selinux_complete_init. */ |
2588 | if (sbsec->initialized) { | 2586 | if (sbsec->flags & SE_SBINITIALIZED) { |
2589 | struct inode_security_struct *isec = inode->i_security; | 2587 | struct inode_security_struct *isec = inode->i_security; |
2590 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | 2588 | isec->sclass = inode_mode_to_security_class(inode->i_mode); |
2591 | isec->sid = newsid; | 2589 | isec->sid = newsid; |
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 3cc45168f674..c4e062336ef3 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h | |||
@@ -60,9 +60,7 @@ struct superblock_security_struct { | |||
60 | u32 def_sid; /* default SID for labeling */ | 60 | u32 def_sid; /* default SID for labeling */ |
61 | u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ | 61 | u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ |
62 | unsigned int behavior; /* labeling behavior */ | 62 | unsigned int behavior; /* labeling behavior */ |
63 | unsigned char initialized; /* initialization flag */ | ||
64 | unsigned char flags; /* which mount options were specified */ | 63 | unsigned char flags; /* which mount options were specified */ |
65 | unsigned char proc; /* proc fs */ | ||
66 | struct mutex lock; | 64 | struct mutex lock; |
67 | struct list_head isec_head; | 65 | struct list_head isec_head; |
68 | spinlock_t isec_lock; | 66 | spinlock_t isec_lock; |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 72447370bc95..ff4e19ccd8f8 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -37,10 +37,16 @@ | |||
37 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_BOUNDARY | 37 | #define POLICYDB_VERSION_MAX POLICYDB_VERSION_BOUNDARY |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | /* Mask for just the mount related flags */ | ||
41 | #define SE_MNTMASK 0x0f | ||
42 | /* Super block security struct flags for mount options */ | ||
40 | #define CONTEXT_MNT 0x01 | 43 | #define CONTEXT_MNT 0x01 |
41 | #define FSCONTEXT_MNT 0x02 | 44 | #define FSCONTEXT_MNT 0x02 |
42 | #define ROOTCONTEXT_MNT 0x04 | 45 | #define ROOTCONTEXT_MNT 0x04 |
43 | #define DEFCONTEXT_MNT 0x08 | 46 | #define DEFCONTEXT_MNT 0x08 |
47 | /* Non-mount related flags */ | ||
48 | #define SE_SBINITIALIZED 0x10 | ||
49 | #define SE_SBPROC 0x20 | ||
44 | 50 | ||
45 | #define CONTEXT_STR "context=" | 51 | #define CONTEXT_STR "context=" |
46 | #define FSCONTEXT_STR "fscontext=" | 52 | #define FSCONTEXT_STR "fscontext=" |