aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c241
-rw-r--r--security/selinux/include/objsec.h2
-rw-r--r--security/selinux/include/security.h8
3 files changed, 74 insertions, 177 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 00815973d412..a69d6f8970ca 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->initialized = 1; 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
@@ -487,23 +495,22 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
487 495
488 security_init_mnt_opts(opts); 496 security_init_mnt_opts(opts);
489 497
490 if (!sbsec->initialized) 498 if (!(sbsec->flags & SE_SBINITIALIZED))
491 return -EINVAL; 499 return -EINVAL;
492 500
493 if (!ss_initialized) 501 if (!ss_initialized)
494 return -EINVAL; 502 return -EINVAL;
495 503
496 /* 504 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 */ 505 /* count the number of mount options for this sb */
502 for (i = 0; i < 8; i++) { 506 for (i = 0; i < 8; i++) {
503 if (tmp & 0x01) 507 if (tmp & 0x01)
504 opts->num_mnt_opts++; 508 opts->num_mnt_opts++;
505 tmp >>= 1; 509 tmp >>= 1;
506 } 510 }
511 /* Check if the Label support flag is set */
512 if (sbsec->flags & SE_SBLABELSUPP)
513 opts->num_mnt_opts++;
507 514
508 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);
509 if (!opts->mnt_opts) { 516 if (!opts->mnt_opts) {
@@ -549,6 +556,10 @@ static int selinux_get_mnt_opts(const struct super_block *sb,
549 opts->mnt_opts[i] = context; 556 opts->mnt_opts[i] = context;
550 opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT; 557 opts->mnt_opts_flags[i++] = ROOTCONTEXT_MNT;
551 } 558 }
559 if (sbsec->flags & SE_SBLABELSUPP) {
560 opts->mnt_opts[i] = NULL;
561 opts->mnt_opts_flags[i++] = SE_SBLABELSUPP;
562 }
552 563
553 BUG_ON(i != opts->num_mnt_opts); 564 BUG_ON(i != opts->num_mnt_opts);
554 565
@@ -562,8 +573,10 @@ out_free:
562static int bad_option(struct superblock_security_struct *sbsec, char flag, 573static int bad_option(struct superblock_security_struct *sbsec, char flag,
563 u32 old_sid, u32 new_sid) 574 u32 old_sid, u32 new_sid)
564{ 575{
576 char mnt_flags = sbsec->flags & SE_MNTMASK;
577
565 /* check if the old mount command had the same options */ 578 /* check if the old mount command had the same options */
566 if (sbsec->initialized) 579 if (sbsec->flags & SE_SBINITIALIZED)
567 if (!(sbsec->flags & flag) || 580 if (!(sbsec->flags & flag) ||
568 (old_sid != new_sid)) 581 (old_sid != new_sid))
569 return 1; 582 return 1;
@@ -571,8 +584,8 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
571 /* check if we were passed the same options twice, 584 /* check if we were passed the same options twice,
572 * aka someone passed context=a,context=b 585 * aka someone passed context=a,context=b
573 */ 586 */
574 if (!sbsec->initialized) 587 if (!(sbsec->flags & SE_SBINITIALIZED))
575 if (sbsec->flags & flag) 588 if (mnt_flags & flag)
576 return 1; 589 return 1;
577 return 0; 590 return 0;
578} 591}
@@ -626,7 +639,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
626 * this sb does not set any security options. (The first options 639 * this sb does not set any security options. (The first options
627 * will be used for both mounts) 640 * will be used for both mounts)
628 */ 641 */
629 if (sbsec->initialized && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) 642 if ((sbsec->flags & SE_SBINITIALIZED) && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
630 && (num_opts == 0)) 643 && (num_opts == 0))
631 goto out; 644 goto out;
632 645
@@ -637,6 +650,9 @@ static int selinux_set_mnt_opts(struct super_block *sb,
637 */ 650 */
638 for (i = 0; i < num_opts; i++) { 651 for (i = 0; i < num_opts; i++) {
639 u32 sid; 652 u32 sid;
653
654 if (flags[i] == SE_SBLABELSUPP)
655 continue;
640 rc = security_context_to_sid(mount_options[i], 656 rc = security_context_to_sid(mount_options[i],
641 strlen(mount_options[i]), &sid); 657 strlen(mount_options[i]), &sid);
642 if (rc) { 658 if (rc) {
@@ -690,19 +706,19 @@ static int selinux_set_mnt_opts(struct super_block *sb,
690 } 706 }
691 } 707 }
692 708
693 if (sbsec->initialized) { 709 if (sbsec->flags & SE_SBINITIALIZED) {
694 /* previously mounted with options, but not on this attempt? */ 710 /* previously mounted with options, but not on this attempt? */
695 if (sbsec->flags && !num_opts) 711 if ((sbsec->flags & SE_MNTMASK) && !num_opts)
696 goto out_double_mount; 712 goto out_double_mount;
697 rc = 0; 713 rc = 0;
698 goto out; 714 goto out;
699 } 715 }
700 716
701 if (strcmp(sb->s_type->name, "proc") == 0) 717 if (strcmp(sb->s_type->name, "proc") == 0)
702 sbsec->proc = 1; 718 sbsec->flags |= SE_SBPROC;
703 719
704 /* Determine the labeling behavior to use for this filesystem type. */ 720 /* 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); 721 rc = security_fs_use((sbsec->flags & SE_SBPROC) ? "proc" : sb->s_type->name, &sbsec->behavior, &sbsec->sid);
706 if (rc) { 722 if (rc) {
707 printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", 723 printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n",
708 __func__, sb->s_type->name, rc); 724 __func__, sb->s_type->name, rc);
@@ -806,10 +822,10 @@ static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
806 } 822 }
807 823
808 /* how can we clone if the old one wasn't set up?? */ 824 /* how can we clone if the old one wasn't set up?? */
809 BUG_ON(!oldsbsec->initialized); 825 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED));
810 826
811 /* if fs is reusing a sb, just let its options stand... */ 827 /* if fs is reusing a sb, just let its options stand... */
812 if (newsbsec->initialized) 828 if (newsbsec->flags & SE_SBINITIALIZED)
813 return; 829 return;
814 830
815 mutex_lock(&newsbsec->lock); 831 mutex_lock(&newsbsec->lock);
@@ -917,7 +933,8 @@ static int selinux_parse_opts_str(char *options,
917 goto out_err; 933 goto out_err;
918 } 934 }
919 break; 935 break;
920 936 case Opt_labelsupport:
937 break;
921 default: 938 default:
922 rc = -EINVAL; 939 rc = -EINVAL;
923 printk(KERN_WARNING "SELinux: unknown mount option\n"); 940 printk(KERN_WARNING "SELinux: unknown mount option\n");
@@ -999,7 +1016,12 @@ static void selinux_write_opts(struct seq_file *m,
999 char *prefix; 1016 char *prefix;
1000 1017
1001 for (i = 0; i < opts->num_mnt_opts; i++) { 1018 for (i = 0; i < opts->num_mnt_opts; i++) {
1002 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;
1003 1025
1004 switch (opts->mnt_opts_flags[i]) { 1026 switch (opts->mnt_opts_flags[i]) {
1005 case CONTEXT_MNT: 1027 case CONTEXT_MNT:
@@ -1014,6 +1036,10 @@ static void selinux_write_opts(struct seq_file *m,
1014 case DEFCONTEXT_MNT: 1036 case DEFCONTEXT_MNT:
1015 prefix = DEFCONTEXT_STR; 1037 prefix = DEFCONTEXT_STR;
1016 break; 1038 break;
1039 case SE_SBLABELSUPP:
1040 seq_putc(m, ',');
1041 seq_puts(m, LABELSUPP_STR);
1042 continue;
1017 default: 1043 default:
1018 BUG(); 1044 BUG();
1019 }; 1045 };
@@ -1209,7 +1235,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1209 goto out_unlock; 1235 goto out_unlock;
1210 1236
1211 sbsec = inode->i_sb->s_security; 1237 sbsec = inode->i_sb->s_security;
1212 if (!sbsec->initialized) { 1238 if (!(sbsec->flags & SE_SBINITIALIZED)) {
1213 /* Defer initialization until selinux_complete_init, 1239 /* Defer initialization until selinux_complete_init,
1214 after the initial policy is loaded and the security 1240 after the initial policy is loaded and the security
1215 server is ready to handle calls. */ 1241 server is ready to handle calls. */
@@ -1326,7 +1352,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1326 /* Default to the fs superblock SID. */ 1352 /* Default to the fs superblock SID. */
1327 isec->sid = sbsec->sid; 1353 isec->sid = sbsec->sid;
1328 1354
1329 if (sbsec->proc && !S_ISLNK(inode->i_mode)) { 1355 if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) {
1330 struct proc_inode *proci = PROC_I(inode); 1356 struct proc_inode *proci = PROC_I(inode);
1331 if (proci->pde) { 1357 if (proci->pde) {
1332 isec->sclass = inode_mode_to_security_class(inode->i_mode); 1358 isec->sclass = inode_mode_to_security_class(inode->i_mode);
@@ -1587,7 +1613,7 @@ static int may_create(struct inode *dir,
1587 if (rc) 1613 if (rc)
1588 return rc; 1614 return rc;
1589 1615
1590 if (!newsid || sbsec->behavior == SECURITY_FS_USE_MNTPOINT) { 1616 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
1591 rc = security_transition_sid(sid, dsec->sid, tclass, &newsid); 1617 rc = security_transition_sid(sid, dsec->sid, tclass, &newsid);
1592 if (rc) 1618 if (rc)
1593 return rc; 1619 return rc;
@@ -1866,6 +1892,16 @@ static int selinux_capset(struct cred *new, const struct cred *old,
1866 return cred_has_perm(old, new, PROCESS__SETCAP); 1892 return cred_has_perm(old, new, PROCESS__SETCAP);
1867} 1893}
1868 1894
1895/*
1896 * (This comment used to live with the selinux_task_setuid hook,
1897 * which was removed).
1898 *
1899 * Since setuid only affects the current process, and since the SELinux
1900 * controls are not based on the Linux identity attributes, SELinux does not
1901 * need to control this operation. However, SELinux does control the use of
1902 * the CAP_SETUID and CAP_SETGID capabilities using the capable hook.
1903 */
1904
1869static int selinux_capable(struct task_struct *tsk, const struct cred *cred, 1905static int selinux_capable(struct task_struct *tsk, const struct cred *cred,
1870 int cap, int audit) 1906 int cap, int audit)
1871{ 1907{
@@ -2156,11 +2192,6 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
2156 return 0; 2192 return 0;
2157} 2193}
2158 2194
2159static int selinux_bprm_check_security(struct linux_binprm *bprm)
2160{
2161 return secondary_ops->bprm_check_security(bprm);
2162}
2163
2164static int selinux_bprm_secureexec(struct linux_binprm *bprm) 2195static int selinux_bprm_secureexec(struct linux_binprm *bprm)
2165{ 2196{
2166 const struct cred *cred = current_cred(); 2197 const struct cred *cred = current_cred();
@@ -2290,8 +2321,6 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
2290 struct rlimit *rlim, *initrlim; 2321 struct rlimit *rlim, *initrlim;
2291 int rc, i; 2322 int rc, i;
2292 2323
2293 secondary_ops->bprm_committing_creds(bprm);
2294
2295 new_tsec = bprm->cred->security; 2324 new_tsec = bprm->cred->security;
2296 if (new_tsec->sid == new_tsec->osid) 2325 if (new_tsec->sid == new_tsec->osid)
2297 return; 2326 return;
@@ -2337,8 +2366,6 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
2337 int rc, i; 2366 int rc, i;
2338 unsigned long flags; 2367 unsigned long flags;
2339 2368
2340 secondary_ops->bprm_committed_creds(bprm);
2341
2342 osid = tsec->osid; 2369 osid = tsec->osid;
2343 sid = tsec->sid; 2370 sid = tsec->sid;
2344 2371
@@ -2400,7 +2427,8 @@ static inline int selinux_option(char *option, int len)
2400 return (match_prefix(CONTEXT_STR, sizeof(CONTEXT_STR)-1, option, len) || 2427 return (match_prefix(CONTEXT_STR, sizeof(CONTEXT_STR)-1, option, len) ||
2401 match_prefix(FSCONTEXT_STR, sizeof(FSCONTEXT_STR)-1, option, len) || 2428 match_prefix(FSCONTEXT_STR, sizeof(FSCONTEXT_STR)-1, option, len) ||
2402 match_prefix(DEFCONTEXT_STR, sizeof(DEFCONTEXT_STR)-1, option, len) || 2429 match_prefix(DEFCONTEXT_STR, sizeof(DEFCONTEXT_STR)-1, option, len) ||
2403 match_prefix(ROOTCONTEXT_STR, sizeof(ROOTCONTEXT_STR)-1, option, len)); 2430 match_prefix(ROOTCONTEXT_STR, sizeof(ROOTCONTEXT_STR)-1, option, len) ||
2431 match_prefix(LABELSUPP_STR, sizeof(LABELSUPP_STR)-1, option, len));
2404} 2432}
2405 2433
2406static inline void take_option(char **to, char *from, int *first, int len) 2434static inline void take_option(char **to, char *from, int *first, int len)
@@ -2513,11 +2541,6 @@ static int selinux_mount(char *dev_name,
2513 void *data) 2541 void *data)
2514{ 2542{
2515 const struct cred *cred = current_cred(); 2543 const struct cred *cred = current_cred();
2516 int rc;
2517
2518 rc = secondary_ops->sb_mount(dev_name, path, type, flags, data);
2519 if (rc)
2520 return rc;
2521 2544
2522 if (flags & MS_REMOUNT) 2545 if (flags & MS_REMOUNT)
2523 return superblock_has_perm(cred, path->mnt->mnt_sb, 2546 return superblock_has_perm(cred, path->mnt->mnt_sb,
@@ -2530,11 +2553,6 @@ static int selinux_mount(char *dev_name,
2530static int selinux_umount(struct vfsmount *mnt, int flags) 2553static int selinux_umount(struct vfsmount *mnt, int flags)
2531{ 2554{
2532 const struct cred *cred = current_cred(); 2555 const struct cred *cred = current_cred();
2533 int rc;
2534
2535 rc = secondary_ops->sb_umount(mnt, flags);
2536 if (rc)
2537 return rc;
2538 2556
2539 return superblock_has_perm(cred, mnt->mnt_sb, 2557 return superblock_has_perm(cred, mnt->mnt_sb,
2540 FILESYSTEM__UNMOUNT, NULL); 2558 FILESYSTEM__UNMOUNT, NULL);
@@ -2570,7 +2588,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2570 sid = tsec->sid; 2588 sid = tsec->sid;
2571 newsid = tsec->create_sid; 2589 newsid = tsec->create_sid;
2572 2590
2573 if (!newsid || sbsec->behavior == SECURITY_FS_USE_MNTPOINT) { 2591 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
2574 rc = security_transition_sid(sid, dsec->sid, 2592 rc = security_transition_sid(sid, dsec->sid,
2575 inode_mode_to_security_class(inode->i_mode), 2593 inode_mode_to_security_class(inode->i_mode),
2576 &newsid); 2594 &newsid);
@@ -2585,14 +2603,14 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2585 } 2603 }
2586 2604
2587 /* Possibly defer initialization to selinux_complete_init. */ 2605 /* Possibly defer initialization to selinux_complete_init. */
2588 if (sbsec->initialized) { 2606 if (sbsec->flags & SE_SBINITIALIZED) {
2589 struct inode_security_struct *isec = inode->i_security; 2607 struct inode_security_struct *isec = inode->i_security;
2590 isec->sclass = inode_mode_to_security_class(inode->i_mode); 2608 isec->sclass = inode_mode_to_security_class(inode->i_mode);
2591 isec->sid = newsid; 2609 isec->sid = newsid;
2592 isec->initialized = 1; 2610 isec->initialized = 1;
2593 } 2611 }
2594 2612
2595 if (!ss_initialized || sbsec->behavior == SECURITY_FS_USE_MNTPOINT) 2613 if (!ss_initialized || !(sbsec->flags & SE_SBLABELSUPP))
2596 return -EOPNOTSUPP; 2614 return -EOPNOTSUPP;
2597 2615
2598 if (name) { 2616 if (name) {
@@ -2622,21 +2640,11 @@ static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int ma
2622 2640
2623static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) 2641static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
2624{ 2642{
2625 int rc;
2626
2627 rc = secondary_ops->inode_link(old_dentry, dir, new_dentry);
2628 if (rc)
2629 return rc;
2630 return may_link(dir, old_dentry, MAY_LINK); 2643 return may_link(dir, old_dentry, MAY_LINK);
2631} 2644}
2632 2645
2633static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry) 2646static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry)
2634{ 2647{
2635 int rc;
2636
2637 rc = secondary_ops->inode_unlink(dir, dentry);
2638 if (rc)
2639 return rc;
2640 return may_link(dir, dentry, MAY_UNLINK); 2648 return may_link(dir, dentry, MAY_UNLINK);
2641} 2649}
2642 2650
@@ -2657,12 +2665,6 @@ static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry)
2657 2665
2658static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) 2666static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
2659{ 2667{
2660 int rc;
2661
2662 rc = secondary_ops->inode_mknod(dir, dentry, mode, dev);
2663 if (rc)
2664 return rc;
2665
2666 return may_create(dir, dentry, inode_mode_to_security_class(mode)); 2668 return may_create(dir, dentry, inode_mode_to_security_class(mode));
2667} 2669}
2668 2670
@@ -2682,22 +2684,13 @@ static int selinux_inode_readlink(struct dentry *dentry)
2682static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata) 2684static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
2683{ 2685{
2684 const struct cred *cred = current_cred(); 2686 const struct cred *cred = current_cred();
2685 int rc;
2686 2687
2687 rc = secondary_ops->inode_follow_link(dentry, nameidata);
2688 if (rc)
2689 return rc;
2690 return dentry_has_perm(cred, NULL, dentry, FILE__READ); 2688 return dentry_has_perm(cred, NULL, dentry, FILE__READ);
2691} 2689}
2692 2690
2693static int selinux_inode_permission(struct inode *inode, int mask) 2691static int selinux_inode_permission(struct inode *inode, int mask)
2694{ 2692{
2695 const struct cred *cred = current_cred(); 2693 const struct cred *cred = current_cred();
2696 int rc;
2697
2698 rc = secondary_ops->inode_permission(inode, mask);
2699 if (rc)
2700 return rc;
2701 2694
2702 if (!mask) { 2695 if (!mask) {
2703 /* No permission to check. Existence test. */ 2696 /* No permission to check. Existence test. */
@@ -2711,11 +2704,6 @@ static int selinux_inode_permission(struct inode *inode, int mask)
2711static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) 2704static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
2712{ 2705{
2713 const struct cred *cred = current_cred(); 2706 const struct cred *cred = current_cred();
2714 int rc;
2715
2716 rc = secondary_ops->inode_setattr(dentry, iattr);
2717 if (rc)
2718 return rc;
2719 2707
2720 if (iattr->ia_valid & ATTR_FORCE) 2708 if (iattr->ia_valid & ATTR_FORCE)
2721 return 0; 2709 return 0;
@@ -2769,7 +2757,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2769 return selinux_inode_setotherxattr(dentry, name); 2757 return selinux_inode_setotherxattr(dentry, name);
2770 2758
2771 sbsec = inode->i_sb->s_security; 2759 sbsec = inode->i_sb->s_security;
2772 if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT) 2760 if (!(sbsec->flags & SE_SBLABELSUPP))
2773 return -EOPNOTSUPP; 2761 return -EOPNOTSUPP;
2774 2762
2775 if (!is_owner_or_cap(inode)) 2763 if (!is_owner_or_cap(inode))
@@ -2931,16 +2919,6 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t
2931 return len; 2919 return len;
2932} 2920}
2933 2921
2934static int selinux_inode_need_killpriv(struct dentry *dentry)
2935{
2936 return secondary_ops->inode_need_killpriv(dentry);
2937}
2938
2939static int selinux_inode_killpriv(struct dentry *dentry)
2940{
2941 return secondary_ops->inode_killpriv(dentry);
2942}
2943
2944static void selinux_inode_getsecid(const struct inode *inode, u32 *secid) 2922static void selinux_inode_getsecid(const struct inode *inode, u32 *secid)
2945{ 2923{
2946 struct inode_security_struct *isec = inode->i_security; 2924 struct inode_security_struct *isec = inode->i_security;
@@ -3078,18 +3056,13 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
3078 unsigned long prot) 3056 unsigned long prot)
3079{ 3057{
3080 const struct cred *cred = current_cred(); 3058 const struct cred *cred = current_cred();
3081 int rc;
3082
3083 rc = secondary_ops->file_mprotect(vma, reqprot, prot);
3084 if (rc)
3085 return rc;
3086 3059
3087 if (selinux_checkreqprot) 3060 if (selinux_checkreqprot)
3088 prot = reqprot; 3061 prot = reqprot;
3089 3062
3090#ifndef CONFIG_PPC32 3063#ifndef CONFIG_PPC32
3091 if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) { 3064 if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
3092 rc = 0; 3065 int rc = 0;
3093 if (vma->vm_start >= vma->vm_mm->start_brk && 3066 if (vma->vm_start >= vma->vm_mm->start_brk &&
3094 vma->vm_end <= vma->vm_mm->brk) { 3067 vma->vm_end <= vma->vm_mm->brk) {
3095 rc = cred_has_perm(cred, cred, PROCESS__EXECHEAP); 3068 rc = cred_has_perm(cred, cred, PROCESS__EXECHEAP);
@@ -3239,12 +3212,6 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred)
3239 3212
3240static int selinux_task_create(unsigned long clone_flags) 3213static int selinux_task_create(unsigned long clone_flags)
3241{ 3214{
3242 int rc;
3243
3244 rc = secondary_ops->task_create(clone_flags);
3245 if (rc)
3246 return rc;
3247
3248 return current_has_perm(current, PROCESS__FORK); 3215 return current_has_perm(current, PROCESS__FORK);
3249} 3216}
3250 3217
@@ -3278,14 +3245,6 @@ static int selinux_cred_prepare(struct cred *new, const struct cred *old,
3278} 3245}
3279 3246
3280/* 3247/*
3281 * commit new credentials
3282 */
3283static void selinux_cred_commit(struct cred *new, const struct cred *old)
3284{
3285 secondary_ops->cred_commit(new, old);
3286}
3287
3288/*
3289 * set the security data for a kernel service 3248 * set the security data for a kernel service
3290 * - all the creation contexts are set to unlabelled 3249 * - all the creation contexts are set to unlabelled
3291 */ 3250 */
@@ -3329,29 +3288,6 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
3329 return 0; 3288 return 0;
3330} 3289}
3331 3290
3332static int selinux_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
3333{
3334 /* Since setuid only affects the current process, and
3335 since the SELinux controls are not based on the Linux
3336 identity attributes, SELinux does not need to control
3337 this operation. However, SELinux does control the use
3338 of the CAP_SETUID and CAP_SETGID capabilities using the
3339 capable hook. */
3340 return 0;
3341}
3342
3343static int selinux_task_fix_setuid(struct cred *new, const struct cred *old,
3344 int flags)
3345{
3346 return secondary_ops->task_fix_setuid(new, old, flags);
3347}
3348
3349static int selinux_task_setgid(gid_t id0, gid_t id1, gid_t id2, int flags)
3350{
3351 /* See the comment for setuid above. */
3352 return 0;
3353}
3354
3355static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) 3291static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
3356{ 3292{
3357 return current_has_perm(p, PROCESS__SETPGID); 3293 return current_has_perm(p, PROCESS__SETPGID);
@@ -3372,12 +3308,6 @@ static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
3372 *secid = task_sid(p); 3308 *secid = task_sid(p);
3373} 3309}
3374 3310
3375static int selinux_task_setgroups(struct group_info *group_info)
3376{
3377 /* See the comment for setuid above. */
3378 return 0;
3379}
3380
3381static int selinux_task_setnice(struct task_struct *p, int nice) 3311static int selinux_task_setnice(struct task_struct *p, int nice)
3382{ 3312{
3383 int rc; 3313 int rc;
@@ -3408,11 +3338,6 @@ static int selinux_task_getioprio(struct task_struct *p)
3408static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim) 3338static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim)
3409{ 3339{
3410 struct rlimit *old_rlim = current->signal->rlim + resource; 3340 struct rlimit *old_rlim = current->signal->rlim + resource;
3411 int rc;
3412
3413 rc = secondary_ops->task_setrlimit(resource, new_rlim);
3414 if (rc)
3415 return rc;
3416 3341
3417 /* Control the ability to change the hard limit (whether 3342 /* Control the ability to change the hard limit (whether
3418 lowering or raising it), so that the hard limit can 3343 lowering or raising it), so that the hard limit can
@@ -3451,10 +3376,6 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info,
3451 u32 perm; 3376 u32 perm;
3452 int rc; 3377 int rc;
3453 3378
3454 rc = secondary_ops->task_kill(p, info, sig, secid);
3455 if (rc)
3456 return rc;
3457
3458 if (!sig) 3379 if (!sig)
3459 perm = PROCESS__SIGNULL; /* null signal; existence test */ 3380 perm = PROCESS__SIGNULL; /* null signal; existence test */
3460 else 3381 else
@@ -3467,18 +3388,6 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info,
3467 return rc; 3388 return rc;
3468} 3389}
3469 3390
3470static int selinux_task_prctl(int option,
3471 unsigned long arg2,
3472 unsigned long arg3,
3473 unsigned long arg4,
3474 unsigned long arg5)
3475{
3476 /* The current prctl operations do not appear to require
3477 any SELinux controls since they merely observe or modify
3478 the state of the current process. */
3479 return secondary_ops->task_prctl(option, arg2, arg3, arg4, arg5);
3480}
3481
3482static int selinux_task_wait(struct task_struct *p) 3391static int selinux_task_wait(struct task_struct *p)
3483{ 3392{
3484 return task_has_perm(p, current, PROCESS__SIGCHLD); 3393 return task_has_perm(p, current, PROCESS__SIGCHLD);
@@ -4047,10 +3956,6 @@ static int selinux_socket_unix_stream_connect(struct socket *sock,
4047 struct avc_audit_data ad; 3956 struct avc_audit_data ad;
4048 int err; 3957 int err;
4049 3958
4050 err = secondary_ops->unix_stream_connect(sock, other, newsk);
4051 if (err)
4052 return err;
4053
4054 isec = SOCK_INODE(sock)->i_security; 3959 isec = SOCK_INODE(sock)->i_security;
4055 other_isec = SOCK_INODE(other)->i_security; 3960 other_isec = SOCK_INODE(other)->i_security;
4056 3961
@@ -5167,11 +5072,6 @@ static int selinux_shm_shmat(struct shmid_kernel *shp,
5167 char __user *shmaddr, int shmflg) 5072 char __user *shmaddr, int shmflg)
5168{ 5073{
5169 u32 perms; 5074 u32 perms;
5170 int rc;
5171
5172 rc = secondary_ops->shm_shmat(shp, shmaddr, shmflg);
5173 if (rc)
5174 return rc;
5175 5075
5176 if (shmflg & SHM_RDONLY) 5076 if (shmflg & SHM_RDONLY)
5177 perms = SHM__READ; 5077 perms = SHM__READ;
@@ -5581,7 +5481,6 @@ static struct security_operations selinux_ops = {
5581 .netlink_recv = selinux_netlink_recv, 5481 .netlink_recv = selinux_netlink_recv,
5582 5482
5583 .bprm_set_creds = selinux_bprm_set_creds, 5483 .bprm_set_creds = selinux_bprm_set_creds,
5584 .bprm_check_security = selinux_bprm_check_security,
5585 .bprm_committing_creds = selinux_bprm_committing_creds, 5484 .bprm_committing_creds = selinux_bprm_committing_creds,
5586 .bprm_committed_creds = selinux_bprm_committed_creds, 5485 .bprm_committed_creds = selinux_bprm_committed_creds,
5587 .bprm_secureexec = selinux_bprm_secureexec, 5486 .bprm_secureexec = selinux_bprm_secureexec,
@@ -5623,8 +5522,6 @@ static struct security_operations selinux_ops = {
5623 .inode_getsecurity = selinux_inode_getsecurity, 5522 .inode_getsecurity = selinux_inode_getsecurity,
5624 .inode_setsecurity = selinux_inode_setsecurity, 5523 .inode_setsecurity = selinux_inode_setsecurity,
5625 .inode_listsecurity = selinux_inode_listsecurity, 5524 .inode_listsecurity = selinux_inode_listsecurity,
5626 .inode_need_killpriv = selinux_inode_need_killpriv,
5627 .inode_killpriv = selinux_inode_killpriv,
5628 .inode_getsecid = selinux_inode_getsecid, 5525 .inode_getsecid = selinux_inode_getsecid,
5629 5526
5630 .file_permission = selinux_file_permission, 5527 .file_permission = selinux_file_permission,
@@ -5644,17 +5541,12 @@ static struct security_operations selinux_ops = {
5644 .task_create = selinux_task_create, 5541 .task_create = selinux_task_create,
5645 .cred_free = selinux_cred_free, 5542 .cred_free = selinux_cred_free,
5646 .cred_prepare = selinux_cred_prepare, 5543 .cred_prepare = selinux_cred_prepare,
5647 .cred_commit = selinux_cred_commit,
5648 .kernel_act_as = selinux_kernel_act_as, 5544 .kernel_act_as = selinux_kernel_act_as,
5649 .kernel_create_files_as = selinux_kernel_create_files_as, 5545 .kernel_create_files_as = selinux_kernel_create_files_as,
5650 .task_setuid = selinux_task_setuid,
5651 .task_fix_setuid = selinux_task_fix_setuid,
5652 .task_setgid = selinux_task_setgid,
5653 .task_setpgid = selinux_task_setpgid, 5546 .task_setpgid = selinux_task_setpgid,
5654 .task_getpgid = selinux_task_getpgid, 5547 .task_getpgid = selinux_task_getpgid,
5655 .task_getsid = selinux_task_getsid, 5548 .task_getsid = selinux_task_getsid,
5656 .task_getsecid = selinux_task_getsecid, 5549 .task_getsecid = selinux_task_getsecid,
5657 .task_setgroups = selinux_task_setgroups,
5658 .task_setnice = selinux_task_setnice, 5550 .task_setnice = selinux_task_setnice,
5659 .task_setioprio = selinux_task_setioprio, 5551 .task_setioprio = selinux_task_setioprio,
5660 .task_getioprio = selinux_task_getioprio, 5552 .task_getioprio = selinux_task_getioprio,
@@ -5664,7 +5556,6 @@ static struct security_operations selinux_ops = {
5664 .task_movememory = selinux_task_movememory, 5556 .task_movememory = selinux_task_movememory,
5665 .task_kill = selinux_task_kill, 5557 .task_kill = selinux_task_kill,
5666 .task_wait = selinux_task_wait, 5558 .task_wait = selinux_task_wait,
5667 .task_prctl = selinux_task_prctl,
5668 .task_to_inode = selinux_task_to_inode, 5559 .task_to_inode = selinux_task_to_inode,
5669 5560
5670 .ipc_permission = selinux_ipc_permission, 5561 .ipc_permission = selinux_ipc_permission,
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..e1d9db779983 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -37,15 +37,23 @@
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
50#define SE_SBLABELSUPP 0x40
44 51
45#define CONTEXT_STR "context=" 52#define CONTEXT_STR "context="
46#define FSCONTEXT_STR "fscontext=" 53#define FSCONTEXT_STR "fscontext="
47#define ROOTCONTEXT_STR "rootcontext=" 54#define ROOTCONTEXT_STR "rootcontext="
48#define DEFCONTEXT_STR "defcontext=" 55#define DEFCONTEXT_STR "defcontext="
56#define LABELSUPP_STR "seclabel"
49 57
50struct netlbl_lsm_secattr; 58struct netlbl_lsm_secattr;
51 59