diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 214 |
1 files changed, 140 insertions, 74 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 28a5c4ee0705..d78f9e2f6df0 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -100,20 +100,24 @@ | |||
100 | #include "audit.h" | 100 | #include "audit.h" |
101 | #include "avc_ss.h" | 101 | #include "avc_ss.h" |
102 | 102 | ||
103 | struct selinux_state selinux_state; | ||
104 | |||
103 | /* SECMARK reference count */ | 105 | /* SECMARK reference count */ |
104 | static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0); | 106 | static atomic_t selinux_secmark_refcount = ATOMIC_INIT(0); |
105 | 107 | ||
106 | #ifdef CONFIG_SECURITY_SELINUX_DEVELOP | 108 | #ifdef CONFIG_SECURITY_SELINUX_DEVELOP |
107 | int selinux_enforcing; | 109 | static int selinux_enforcing_boot; |
108 | 110 | ||
109 | static int __init enforcing_setup(char *str) | 111 | static int __init enforcing_setup(char *str) |
110 | { | 112 | { |
111 | unsigned long enforcing; | 113 | unsigned long enforcing; |
112 | if (!kstrtoul(str, 0, &enforcing)) | 114 | if (!kstrtoul(str, 0, &enforcing)) |
113 | selinux_enforcing = enforcing ? 1 : 0; | 115 | selinux_enforcing_boot = enforcing ? 1 : 0; |
114 | return 1; | 116 | return 1; |
115 | } | 117 | } |
116 | __setup("enforcing=", enforcing_setup); | 118 | __setup("enforcing=", enforcing_setup); |
119 | #else | ||
120 | #define selinux_enforcing_boot 1 | ||
117 | #endif | 121 | #endif |
118 | 122 | ||
119 | #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM | 123 | #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM |
@@ -131,6 +135,19 @@ __setup("selinux=", selinux_enabled_setup); | |||
131 | int selinux_enabled = 1; | 135 | int selinux_enabled = 1; |
132 | #endif | 136 | #endif |
133 | 137 | ||
138 | static unsigned int selinux_checkreqprot_boot = | ||
139 | CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; | ||
140 | |||
141 | static int __init checkreqprot_setup(char *str) | ||
142 | { | ||
143 | unsigned long checkreqprot; | ||
144 | |||
145 | if (!kstrtoul(str, 0, &checkreqprot)) | ||
146 | selinux_checkreqprot_boot = checkreqprot ? 1 : 0; | ||
147 | return 1; | ||
148 | } | ||
149 | __setup("checkreqprot=", checkreqprot_setup); | ||
150 | |||
134 | static struct kmem_cache *sel_inode_cache; | 151 | static struct kmem_cache *sel_inode_cache; |
135 | static struct kmem_cache *file_security_cache; | 152 | static struct kmem_cache *file_security_cache; |
136 | 153 | ||
@@ -147,7 +164,8 @@ static struct kmem_cache *file_security_cache; | |||
147 | */ | 164 | */ |
148 | static int selinux_secmark_enabled(void) | 165 | static int selinux_secmark_enabled(void) |
149 | { | 166 | { |
150 | return (selinux_policycap_alwaysnetwork || atomic_read(&selinux_secmark_refcount)); | 167 | return (selinux_policycap_alwaysnetwork() || |
168 | atomic_read(&selinux_secmark_refcount)); | ||
151 | } | 169 | } |
152 | 170 | ||
153 | /** | 171 | /** |
@@ -162,7 +180,8 @@ static int selinux_secmark_enabled(void) | |||
162 | */ | 180 | */ |
163 | static int selinux_peerlbl_enabled(void) | 181 | static int selinux_peerlbl_enabled(void) |
164 | { | 182 | { |
165 | return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled()); | 183 | return (selinux_policycap_alwaysnetwork() || |
184 | netlbl_enabled() || selinux_xfrm_enabled()); | ||
166 | } | 185 | } |
167 | 186 | ||
168 | static int selinux_netcache_avc_callback(u32 event) | 187 | static int selinux_netcache_avc_callback(u32 event) |
@@ -266,7 +285,8 @@ static int __inode_security_revalidate(struct inode *inode, | |||
266 | 285 | ||
267 | might_sleep_if(may_sleep); | 286 | might_sleep_if(may_sleep); |
268 | 287 | ||
269 | if (ss_initialized && isec->initialized != LABEL_INITIALIZED) { | 288 | if (selinux_state.initialized && |
289 | isec->initialized != LABEL_INITIALIZED) { | ||
270 | if (!may_sleep) | 290 | if (!may_sleep) |
271 | return -ECHILD; | 291 | return -ECHILD; |
272 | 292 | ||
@@ -488,7 +508,7 @@ static int selinux_is_sblabel_mnt(struct super_block *sb) | |||
488 | !strcmp(sb->s_type->name, "debugfs") || | 508 | !strcmp(sb->s_type->name, "debugfs") || |
489 | !strcmp(sb->s_type->name, "tracefs") || | 509 | !strcmp(sb->s_type->name, "tracefs") || |
490 | !strcmp(sb->s_type->name, "rootfs") || | 510 | !strcmp(sb->s_type->name, "rootfs") || |
491 | (selinux_policycap_cgroupseclabel && | 511 | (selinux_policycap_cgroupseclabel() && |
492 | (!strcmp(sb->s_type->name, "cgroup") || | 512 | (!strcmp(sb->s_type->name, "cgroup") || |
493 | !strcmp(sb->s_type->name, "cgroup2"))); | 513 | !strcmp(sb->s_type->name, "cgroup2"))); |
494 | } | 514 | } |
@@ -588,7 +608,7 @@ static int selinux_get_mnt_opts(const struct super_block *sb, | |||
588 | if (!(sbsec->flags & SE_SBINITIALIZED)) | 608 | if (!(sbsec->flags & SE_SBINITIALIZED)) |
589 | return -EINVAL; | 609 | return -EINVAL; |
590 | 610 | ||
591 | if (!ss_initialized) | 611 | if (!selinux_state.initialized) |
592 | return -EINVAL; | 612 | return -EINVAL; |
593 | 613 | ||
594 | /* make sure we always check enough bits to cover the mask */ | 614 | /* make sure we always check enough bits to cover the mask */ |
@@ -619,21 +639,25 @@ static int selinux_get_mnt_opts(const struct super_block *sb, | |||
619 | 639 | ||
620 | i = 0; | 640 | i = 0; |
621 | if (sbsec->flags & FSCONTEXT_MNT) { | 641 | if (sbsec->flags & FSCONTEXT_MNT) { |
622 | rc = security_sid_to_context(sbsec->sid, &context, &len); | 642 | rc = security_sid_to_context(&selinux_state, sbsec->sid, |
643 | &context, &len); | ||
623 | if (rc) | 644 | if (rc) |
624 | goto out_free; | 645 | goto out_free; |
625 | opts->mnt_opts[i] = context; | 646 | opts->mnt_opts[i] = context; |
626 | opts->mnt_opts_flags[i++] = FSCONTEXT_MNT; | 647 | opts->mnt_opts_flags[i++] = FSCONTEXT_MNT; |
627 | } | 648 | } |
628 | if (sbsec->flags & CONTEXT_MNT) { | 649 | if (sbsec->flags & CONTEXT_MNT) { |
629 | rc = security_sid_to_context(sbsec->mntpoint_sid, &context, &len); | 650 | rc = security_sid_to_context(&selinux_state, |
651 | sbsec->mntpoint_sid, | ||
652 | &context, &len); | ||
630 | if (rc) | 653 | if (rc) |
631 | goto out_free; | 654 | goto out_free; |
632 | opts->mnt_opts[i] = context; | 655 | opts->mnt_opts[i] = context; |
633 | opts->mnt_opts_flags[i++] = CONTEXT_MNT; | 656 | opts->mnt_opts_flags[i++] = CONTEXT_MNT; |
634 | } | 657 | } |
635 | if (sbsec->flags & DEFCONTEXT_MNT) { | 658 | if (sbsec->flags & DEFCONTEXT_MNT) { |
636 | rc = security_sid_to_context(sbsec->def_sid, &context, &len); | 659 | rc = security_sid_to_context(&selinux_state, sbsec->def_sid, |
660 | &context, &len); | ||
637 | if (rc) | 661 | if (rc) |
638 | goto out_free; | 662 | goto out_free; |
639 | opts->mnt_opts[i] = context; | 663 | opts->mnt_opts[i] = context; |
@@ -643,7 +667,8 @@ static int selinux_get_mnt_opts(const struct super_block *sb, | |||
643 | struct dentry *root = sbsec->sb->s_root; | 667 | struct dentry *root = sbsec->sb->s_root; |
644 | struct inode_security_struct *isec = backing_inode_security(root); | 668 | struct inode_security_struct *isec = backing_inode_security(root); |
645 | 669 | ||
646 | rc = security_sid_to_context(isec->sid, &context, &len); | 670 | rc = security_sid_to_context(&selinux_state, isec->sid, |
671 | &context, &len); | ||
647 | if (rc) | 672 | if (rc) |
648 | goto out_free; | 673 | goto out_free; |
649 | opts->mnt_opts[i] = context; | 674 | opts->mnt_opts[i] = context; |
@@ -706,7 +731,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
706 | 731 | ||
707 | mutex_lock(&sbsec->lock); | 732 | mutex_lock(&sbsec->lock); |
708 | 733 | ||
709 | if (!ss_initialized) { | 734 | if (!selinux_state.initialized) { |
710 | if (!num_opts) { | 735 | if (!num_opts) { |
711 | /* Defer initialization until selinux_complete_init, | 736 | /* Defer initialization until selinux_complete_init, |
712 | after the initial policy is loaded and the security | 737 | after the initial policy is loaded and the security |
@@ -752,7 +777,9 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
752 | 777 | ||
753 | if (flags[i] == SBLABEL_MNT) | 778 | if (flags[i] == SBLABEL_MNT) |
754 | continue; | 779 | continue; |
755 | rc = security_context_str_to_sid(mount_options[i], &sid, GFP_KERNEL); | 780 | rc = security_context_str_to_sid(&selinux_state, |
781 | mount_options[i], &sid, | ||
782 | GFP_KERNEL); | ||
756 | if (rc) { | 783 | if (rc) { |
757 | printk(KERN_WARNING "SELinux: security_context_str_to_sid" | 784 | printk(KERN_WARNING "SELinux: security_context_str_to_sid" |
758 | "(%s) failed for (dev %s, type %s) errno=%d\n", | 785 | "(%s) failed for (dev %s, type %s) errno=%d\n", |
@@ -828,7 +855,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
828 | * Determine the labeling behavior to use for this | 855 | * Determine the labeling behavior to use for this |
829 | * filesystem type. | 856 | * filesystem type. |
830 | */ | 857 | */ |
831 | rc = security_fs_use(sb); | 858 | rc = security_fs_use(&selinux_state, sb); |
832 | if (rc) { | 859 | if (rc) { |
833 | printk(KERN_WARNING | 860 | printk(KERN_WARNING |
834 | "%s: security_fs_use(%s) returned %d\n", | 861 | "%s: security_fs_use(%s) returned %d\n", |
@@ -853,7 +880,9 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
853 | } | 880 | } |
854 | if (sbsec->behavior == SECURITY_FS_USE_XATTR) { | 881 | if (sbsec->behavior == SECURITY_FS_USE_XATTR) { |
855 | sbsec->behavior = SECURITY_FS_USE_MNTPOINT; | 882 | sbsec->behavior = SECURITY_FS_USE_MNTPOINT; |
856 | rc = security_transition_sid(current_sid(), current_sid(), | 883 | rc = security_transition_sid(&selinux_state, |
884 | current_sid(), | ||
885 | current_sid(), | ||
857 | SECCLASS_FILE, NULL, | 886 | SECCLASS_FILE, NULL, |
858 | &sbsec->mntpoint_sid); | 887 | &sbsec->mntpoint_sid); |
859 | if (rc) | 888 | if (rc) |
@@ -989,7 +1018,7 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb, | |||
989 | * if the parent was able to be mounted it clearly had no special lsm | 1018 | * if the parent was able to be mounted it clearly had no special lsm |
990 | * mount options. thus we can safely deal with this superblock later | 1019 | * mount options. thus we can safely deal with this superblock later |
991 | */ | 1020 | */ |
992 | if (!ss_initialized) | 1021 | if (!selinux_state.initialized) |
993 | return 0; | 1022 | return 0; |
994 | 1023 | ||
995 | /* | 1024 | /* |
@@ -1016,7 +1045,7 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb, | |||
1016 | 1045 | ||
1017 | if (newsbsec->behavior == SECURITY_FS_USE_NATIVE && | 1046 | if (newsbsec->behavior == SECURITY_FS_USE_NATIVE && |
1018 | !(kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context) { | 1047 | !(kern_flags & SECURITY_LSM_NATIVE_LABELS) && !set_context) { |
1019 | rc = security_fs_use(newsb); | 1048 | rc = security_fs_use(&selinux_state, newsb); |
1020 | if (rc) | 1049 | if (rc) |
1021 | goto out; | 1050 | goto out; |
1022 | } | 1051 | } |
@@ -1299,7 +1328,7 @@ static inline int default_protocol_dgram(int protocol) | |||
1299 | 1328 | ||
1300 | static inline u16 socket_type_to_security_class(int family, int type, int protocol) | 1329 | static inline u16 socket_type_to_security_class(int family, int type, int protocol) |
1301 | { | 1330 | { |
1302 | int extsockclass = selinux_policycap_extsockclass; | 1331 | int extsockclass = selinux_policycap_extsockclass(); |
1303 | 1332 | ||
1304 | switch (family) { | 1333 | switch (family) { |
1305 | case PF_UNIX: | 1334 | case PF_UNIX: |
@@ -1473,7 +1502,8 @@ static int selinux_genfs_get_sid(struct dentry *dentry, | |||
1473 | path++; | 1502 | path++; |
1474 | } | 1503 | } |
1475 | } | 1504 | } |
1476 | rc = security_genfs_sid(sb->s_type->name, path, tclass, sid); | 1505 | rc = security_genfs_sid(&selinux_state, sb->s_type->name, |
1506 | path, tclass, sid); | ||
1477 | } | 1507 | } |
1478 | free_page((unsigned long)buffer); | 1508 | free_page((unsigned long)buffer); |
1479 | return rc; | 1509 | return rc; |
@@ -1591,7 +1621,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1591 | sid = sbsec->def_sid; | 1621 | sid = sbsec->def_sid; |
1592 | rc = 0; | 1622 | rc = 0; |
1593 | } else { | 1623 | } else { |
1594 | rc = security_context_to_sid_default(context, rc, &sid, | 1624 | rc = security_context_to_sid_default(&selinux_state, |
1625 | context, rc, &sid, | ||
1595 | sbsec->def_sid, | 1626 | sbsec->def_sid, |
1596 | GFP_NOFS); | 1627 | GFP_NOFS); |
1597 | if (rc) { | 1628 | if (rc) { |
@@ -1624,7 +1655,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1624 | sid = sbsec->sid; | 1655 | sid = sbsec->sid; |
1625 | 1656 | ||
1626 | /* Try to obtain a transition SID. */ | 1657 | /* Try to obtain a transition SID. */ |
1627 | rc = security_transition_sid(task_sid, sid, sclass, NULL, &sid); | 1658 | rc = security_transition_sid(&selinux_state, task_sid, sid, |
1659 | sclass, NULL, &sid); | ||
1628 | if (rc) | 1660 | if (rc) |
1629 | goto out; | 1661 | goto out; |
1630 | break; | 1662 | break; |
@@ -1885,7 +1917,8 @@ selinux_determine_inode_label(const struct task_security_struct *tsec, | |||
1885 | *_new_isid = tsec->create_sid; | 1917 | *_new_isid = tsec->create_sid; |
1886 | } else { | 1918 | } else { |
1887 | const struct inode_security_struct *dsec = inode_security(dir); | 1919 | const struct inode_security_struct *dsec = inode_security(dir); |
1888 | return security_transition_sid(tsec->sid, dsec->sid, tclass, | 1920 | return security_transition_sid(&selinux_state, tsec->sid, |
1921 | dsec->sid, tclass, | ||
1889 | name, _new_isid); | 1922 | name, _new_isid); |
1890 | } | 1923 | } |
1891 | 1924 | ||
@@ -2108,7 +2141,8 @@ static inline u32 open_file_to_av(struct file *file) | |||
2108 | u32 av = file_to_av(file); | 2141 | u32 av = file_to_av(file); |
2109 | struct inode *inode = file_inode(file); | 2142 | struct inode *inode = file_inode(file); |
2110 | 2143 | ||
2111 | if (selinux_policycap_openperm && inode->i_sb->s_magic != SOCKFS_MAGIC) | 2144 | if (selinux_policycap_openperm() && |
2145 | inode->i_sb->s_magic != SOCKFS_MAGIC) | ||
2112 | av |= FILE__OPEN; | 2146 | av |= FILE__OPEN; |
2113 | 2147 | ||
2114 | return av; | 2148 | return av; |
@@ -2353,7 +2387,7 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, | |||
2353 | * policy allows the corresponding permission between | 2387 | * policy allows the corresponding permission between |
2354 | * the old and new contexts. | 2388 | * the old and new contexts. |
2355 | */ | 2389 | */ |
2356 | if (selinux_policycap_nnp_nosuid_transition) { | 2390 | if (selinux_policycap_nnp_nosuid_transition()) { |
2357 | av = 0; | 2391 | av = 0; |
2358 | if (nnp) | 2392 | if (nnp) |
2359 | av |= PROCESS2__NNP_TRANSITION; | 2393 | av |= PROCESS2__NNP_TRANSITION; |
@@ -2370,7 +2404,8 @@ static int check_nnp_nosuid(const struct linux_binprm *bprm, | |||
2370 | * i.e. SIDs that are guaranteed to only be allowed a subset | 2404 | * i.e. SIDs that are guaranteed to only be allowed a subset |
2371 | * of the permissions of the current SID. | 2405 | * of the permissions of the current SID. |
2372 | */ | 2406 | */ |
2373 | rc = security_bounded_transition(old_tsec->sid, new_tsec->sid); | 2407 | rc = security_bounded_transition(&selinux_state, old_tsec->sid, |
2408 | new_tsec->sid); | ||
2374 | if (!rc) | 2409 | if (!rc) |
2375 | return 0; | 2410 | return 0; |
2376 | 2411 | ||
@@ -2422,8 +2457,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
2422 | return rc; | 2457 | return rc; |
2423 | } else { | 2458 | } else { |
2424 | /* Check for a default transition on this program. */ | 2459 | /* Check for a default transition on this program. */ |
2425 | rc = security_transition_sid(old_tsec->sid, isec->sid, | 2460 | rc = security_transition_sid(&selinux_state, old_tsec->sid, |
2426 | SECCLASS_PROCESS, NULL, | 2461 | isec->sid, SECCLASS_PROCESS, NULL, |
2427 | &new_tsec->sid); | 2462 | &new_tsec->sid); |
2428 | if (rc) | 2463 | if (rc) |
2429 | return rc; | 2464 | return rc; |
@@ -2781,7 +2816,9 @@ static int selinux_sb_remount(struct super_block *sb, void *data) | |||
2781 | 2816 | ||
2782 | if (flags[i] == SBLABEL_MNT) | 2817 | if (flags[i] == SBLABEL_MNT) |
2783 | continue; | 2818 | continue; |
2784 | rc = security_context_str_to_sid(mount_options[i], &sid, GFP_KERNEL); | 2819 | rc = security_context_str_to_sid(&selinux_state, |
2820 | mount_options[i], &sid, | ||
2821 | GFP_KERNEL); | ||
2785 | if (rc) { | 2822 | if (rc) { |
2786 | printk(KERN_WARNING "SELinux: security_context_str_to_sid" | 2823 | printk(KERN_WARNING "SELinux: security_context_str_to_sid" |
2787 | "(%s) failed for (dev %s, type %s) errno=%d\n", | 2824 | "(%s) failed for (dev %s, type %s) errno=%d\n", |
@@ -2906,7 +2943,8 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode, | |||
2906 | if (rc) | 2943 | if (rc) |
2907 | return rc; | 2944 | return rc; |
2908 | 2945 | ||
2909 | return security_sid_to_context(newsid, (char **)ctx, ctxlen); | 2946 | return security_sid_to_context(&selinux_state, newsid, (char **)ctx, |
2947 | ctxlen); | ||
2910 | } | 2948 | } |
2911 | 2949 | ||
2912 | static int selinux_dentry_create_files_as(struct dentry *dentry, int mode, | 2950 | static int selinux_dentry_create_files_as(struct dentry *dentry, int mode, |
@@ -2960,14 +2998,15 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
2960 | isec->initialized = LABEL_INITIALIZED; | 2998 | isec->initialized = LABEL_INITIALIZED; |
2961 | } | 2999 | } |
2962 | 3000 | ||
2963 | if (!ss_initialized || !(sbsec->flags & SBLABEL_MNT)) | 3001 | if (!selinux_state.initialized || !(sbsec->flags & SBLABEL_MNT)) |
2964 | return -EOPNOTSUPP; | 3002 | return -EOPNOTSUPP; |
2965 | 3003 | ||
2966 | if (name) | 3004 | if (name) |
2967 | *name = XATTR_SELINUX_SUFFIX; | 3005 | *name = XATTR_SELINUX_SUFFIX; |
2968 | 3006 | ||
2969 | if (value && len) { | 3007 | if (value && len) { |
2970 | rc = security_sid_to_context_force(newsid, &context, &clen); | 3008 | rc = security_sid_to_context_force(&selinux_state, newsid, |
3009 | &context, &clen); | ||
2971 | if (rc) | 3010 | if (rc) |
2972 | return rc; | 3011 | return rc; |
2973 | *value = context; | 3012 | *value = context; |
@@ -3128,7 +3167,7 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | |||
3128 | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) | 3167 | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) |
3129 | return dentry_has_perm(cred, dentry, FILE__SETATTR); | 3168 | return dentry_has_perm(cred, dentry, FILE__SETATTR); |
3130 | 3169 | ||
3131 | if (selinux_policycap_openperm && | 3170 | if (selinux_policycap_openperm() && |
3132 | inode->i_sb->s_magic != SOCKFS_MAGIC && | 3171 | inode->i_sb->s_magic != SOCKFS_MAGIC && |
3133 | (ia_valid & ATTR_SIZE) && | 3172 | (ia_valid & ATTR_SIZE) && |
3134 | !(ia_valid & ATTR_FILE)) | 3173 | !(ia_valid & ATTR_FILE)) |
@@ -3190,7 +3229,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
3190 | if (rc) | 3229 | if (rc) |
3191 | return rc; | 3230 | return rc; |
3192 | 3231 | ||
3193 | rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL); | 3232 | rc = security_context_to_sid(&selinux_state, value, size, &newsid, |
3233 | GFP_KERNEL); | ||
3194 | if (rc == -EINVAL) { | 3234 | if (rc == -EINVAL) { |
3195 | if (!has_cap_mac_admin(true)) { | 3235 | if (!has_cap_mac_admin(true)) { |
3196 | struct audit_buffer *ab; | 3236 | struct audit_buffer *ab; |
@@ -3215,7 +3255,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
3215 | 3255 | ||
3216 | return rc; | 3256 | return rc; |
3217 | } | 3257 | } |
3218 | rc = security_context_to_sid_force(value, size, &newsid); | 3258 | rc = security_context_to_sid_force(&selinux_state, value, |
3259 | size, &newsid); | ||
3219 | } | 3260 | } |
3220 | if (rc) | 3261 | if (rc) |
3221 | return rc; | 3262 | return rc; |
@@ -3225,8 +3266,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
3225 | if (rc) | 3266 | if (rc) |
3226 | return rc; | 3267 | return rc; |
3227 | 3268 | ||
3228 | rc = security_validate_transition(isec->sid, newsid, sid, | 3269 | rc = security_validate_transition(&selinux_state, isec->sid, newsid, |
3229 | isec->sclass); | 3270 | sid, isec->sclass); |
3230 | if (rc) | 3271 | if (rc) |
3231 | return rc; | 3272 | return rc; |
3232 | 3273 | ||
@@ -3251,7 +3292,8 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, | |||
3251 | return; | 3292 | return; |
3252 | } | 3293 | } |
3253 | 3294 | ||
3254 | rc = security_context_to_sid_force(value, size, &newsid); | 3295 | rc = security_context_to_sid_force(&selinux_state, value, size, |
3296 | &newsid); | ||
3255 | if (rc) { | 3297 | if (rc) { |
3256 | printk(KERN_ERR "SELinux: unable to map context to SID" | 3298 | printk(KERN_ERR "SELinux: unable to map context to SID" |
3257 | "for (%s, %lu), rc=%d\n", | 3299 | "for (%s, %lu), rc=%d\n", |
@@ -3326,10 +3368,12 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void | |||
3326 | */ | 3368 | */ |
3327 | isec = inode_security(inode); | 3369 | isec = inode_security(inode); |
3328 | if (has_cap_mac_admin(false)) | 3370 | if (has_cap_mac_admin(false)) |
3329 | error = security_sid_to_context_force(isec->sid, &context, | 3371 | error = security_sid_to_context_force(&selinux_state, |
3372 | isec->sid, &context, | ||
3330 | &size); | 3373 | &size); |
3331 | else | 3374 | else |
3332 | error = security_sid_to_context(isec->sid, &context, &size); | 3375 | error = security_sid_to_context(&selinux_state, isec->sid, |
3376 | &context, &size); | ||
3333 | if (error) | 3377 | if (error) |
3334 | return error; | 3378 | return error; |
3335 | error = size; | 3379 | error = size; |
@@ -3355,7 +3399,8 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name, | |||
3355 | if (!value || !size) | 3399 | if (!value || !size) |
3356 | return -EACCES; | 3400 | return -EACCES; |
3357 | 3401 | ||
3358 | rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL); | 3402 | rc = security_context_to_sid(&selinux_state, value, size, &newsid, |
3403 | GFP_KERNEL); | ||
3359 | if (rc) | 3404 | if (rc) |
3360 | return rc; | 3405 | return rc; |
3361 | 3406 | ||
@@ -3617,7 +3662,7 @@ static int selinux_mmap_file(struct file *file, unsigned long reqprot, | |||
3617 | return rc; | 3662 | return rc; |
3618 | } | 3663 | } |
3619 | 3664 | ||
3620 | if (selinux_checkreqprot) | 3665 | if (selinux_state.checkreqprot) |
3621 | prot = reqprot; | 3666 | prot = reqprot; |
3622 | 3667 | ||
3623 | return file_map_prot_check(file, prot, | 3668 | return file_map_prot_check(file, prot, |
@@ -3631,7 +3676,7 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, | |||
3631 | const struct cred *cred = current_cred(); | 3676 | const struct cred *cred = current_cred(); |
3632 | u32 sid = cred_sid(cred); | 3677 | u32 sid = cred_sid(cred); |
3633 | 3678 | ||
3634 | if (selinux_checkreqprot) | 3679 | if (selinux_state.checkreqprot) |
3635 | prot = reqprot; | 3680 | prot = reqprot; |
3636 | 3681 | ||
3637 | if (default_noexec && | 3682 | if (default_noexec && |
@@ -4319,7 +4364,8 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid) | |||
4319 | if (unlikely(err)) | 4364 | if (unlikely(err)) |
4320 | return -EACCES; | 4365 | return -EACCES; |
4321 | 4366 | ||
4322 | err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid); | 4367 | err = security_net_peersid_resolve(&selinux_state, nlbl_sid, |
4368 | nlbl_type, xfrm_sid, sid); | ||
4323 | if (unlikely(err)) { | 4369 | if (unlikely(err)) { |
4324 | printk(KERN_WARNING | 4370 | printk(KERN_WARNING |
4325 | "SELinux: failure in selinux_skb_peerlbl_sid()," | 4371 | "SELinux: failure in selinux_skb_peerlbl_sid()," |
@@ -4347,7 +4393,8 @@ static int selinux_conn_sid(u32 sk_sid, u32 skb_sid, u32 *conn_sid) | |||
4347 | int err = 0; | 4393 | int err = 0; |
4348 | 4394 | ||
4349 | if (skb_sid != SECSID_NULL) | 4395 | if (skb_sid != SECSID_NULL) |
4350 | err = security_sid_mls_copy(sk_sid, skb_sid, conn_sid); | 4396 | err = security_sid_mls_copy(&selinux_state, sk_sid, skb_sid, |
4397 | conn_sid); | ||
4351 | else | 4398 | else |
4352 | *conn_sid = sk_sid; | 4399 | *conn_sid = sk_sid; |
4353 | 4400 | ||
@@ -4364,8 +4411,8 @@ static int socket_sockcreate_sid(const struct task_security_struct *tsec, | |||
4364 | return 0; | 4411 | return 0; |
4365 | } | 4412 | } |
4366 | 4413 | ||
4367 | return security_transition_sid(tsec->sid, tsec->sid, secclass, NULL, | 4414 | return security_transition_sid(&selinux_state, tsec->sid, tsec->sid, |
4368 | socksid); | 4415 | secclass, NULL, socksid); |
4369 | } | 4416 | } |
4370 | 4417 | ||
4371 | static int sock_has_perm(struct sock *sk, u32 perms) | 4418 | static int sock_has_perm(struct sock *sk, u32 perms) |
@@ -4741,8 +4788,8 @@ static int selinux_socket_unix_stream_connect(struct sock *sock, | |||
4741 | 4788 | ||
4742 | /* server child socket */ | 4789 | /* server child socket */ |
4743 | sksec_new->peer_sid = sksec_sock->sid; | 4790 | sksec_new->peer_sid = sksec_sock->sid; |
4744 | err = security_sid_mls_copy(sksec_other->sid, sksec_sock->sid, | 4791 | err = security_sid_mls_copy(&selinux_state, sksec_other->sid, |
4745 | &sksec_new->sid); | 4792 | sksec_sock->sid, &sksec_new->sid); |
4746 | if (err) | 4793 | if (err) |
4747 | return err; | 4794 | return err; |
4748 | 4795 | ||
@@ -4847,7 +4894,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
4847 | * to the selinux_sock_rcv_skb_compat() function to deal with the | 4894 | * to the selinux_sock_rcv_skb_compat() function to deal with the |
4848 | * special handling. We do this in an attempt to keep this function | 4895 | * special handling. We do this in an attempt to keep this function |
4849 | * as fast and as clean as possible. */ | 4896 | * as fast and as clean as possible. */ |
4850 | if (!selinux_policycap_netpeer) | 4897 | if (!selinux_policycap_netpeer()) |
4851 | return selinux_sock_rcv_skb_compat(sk, skb, family); | 4898 | return selinux_sock_rcv_skb_compat(sk, skb, family); |
4852 | 4899 | ||
4853 | secmark_active = selinux_secmark_enabled(); | 4900 | secmark_active = selinux_secmark_enabled(); |
@@ -4909,7 +4956,8 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op | |||
4909 | if (peer_sid == SECSID_NULL) | 4956 | if (peer_sid == SECSID_NULL) |
4910 | return -ENOPROTOOPT; | 4957 | return -ENOPROTOOPT; |
4911 | 4958 | ||
4912 | err = security_sid_to_context(peer_sid, &scontext, &scontext_len); | 4959 | err = security_sid_to_context(&selinux_state, peer_sid, &scontext, |
4960 | &scontext_len); | ||
4913 | if (err) | 4961 | if (err) |
4914 | return err; | 4962 | return err; |
4915 | 4963 | ||
@@ -5032,7 +5080,7 @@ static int selinux_sctp_assoc_request(struct sctp_endpoint *ep, | |||
5032 | u32 conn_sid; | 5080 | u32 conn_sid; |
5033 | int err = 0; | 5081 | int err = 0; |
5034 | 5082 | ||
5035 | if (!selinux_policycap_extsockclass) | 5083 | if (!selinux_policycap_extsockclass()) |
5036 | return 0; | 5084 | return 0; |
5037 | 5085 | ||
5038 | peerlbl_active = selinux_peerlbl_enabled(); | 5086 | peerlbl_active = selinux_peerlbl_enabled(); |
@@ -5101,7 +5149,7 @@ static int selinux_sctp_bind_connect(struct sock *sk, int optname, | |||
5101 | struct sockaddr *addr; | 5149 | struct sockaddr *addr; |
5102 | struct socket *sock; | 5150 | struct socket *sock; |
5103 | 5151 | ||
5104 | if (!selinux_policycap_extsockclass) | 5152 | if (!selinux_policycap_extsockclass()) |
5105 | return 0; | 5153 | return 0; |
5106 | 5154 | ||
5107 | /* Process one or more addresses that may be IPv4 or IPv6 */ | 5155 | /* Process one or more addresses that may be IPv4 or IPv6 */ |
@@ -5173,7 +5221,7 @@ static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk, | |||
5173 | /* If policy does not support SECCLASS_SCTP_SOCKET then call | 5221 | /* If policy does not support SECCLASS_SCTP_SOCKET then call |
5174 | * the non-sctp clone version. | 5222 | * the non-sctp clone version. |
5175 | */ | 5223 | */ |
5176 | if (!selinux_policycap_extsockclass) | 5224 | if (!selinux_policycap_extsockclass()) |
5177 | return selinux_sk_clone_security(sk, newsk); | 5225 | return selinux_sk_clone_security(sk, newsk); |
5178 | 5226 | ||
5179 | newsksec->sid = ep->secid; | 5227 | newsksec->sid = ep->secid; |
@@ -5359,7 +5407,8 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) | |||
5359 | sk->sk_protocol, nlh->nlmsg_type, | 5407 | sk->sk_protocol, nlh->nlmsg_type, |
5360 | secclass_map[sksec->sclass - 1].name, | 5408 | secclass_map[sksec->sclass - 1].name, |
5361 | task_pid_nr(current), current->comm); | 5409 | task_pid_nr(current), current->comm); |
5362 | if (!selinux_enforcing || security_get_allow_unknown()) | 5410 | if (!is_enforcing(&selinux_state) || |
5411 | security_get_allow_unknown(&selinux_state)) | ||
5363 | err = 0; | 5412 | err = 0; |
5364 | } | 5413 | } |
5365 | 5414 | ||
@@ -5389,7 +5438,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, | |||
5389 | u8 netlbl_active; | 5438 | u8 netlbl_active; |
5390 | u8 peerlbl_active; | 5439 | u8 peerlbl_active; |
5391 | 5440 | ||
5392 | if (!selinux_policycap_netpeer) | 5441 | if (!selinux_policycap_netpeer()) |
5393 | return NF_ACCEPT; | 5442 | return NF_ACCEPT; |
5394 | 5443 | ||
5395 | secmark_active = selinux_secmark_enabled(); | 5444 | secmark_active = selinux_secmark_enabled(); |
@@ -5558,7 +5607,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, | |||
5558 | * to the selinux_ip_postroute_compat() function to deal with the | 5607 | * to the selinux_ip_postroute_compat() function to deal with the |
5559 | * special handling. We do this in an attempt to keep this function | 5608 | * special handling. We do this in an attempt to keep this function |
5560 | * as fast and as clean as possible. */ | 5609 | * as fast and as clean as possible. */ |
5561 | if (!selinux_policycap_netpeer) | 5610 | if (!selinux_policycap_netpeer()) |
5562 | return selinux_ip_postroute_compat(skb, ifindex, family); | 5611 | return selinux_ip_postroute_compat(skb, ifindex, family); |
5563 | 5612 | ||
5564 | secmark_active = selinux_secmark_enabled(); | 5613 | secmark_active = selinux_secmark_enabled(); |
@@ -5864,8 +5913,8 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
5864 | * Compute new sid based on current process and | 5913 | * Compute new sid based on current process and |
5865 | * message queue this message will be stored in | 5914 | * message queue this message will be stored in |
5866 | */ | 5915 | */ |
5867 | rc = security_transition_sid(sid, isec->sid, SECCLASS_MSG, | 5916 | rc = security_transition_sid(&selinux_state, sid, isec->sid, |
5868 | NULL, &msec->sid); | 5917 | SECCLASS_MSG, NULL, &msec->sid); |
5869 | if (rc) | 5918 | if (rc) |
5870 | return rc; | 5919 | return rc; |
5871 | } | 5920 | } |
@@ -6174,7 +6223,7 @@ static int selinux_getprocattr(struct task_struct *p, | |||
6174 | if (!sid) | 6223 | if (!sid) |
6175 | return 0; | 6224 | return 0; |
6176 | 6225 | ||
6177 | error = security_sid_to_context(sid, value, &len); | 6226 | error = security_sid_to_context(&selinux_state, sid, value, &len); |
6178 | if (error) | 6227 | if (error) |
6179 | return error; | 6228 | return error; |
6180 | return len; | 6229 | return len; |
@@ -6221,7 +6270,8 @@ static int selinux_setprocattr(const char *name, void *value, size_t size) | |||
6221 | str[size-1] = 0; | 6270 | str[size-1] = 0; |
6222 | size--; | 6271 | size--; |
6223 | } | 6272 | } |
6224 | error = security_context_to_sid(value, size, &sid, GFP_KERNEL); | 6273 | error = security_context_to_sid(&selinux_state, value, size, |
6274 | &sid, GFP_KERNEL); | ||
6225 | if (error == -EINVAL && !strcmp(name, "fscreate")) { | 6275 | if (error == -EINVAL && !strcmp(name, "fscreate")) { |
6226 | if (!has_cap_mac_admin(true)) { | 6276 | if (!has_cap_mac_admin(true)) { |
6227 | struct audit_buffer *ab; | 6277 | struct audit_buffer *ab; |
@@ -6240,8 +6290,9 @@ static int selinux_setprocattr(const char *name, void *value, size_t size) | |||
6240 | 6290 | ||
6241 | return error; | 6291 | return error; |
6242 | } | 6292 | } |
6243 | error = security_context_to_sid_force(value, size, | 6293 | error = security_context_to_sid_force( |
6244 | &sid); | 6294 | &selinux_state, |
6295 | value, size, &sid); | ||
6245 | } | 6296 | } |
6246 | if (error) | 6297 | if (error) |
6247 | return error; | 6298 | return error; |
@@ -6278,7 +6329,8 @@ static int selinux_setprocattr(const char *name, void *value, size_t size) | |||
6278 | /* Only allow single threaded processes to change context */ | 6329 | /* Only allow single threaded processes to change context */ |
6279 | error = -EPERM; | 6330 | error = -EPERM; |
6280 | if (!current_is_single_threaded()) { | 6331 | if (!current_is_single_threaded()) { |
6281 | error = security_bounded_transition(tsec->sid, sid); | 6332 | error = security_bounded_transition(&selinux_state, |
6333 | tsec->sid, sid); | ||
6282 | if (error) | 6334 | if (error) |
6283 | goto abort_change; | 6335 | goto abort_change; |
6284 | } | 6336 | } |
@@ -6320,12 +6372,14 @@ static int selinux_ismaclabel(const char *name) | |||
6320 | 6372 | ||
6321 | static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | 6373 | static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) |
6322 | { | 6374 | { |
6323 | return security_sid_to_context(secid, secdata, seclen); | 6375 | return security_sid_to_context(&selinux_state, secid, |
6376 | secdata, seclen); | ||
6324 | } | 6377 | } |
6325 | 6378 | ||
6326 | static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) | 6379 | static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) |
6327 | { | 6380 | { |
6328 | return security_context_to_sid(secdata, seclen, secid, GFP_KERNEL); | 6381 | return security_context_to_sid(&selinux_state, secdata, seclen, |
6382 | secid, GFP_KERNEL); | ||
6329 | } | 6383 | } |
6330 | 6384 | ||
6331 | static void selinux_release_secctx(char *secdata, u32 seclen) | 6385 | static void selinux_release_secctx(char *secdata, u32 seclen) |
@@ -6427,7 +6481,8 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer) | |||
6427 | unsigned len; | 6481 | unsigned len; |
6428 | int rc; | 6482 | int rc; |
6429 | 6483 | ||
6430 | rc = security_sid_to_context(ksec->sid, &context, &len); | 6484 | rc = security_sid_to_context(&selinux_state, ksec->sid, |
6485 | &context, &len); | ||
6431 | if (!rc) | 6486 | if (!rc) |
6432 | rc = len; | 6487 | rc = len; |
6433 | *_buffer = context; | 6488 | *_buffer = context; |
@@ -6466,7 +6521,8 @@ static int selinux_ib_endport_manage_subnet(void *ib_sec, const char *dev_name, | |||
6466 | struct ib_security_struct *sec = ib_sec; | 6521 | struct ib_security_struct *sec = ib_sec; |
6467 | struct lsm_ibendport_audit ibendport; | 6522 | struct lsm_ibendport_audit ibendport; |
6468 | 6523 | ||
6469 | err = security_ib_endport_sid(dev_name, port_num, &sid); | 6524 | err = security_ib_endport_sid(&selinux_state, dev_name, port_num, |
6525 | &sid); | ||
6470 | 6526 | ||
6471 | if (err) | 6527 | if (err) |
6472 | return err; | 6528 | return err; |
@@ -6880,6 +6936,11 @@ static __init int selinux_init(void) | |||
6880 | 6936 | ||
6881 | printk(KERN_INFO "SELinux: Initializing.\n"); | 6937 | printk(KERN_INFO "SELinux: Initializing.\n"); |
6882 | 6938 | ||
6939 | memset(&selinux_state, 0, sizeof(selinux_state)); | ||
6940 | set_enforcing(&selinux_state, selinux_enforcing_boot); | ||
6941 | selinux_state.checkreqprot = selinux_checkreqprot_boot; | ||
6942 | selinux_ss_init(&selinux_state.ss); | ||
6943 | |||
6883 | /* Set the security state for the initial task. */ | 6944 | /* Set the security state for the initial task. */ |
6884 | cred_init_security(); | 6945 | cred_init_security(); |
6885 | 6946 | ||
@@ -6893,6 +6954,12 @@ static __init int selinux_init(void) | |||
6893 | 0, SLAB_PANIC, NULL); | 6954 | 0, SLAB_PANIC, NULL); |
6894 | avc_init(); | 6955 | avc_init(); |
6895 | 6956 | ||
6957 | avtab_cache_init(); | ||
6958 | |||
6959 | ebitmap_cache_init(); | ||
6960 | |||
6961 | hashtab_cache_init(); | ||
6962 | |||
6896 | security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux"); | 6963 | security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux"); |
6897 | 6964 | ||
6898 | if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) | 6965 | if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) |
@@ -6901,7 +6968,7 @@ static __init int selinux_init(void) | |||
6901 | if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET)) | 6968 | if (avc_add_callback(selinux_lsm_notifier_avc_callback, AVC_CALLBACK_RESET)) |
6902 | panic("SELinux: Unable to register AVC LSM notifier callback\n"); | 6969 | panic("SELinux: Unable to register AVC LSM notifier callback\n"); |
6903 | 6970 | ||
6904 | if (selinux_enforcing) | 6971 | if (selinux_enforcing_boot) |
6905 | printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n"); | 6972 | printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n"); |
6906 | else | 6973 | else |
6907 | printk(KERN_DEBUG "SELinux: Starting in permissive mode\n"); | 6974 | printk(KERN_DEBUG "SELinux: Starting in permissive mode\n"); |
@@ -7022,23 +7089,22 @@ static void selinux_nf_ip_exit(void) | |||
7022 | #endif /* CONFIG_NETFILTER */ | 7089 | #endif /* CONFIG_NETFILTER */ |
7023 | 7090 | ||
7024 | #ifdef CONFIG_SECURITY_SELINUX_DISABLE | 7091 | #ifdef CONFIG_SECURITY_SELINUX_DISABLE |
7025 | static int selinux_disabled; | 7092 | int selinux_disable(struct selinux_state *state) |
7026 | |||
7027 | int selinux_disable(void) | ||
7028 | { | 7093 | { |
7029 | if (ss_initialized) { | 7094 | if (state->initialized) { |
7030 | /* Not permitted after initial policy load. */ | 7095 | /* Not permitted after initial policy load. */ |
7031 | return -EINVAL; | 7096 | return -EINVAL; |
7032 | } | 7097 | } |
7033 | 7098 | ||
7034 | if (selinux_disabled) { | 7099 | if (state->disabled) { |
7035 | /* Only do this once. */ | 7100 | /* Only do this once. */ |
7036 | return -EINVAL; | 7101 | return -EINVAL; |
7037 | } | 7102 | } |
7038 | 7103 | ||
7104 | state->disabled = 1; | ||
7105 | |||
7039 | printk(KERN_INFO "SELinux: Disabled at runtime.\n"); | 7106 | printk(KERN_INFO "SELinux: Disabled at runtime.\n"); |
7040 | 7107 | ||
7041 | selinux_disabled = 1; | ||
7042 | selinux_enabled = 0; | 7108 | selinux_enabled = 0; |
7043 | 7109 | ||
7044 | security_delete_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks)); | 7110 | security_delete_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks)); |