diff options
25 files changed, 1155 insertions, 797 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 2380b8d72cec..36124f48a5ff 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
@@ -149,7 +149,8 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla | |||
149 | char *scontext; | 149 | char *scontext; |
150 | u32 scontext_len; | 150 | u32 scontext_len; |
151 | 151 | ||
152 | rc = security_sid_to_context(ssid, &scontext, &scontext_len); | 152 | rc = security_sid_to_context(&selinux_state, ssid, |
153 | &scontext, &scontext_len); | ||
153 | if (rc) | 154 | if (rc) |
154 | audit_log_format(ab, "ssid=%d", ssid); | 155 | audit_log_format(ab, "ssid=%d", ssid); |
155 | else { | 156 | else { |
@@ -157,7 +158,8 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla | |||
157 | kfree(scontext); | 158 | kfree(scontext); |
158 | } | 159 | } |
159 | 160 | ||
160 | rc = security_sid_to_context(tsid, &scontext, &scontext_len); | 161 | rc = security_sid_to_context(&selinux_state, tsid, |
162 | &scontext, &scontext_len); | ||
161 | if (rc) | 163 | if (rc) |
162 | audit_log_format(ab, " tsid=%d", tsid); | 164 | audit_log_format(ab, " tsid=%d", tsid); |
163 | else { | 165 | else { |
@@ -969,7 +971,8 @@ static noinline struct avc_node *avc_compute_av(u32 ssid, u32 tsid, | |||
969 | { | 971 | { |
970 | rcu_read_unlock(); | 972 | rcu_read_unlock(); |
971 | INIT_LIST_HEAD(&xp_node->xpd_head); | 973 | INIT_LIST_HEAD(&xp_node->xpd_head); |
972 | security_compute_av(ssid, tsid, tclass, avd, &xp_node->xp); | 974 | security_compute_av(&selinux_state, ssid, tsid, tclass, |
975 | avd, &xp_node->xp); | ||
973 | rcu_read_lock(); | 976 | rcu_read_lock(); |
974 | return avc_insert(ssid, tsid, tclass, avd, xp_node); | 977 | return avc_insert(ssid, tsid, tclass, avd, xp_node); |
975 | } | 978 | } |
@@ -982,7 +985,8 @@ static noinline int avc_denied(u32 ssid, u32 tsid, | |||
982 | if (flags & AVC_STRICT) | 985 | if (flags & AVC_STRICT) |
983 | return -EACCES; | 986 | return -EACCES; |
984 | 987 | ||
985 | if (selinux_enforcing && !(avd->flags & AVD_FLAGS_PERMISSIVE)) | 988 | if (is_enforcing(&selinux_state) && |
989 | !(avd->flags & AVD_FLAGS_PERMISSIVE)) | ||
986 | return -EACCES; | 990 | return -EACCES; |
987 | 991 | ||
988 | avc_update_node(AVC_CALLBACK_GRANT, requested, driver, xperm, ssid, | 992 | avc_update_node(AVC_CALLBACK_GRANT, requested, driver, xperm, ssid, |
@@ -1043,8 +1047,8 @@ int avc_has_extended_perms(u32 ssid, u32 tsid, u16 tclass, u32 requested, | |||
1043 | goto decision; | 1047 | goto decision; |
1044 | } | 1048 | } |
1045 | rcu_read_unlock(); | 1049 | rcu_read_unlock(); |
1046 | security_compute_xperms_decision(ssid, tsid, tclass, driver, | 1050 | security_compute_xperms_decision(&selinux_state, ssid, tsid, |
1047 | &local_xpd); | 1051 | tclass, driver, &local_xpd); |
1048 | rcu_read_lock(); | 1052 | rcu_read_lock(); |
1049 | avc_update_node(AVC_CALLBACK_ADD_XPERMS, requested, driver, xperm, | 1053 | avc_update_node(AVC_CALLBACK_ADD_XPERMS, requested, driver, xperm, |
1050 | ssid, tsid, tclass, avd.seqno, &local_xpd, 0); | 1054 | ssid, tsid, tclass, avd.seqno, &local_xpd, 0); |
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)); |
diff --git a/security/selinux/ibpkey.c b/security/selinux/ibpkey.c index e3614ee5f1c0..0a4b89d48297 100644 --- a/security/selinux/ibpkey.c +++ b/security/selinux/ibpkey.c | |||
@@ -152,7 +152,8 @@ static int sel_ib_pkey_sid_slow(u64 subnet_prefix, u16 pkey_num, u32 *sid) | |||
152 | return 0; | 152 | return 0; |
153 | } | 153 | } |
154 | 154 | ||
155 | ret = security_ib_pkey_sid(subnet_prefix, pkey_num, sid); | 155 | ret = security_ib_pkey_sid(&selinux_state, subnet_prefix, pkey_num, |
156 | sid); | ||
156 | if (ret) | 157 | if (ret) |
157 | goto out; | 158 | goto out; |
158 | 159 | ||
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 57d61cf36500..de33dc9034b8 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h | |||
@@ -20,12 +20,6 @@ | |||
20 | #include "av_permissions.h" | 20 | #include "av_permissions.h" |
21 | #include "security.h" | 21 | #include "security.h" |
22 | 22 | ||
23 | #ifdef CONFIG_SECURITY_SELINUX_DEVELOP | ||
24 | extern int selinux_enforcing; | ||
25 | #else | ||
26 | #define selinux_enforcing 1 | ||
27 | #endif | ||
28 | |||
29 | /* | 23 | /* |
30 | * An entry in the AVC. | 24 | * An entry in the AVC. |
31 | */ | 25 | */ |
diff --git a/security/selinux/include/avc_ss.h b/security/selinux/include/avc_ss.h index 3bcc72769b87..4e2a44d0ae66 100644 --- a/security/selinux/include/avc_ss.h +++ b/security/selinux/include/avc_ss.h | |||
@@ -19,11 +19,5 @@ struct security_class_mapping { | |||
19 | 19 | ||
20 | extern struct security_class_mapping secclass_map[]; | 20 | extern struct security_class_mapping secclass_map[]; |
21 | 21 | ||
22 | /* | ||
23 | * The security server must be initialized before | ||
24 | * any labeling or access decisions can be provided. | ||
25 | */ | ||
26 | extern int ss_initialized; | ||
27 | |||
28 | #endif /* _SELINUX_AVC_SS_H_ */ | 22 | #endif /* _SELINUX_AVC_SS_H_ */ |
29 | 23 | ||
diff --git a/security/selinux/include/conditional.h b/security/selinux/include/conditional.h index ff4fddca9050..0e30eca02c48 100644 --- a/security/selinux/include/conditional.h +++ b/security/selinux/include/conditional.h | |||
@@ -13,10 +13,15 @@ | |||
13 | #ifndef _SELINUX_CONDITIONAL_H_ | 13 | #ifndef _SELINUX_CONDITIONAL_H_ |
14 | #define _SELINUX_CONDITIONAL_H_ | 14 | #define _SELINUX_CONDITIONAL_H_ |
15 | 15 | ||
16 | int security_get_bools(int *len, char ***names, int **values); | 16 | #include "security.h" |
17 | 17 | ||
18 | int security_set_bools(int len, int *values); | 18 | int security_get_bools(struct selinux_state *state, |
19 | int *len, char ***names, int **values); | ||
19 | 20 | ||
20 | int security_get_bool_value(int index); | 21 | int security_set_bools(struct selinux_state *state, |
22 | int len, int *values); | ||
23 | |||
24 | int security_get_bool_value(struct selinux_state *state, | ||
25 | int index); | ||
21 | 26 | ||
22 | #endif | 27 | #endif |
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index dabf02888a95..cc5e26b0161b 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h | |||
@@ -158,6 +158,4 @@ struct bpf_security_struct { | |||
158 | u32 sid; /*SID of bpf obj creater*/ | 158 | u32 sid; /*SID of bpf obj creater*/ |
159 | }; | 159 | }; |
160 | 160 | ||
161 | extern unsigned int selinux_checkreqprot; | ||
162 | |||
163 | #endif /* _SELINUX_OBJSEC_H_ */ | 161 | #endif /* _SELINUX_OBJSEC_H_ */ |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 02f0412d42f2..c3a1ef10e710 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -13,6 +13,8 @@ | |||
13 | #include <linux/dcache.h> | 13 | #include <linux/dcache.h> |
14 | #include <linux/magic.h> | 14 | #include <linux/magic.h> |
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | #include <linux/refcount.h> | ||
17 | #include <linux/workqueue.h> | ||
16 | #include "flask.h" | 18 | #include "flask.h" |
17 | 19 | ||
18 | #define SECSID_NULL 0x00000000 /* unspecified SID */ | 20 | #define SECSID_NULL 0x00000000 /* unspecified SID */ |
@@ -81,13 +83,6 @@ enum { | |||
81 | 83 | ||
82 | extern char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX]; | 84 | extern char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX]; |
83 | 85 | ||
84 | extern int selinux_policycap_netpeer; | ||
85 | extern int selinux_policycap_openperm; | ||
86 | extern int selinux_policycap_extsockclass; | ||
87 | extern int selinux_policycap_alwaysnetwork; | ||
88 | extern int selinux_policycap_cgroupseclabel; | ||
89 | extern int selinux_policycap_nnp_nosuid_transition; | ||
90 | |||
91 | /* | 86 | /* |
92 | * type_datum properties | 87 | * type_datum properties |
93 | * available at the kernel policy version >= POLICYDB_VERSION_BOUNDARY | 88 | * available at the kernel policy version >= POLICYDB_VERSION_BOUNDARY |
@@ -98,13 +93,95 @@ extern int selinux_policycap_nnp_nosuid_transition; | |||
98 | /* limitation of boundary depth */ | 93 | /* limitation of boundary depth */ |
99 | #define POLICYDB_BOUNDS_MAXDEPTH 4 | 94 | #define POLICYDB_BOUNDS_MAXDEPTH 4 |
100 | 95 | ||
101 | int security_mls_enabled(void); | 96 | struct selinux_ss; |
97 | |||
98 | struct selinux_state { | ||
99 | bool disabled; | ||
100 | #ifdef CONFIG_SECURITY_SELINUX_DEVELOP | ||
101 | bool enforcing; | ||
102 | #endif | ||
103 | bool checkreqprot; | ||
104 | bool initialized; | ||
105 | bool policycap[__POLICYDB_CAPABILITY_MAX]; | ||
106 | struct selinux_ss *ss; | ||
107 | }; | ||
108 | |||
109 | void selinux_ss_init(struct selinux_ss **ss); | ||
110 | |||
111 | extern struct selinux_state selinux_state; | ||
112 | |||
113 | #ifdef CONFIG_SECURITY_SELINUX_DEVELOP | ||
114 | static inline bool is_enforcing(struct selinux_state *state) | ||
115 | { | ||
116 | return state->enforcing; | ||
117 | } | ||
118 | |||
119 | static inline void set_enforcing(struct selinux_state *state, bool value) | ||
120 | { | ||
121 | state->enforcing = value; | ||
122 | } | ||
123 | #else | ||
124 | static inline bool is_enforcing(struct selinux_state *state) | ||
125 | { | ||
126 | return true; | ||
127 | } | ||
128 | |||
129 | static inline void set_enforcing(struct selinux_state *state, bool value) | ||
130 | { | ||
131 | } | ||
132 | #endif | ||
133 | |||
134 | static inline bool selinux_policycap_netpeer(void) | ||
135 | { | ||
136 | struct selinux_state *state = &selinux_state; | ||
137 | |||
138 | return state->policycap[POLICYDB_CAPABILITY_NETPEER]; | ||
139 | } | ||
140 | |||
141 | static inline bool selinux_policycap_openperm(void) | ||
142 | { | ||
143 | struct selinux_state *state = &selinux_state; | ||
144 | |||
145 | return state->policycap[POLICYDB_CAPABILITY_OPENPERM]; | ||
146 | } | ||
102 | 147 | ||
103 | int security_load_policy(void *data, size_t len); | 148 | static inline bool selinux_policycap_extsockclass(void) |
104 | int security_read_policy(void **data, size_t *len); | 149 | { |
105 | size_t security_policydb_len(void); | 150 | struct selinux_state *state = &selinux_state; |
151 | |||
152 | return state->policycap[POLICYDB_CAPABILITY_EXTSOCKCLASS]; | ||
153 | } | ||
106 | 154 | ||
107 | int security_policycap_supported(unsigned int req_cap); | 155 | static inline bool selinux_policycap_alwaysnetwork(void) |
156 | { | ||
157 | struct selinux_state *state = &selinux_state; | ||
158 | |||
159 | return state->policycap[POLICYDB_CAPABILITY_ALWAYSNETWORK]; | ||
160 | } | ||
161 | |||
162 | static inline bool selinux_policycap_cgroupseclabel(void) | ||
163 | { | ||
164 | struct selinux_state *state = &selinux_state; | ||
165 | |||
166 | return state->policycap[POLICYDB_CAPABILITY_CGROUPSECLABEL]; | ||
167 | } | ||
168 | |||
169 | static inline bool selinux_policycap_nnp_nosuid_transition(void) | ||
170 | { | ||
171 | struct selinux_state *state = &selinux_state; | ||
172 | |||
173 | return state->policycap[POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION]; | ||
174 | } | ||
175 | |||
176 | int security_mls_enabled(struct selinux_state *state); | ||
177 | int security_load_policy(struct selinux_state *state, | ||
178 | void *data, size_t len); | ||
179 | int security_read_policy(struct selinux_state *state, | ||
180 | void **data, size_t *len); | ||
181 | size_t security_policydb_len(struct selinux_state *state); | ||
182 | |||
183 | int security_policycap_supported(struct selinux_state *state, | ||
184 | unsigned int req_cap); | ||
108 | 185 | ||
109 | #define SEL_VEC_MAX 32 | 186 | #define SEL_VEC_MAX 32 |
110 | struct av_decision { | 187 | struct av_decision { |
@@ -141,76 +218,100 @@ struct extended_perms { | |||
141 | /* definitions of av_decision.flags */ | 218 | /* definitions of av_decision.flags */ |
142 | #define AVD_FLAGS_PERMISSIVE 0x0001 | 219 | #define AVD_FLAGS_PERMISSIVE 0x0001 |
143 | 220 | ||
144 | void security_compute_av(u32 ssid, u32 tsid, | 221 | void security_compute_av(struct selinux_state *state, |
222 | u32 ssid, u32 tsid, | ||
145 | u16 tclass, struct av_decision *avd, | 223 | u16 tclass, struct av_decision *avd, |
146 | struct extended_perms *xperms); | 224 | struct extended_perms *xperms); |
147 | 225 | ||
148 | void security_compute_xperms_decision(u32 ssid, u32 tsid, u16 tclass, | 226 | void security_compute_xperms_decision(struct selinux_state *state, |
149 | u8 driver, struct extended_perms_decision *xpermd); | 227 | u32 ssid, u32 tsid, u16 tclass, |
228 | u8 driver, | ||
229 | struct extended_perms_decision *xpermd); | ||
150 | 230 | ||
151 | void security_compute_av_user(u32 ssid, u32 tsid, | 231 | void security_compute_av_user(struct selinux_state *state, |
152 | u16 tclass, struct av_decision *avd); | 232 | u32 ssid, u32 tsid, |
233 | u16 tclass, struct av_decision *avd); | ||
153 | 234 | ||
154 | int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, | 235 | int security_transition_sid(struct selinux_state *state, |
236 | u32 ssid, u32 tsid, u16 tclass, | ||
155 | const struct qstr *qstr, u32 *out_sid); | 237 | const struct qstr *qstr, u32 *out_sid); |
156 | 238 | ||
157 | int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, | 239 | int security_transition_sid_user(struct selinux_state *state, |
240 | u32 ssid, u32 tsid, u16 tclass, | ||
158 | const char *objname, u32 *out_sid); | 241 | const char *objname, u32 *out_sid); |
159 | 242 | ||
160 | int security_member_sid(u32 ssid, u32 tsid, | 243 | int security_member_sid(struct selinux_state *state, u32 ssid, u32 tsid, |
161 | u16 tclass, u32 *out_sid); | 244 | u16 tclass, u32 *out_sid); |
162 | 245 | ||
163 | int security_change_sid(u32 ssid, u32 tsid, | 246 | int security_change_sid(struct selinux_state *state, u32 ssid, u32 tsid, |
164 | u16 tclass, u32 *out_sid); | 247 | u16 tclass, u32 *out_sid); |
165 | 248 | ||
166 | int security_sid_to_context(u32 sid, char **scontext, | 249 | int security_sid_to_context(struct selinux_state *state, u32 sid, |
167 | u32 *scontext_len); | 250 | char **scontext, u32 *scontext_len); |
168 | 251 | ||
169 | int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len); | 252 | int security_sid_to_context_force(struct selinux_state *state, |
253 | u32 sid, char **scontext, u32 *scontext_len); | ||
170 | 254 | ||
171 | int security_context_to_sid(const char *scontext, u32 scontext_len, | 255 | int security_context_to_sid(struct selinux_state *state, |
256 | const char *scontext, u32 scontext_len, | ||
172 | u32 *out_sid, gfp_t gfp); | 257 | u32 *out_sid, gfp_t gfp); |
173 | 258 | ||
174 | int security_context_str_to_sid(const char *scontext, u32 *out_sid, gfp_t gfp); | 259 | int security_context_str_to_sid(struct selinux_state *state, |
260 | const char *scontext, u32 *out_sid, gfp_t gfp); | ||
175 | 261 | ||
176 | int security_context_to_sid_default(const char *scontext, u32 scontext_len, | 262 | int security_context_to_sid_default(struct selinux_state *state, |
263 | const char *scontext, u32 scontext_len, | ||
177 | u32 *out_sid, u32 def_sid, gfp_t gfp_flags); | 264 | u32 *out_sid, u32 def_sid, gfp_t gfp_flags); |
178 | 265 | ||
179 | int security_context_to_sid_force(const char *scontext, u32 scontext_len, | 266 | int security_context_to_sid_force(struct selinux_state *state, |
267 | const char *scontext, u32 scontext_len, | ||
180 | u32 *sid); | 268 | u32 *sid); |
181 | 269 | ||
182 | int security_get_user_sids(u32 callsid, char *username, | 270 | int security_get_user_sids(struct selinux_state *state, |
271 | u32 callsid, char *username, | ||
183 | u32 **sids, u32 *nel); | 272 | u32 **sids, u32 *nel); |
184 | 273 | ||
185 | int security_port_sid(u8 protocol, u16 port, u32 *out_sid); | 274 | int security_port_sid(struct selinux_state *state, |
275 | u8 protocol, u16 port, u32 *out_sid); | ||
186 | 276 | ||
187 | int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid); | 277 | int security_ib_pkey_sid(struct selinux_state *state, |
278 | u64 subnet_prefix, u16 pkey_num, u32 *out_sid); | ||
188 | 279 | ||
189 | int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid); | 280 | int security_ib_endport_sid(struct selinux_state *state, |
281 | const char *dev_name, u8 port_num, u32 *out_sid); | ||
190 | 282 | ||
191 | int security_netif_sid(char *name, u32 *if_sid); | 283 | int security_netif_sid(struct selinux_state *state, |
284 | char *name, u32 *if_sid); | ||
192 | 285 | ||
193 | int security_node_sid(u16 domain, void *addr, u32 addrlen, | 286 | int security_node_sid(struct selinux_state *state, |
194 | u32 *out_sid); | 287 | u16 domain, void *addr, u32 addrlen, |
288 | u32 *out_sid); | ||
195 | 289 | ||
196 | int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, | 290 | int security_validate_transition(struct selinux_state *state, |
291 | u32 oldsid, u32 newsid, u32 tasksid, | ||
197 | u16 tclass); | 292 | u16 tclass); |
198 | 293 | ||
199 | int security_validate_transition_user(u32 oldsid, u32 newsid, u32 tasksid, | 294 | int security_validate_transition_user(struct selinux_state *state, |
295 | u32 oldsid, u32 newsid, u32 tasksid, | ||
200 | u16 tclass); | 296 | u16 tclass); |
201 | 297 | ||
202 | int security_bounded_transition(u32 oldsid, u32 newsid); | 298 | int security_bounded_transition(struct selinux_state *state, |
299 | u32 oldsid, u32 newsid); | ||
203 | 300 | ||
204 | int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid); | 301 | int security_sid_mls_copy(struct selinux_state *state, |
302 | u32 sid, u32 mls_sid, u32 *new_sid); | ||
205 | 303 | ||
206 | int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, | 304 | int security_net_peersid_resolve(struct selinux_state *state, |
305 | u32 nlbl_sid, u32 nlbl_type, | ||
207 | u32 xfrm_sid, | 306 | u32 xfrm_sid, |
208 | u32 *peer_sid); | 307 | u32 *peer_sid); |
209 | 308 | ||
210 | int security_get_classes(char ***classes, int *nclasses); | 309 | int security_get_classes(struct selinux_state *state, |
211 | int security_get_permissions(char *class, char ***perms, int *nperms); | 310 | char ***classes, int *nclasses); |
212 | int security_get_reject_unknown(void); | 311 | int security_get_permissions(struct selinux_state *state, |
213 | int security_get_allow_unknown(void); | 312 | char *class, char ***perms, int *nperms); |
313 | int security_get_reject_unknown(struct selinux_state *state); | ||
314 | int security_get_allow_unknown(struct selinux_state *state); | ||
214 | 315 | ||
215 | #define SECURITY_FS_USE_XATTR 1 /* use xattr */ | 316 | #define SECURITY_FS_USE_XATTR 1 /* use xattr */ |
216 | #define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */ | 317 | #define SECURITY_FS_USE_TRANS 2 /* use transition SIDs, e.g. devpts/tmpfs */ |
@@ -221,27 +322,31 @@ int security_get_allow_unknown(void); | |||
221 | #define SECURITY_FS_USE_NATIVE 7 /* use native label support */ | 322 | #define SECURITY_FS_USE_NATIVE 7 /* use native label support */ |
222 | #define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */ | 323 | #define SECURITY_FS_USE_MAX 7 /* Highest SECURITY_FS_USE_XXX */ |
223 | 324 | ||
224 | int security_fs_use(struct super_block *sb); | 325 | int security_fs_use(struct selinux_state *state, struct super_block *sb); |
225 | 326 | ||
226 | int security_genfs_sid(const char *fstype, char *name, u16 sclass, | 327 | int security_genfs_sid(struct selinux_state *state, |
227 | u32 *sid); | 328 | const char *fstype, char *name, u16 sclass, |
329 | u32 *sid); | ||
228 | 330 | ||
229 | #ifdef CONFIG_NETLABEL | 331 | #ifdef CONFIG_NETLABEL |
230 | int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, | 332 | int security_netlbl_secattr_to_sid(struct selinux_state *state, |
333 | struct netlbl_lsm_secattr *secattr, | ||
231 | u32 *sid); | 334 | u32 *sid); |
232 | 335 | ||
233 | int security_netlbl_sid_to_secattr(u32 sid, | 336 | int security_netlbl_sid_to_secattr(struct selinux_state *state, |
337 | u32 sid, | ||
234 | struct netlbl_lsm_secattr *secattr); | 338 | struct netlbl_lsm_secattr *secattr); |
235 | #else | 339 | #else |
236 | static inline int security_netlbl_secattr_to_sid( | 340 | static inline int security_netlbl_secattr_to_sid(struct selinux_state *state, |
237 | struct netlbl_lsm_secattr *secattr, | 341 | struct netlbl_lsm_secattr *secattr, |
238 | u32 *sid) | 342 | u32 *sid) |
239 | { | 343 | { |
240 | return -EIDRM; | 344 | return -EIDRM; |
241 | } | 345 | } |
242 | 346 | ||
243 | static inline int security_netlbl_sid_to_secattr(u32 sid, | 347 | static inline int security_netlbl_sid_to_secattr(struct selinux_state *state, |
244 | struct netlbl_lsm_secattr *secattr) | 348 | u32 sid, |
349 | struct netlbl_lsm_secattr *secattr) | ||
245 | { | 350 | { |
246 | return -ENOENT; | 351 | return -ENOENT; |
247 | } | 352 | } |
@@ -252,7 +357,7 @@ const char *security_get_initial_sid_context(u32 sid); | |||
252 | /* | 357 | /* |
253 | * status notifier using mmap interface | 358 | * status notifier using mmap interface |
254 | */ | 359 | */ |
255 | extern struct page *selinux_kernel_status_page(void); | 360 | extern struct page *selinux_kernel_status_page(struct selinux_state *state); |
256 | 361 | ||
257 | #define SELINUX_KERNEL_STATUS_VERSION 1 | 362 | #define SELINUX_KERNEL_STATUS_VERSION 1 |
258 | struct selinux_kernel_status { | 363 | struct selinux_kernel_status { |
@@ -266,10 +371,12 @@ struct selinux_kernel_status { | |||
266 | */ | 371 | */ |
267 | } __packed; | 372 | } __packed; |
268 | 373 | ||
269 | extern void selinux_status_update_setenforce(int enforcing); | 374 | extern void selinux_status_update_setenforce(struct selinux_state *state, |
270 | extern void selinux_status_update_policyload(int seqno); | 375 | int enforcing); |
376 | extern void selinux_status_update_policyload(struct selinux_state *state, | ||
377 | int seqno); | ||
271 | extern void selinux_complete_init(void); | 378 | extern void selinux_complete_init(void); |
272 | extern int selinux_disable(void); | 379 | extern int selinux_disable(struct selinux_state *state); |
273 | extern void exit_sel_fs(void); | 380 | extern void exit_sel_fs(void); |
274 | extern struct path selinux_null; | 381 | extern struct path selinux_null; |
275 | extern struct vfsmount *selinuxfs_mount; | 382 | extern struct vfsmount *selinuxfs_mount; |
@@ -277,5 +384,8 @@ extern void selnl_notify_setenforce(int val); | |||
277 | extern void selnl_notify_policyload(u32 seqno); | 384 | extern void selnl_notify_policyload(u32 seqno); |
278 | extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); | 385 | extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); |
279 | 386 | ||
280 | #endif /* _SELINUX_SECURITY_H_ */ | 387 | extern void avtab_cache_init(void); |
388 | extern void ebitmap_cache_init(void); | ||
389 | extern void hashtab_cache_init(void); | ||
281 | 390 | ||
391 | #endif /* _SELINUX_SECURITY_H_ */ | ||
diff --git a/security/selinux/netif.c b/security/selinux/netif.c index e607b4473ef6..ac65f7417413 100644 --- a/security/selinux/netif.c +++ b/security/selinux/netif.c | |||
@@ -163,7 +163,7 @@ static int sel_netif_sid_slow(struct net *ns, int ifindex, u32 *sid) | |||
163 | ret = -ENOMEM; | 163 | ret = -ENOMEM; |
164 | goto out; | 164 | goto out; |
165 | } | 165 | } |
166 | ret = security_netif_sid(dev->name, &new->nsec.sid); | 166 | ret = security_netif_sid(&selinux_state, dev->name, &new->nsec.sid); |
167 | if (ret != 0) | 167 | if (ret != 0) |
168 | goto out; | 168 | goto out; |
169 | new->nsec.ns = ns; | 169 | new->nsec.ns = ns; |
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 8730be427390..28010f741cfe 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c | |||
@@ -59,7 +59,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb, | |||
59 | { | 59 | { |
60 | int rc; | 60 | int rc; |
61 | 61 | ||
62 | rc = security_netlbl_secattr_to_sid(secattr, sid); | 62 | rc = security_netlbl_secattr_to_sid(&selinux_state, secattr, sid); |
63 | if (rc == 0 && | 63 | if (rc == 0 && |
64 | (secattr->flags & NETLBL_SECATTR_CACHEABLE) && | 64 | (secattr->flags & NETLBL_SECATTR_CACHEABLE) && |
65 | (secattr->flags & NETLBL_SECATTR_CACHE)) | 65 | (secattr->flags & NETLBL_SECATTR_CACHE)) |
@@ -90,7 +90,8 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk) | |||
90 | secattr = netlbl_secattr_alloc(GFP_ATOMIC); | 90 | secattr = netlbl_secattr_alloc(GFP_ATOMIC); |
91 | if (secattr == NULL) | 91 | if (secattr == NULL) |
92 | return NULL; | 92 | return NULL; |
93 | rc = security_netlbl_sid_to_secattr(sksec->sid, secattr); | 93 | rc = security_netlbl_sid_to_secattr(&selinux_state, sksec->sid, |
94 | secattr); | ||
94 | if (rc != 0) { | 95 | if (rc != 0) { |
95 | netlbl_secattr_free(secattr); | 96 | netlbl_secattr_free(secattr); |
96 | return NULL; | 97 | return NULL; |
@@ -257,7 +258,8 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, | |||
257 | if (secattr == NULL) { | 258 | if (secattr == NULL) { |
258 | secattr = &secattr_storage; | 259 | secattr = &secattr_storage; |
259 | netlbl_secattr_init(secattr); | 260 | netlbl_secattr_init(secattr); |
260 | rc = security_netlbl_sid_to_secattr(sid, secattr); | 261 | rc = security_netlbl_sid_to_secattr(&selinux_state, sid, |
262 | secattr); | ||
261 | if (rc != 0) | 263 | if (rc != 0) |
262 | goto skbuff_setsid_return; | 264 | goto skbuff_setsid_return; |
263 | } | 265 | } |
@@ -297,7 +299,8 @@ int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep, | |||
297 | return 0; | 299 | return 0; |
298 | 300 | ||
299 | netlbl_secattr_init(&secattr); | 301 | netlbl_secattr_init(&secattr); |
300 | rc = security_netlbl_sid_to_secattr(ep->secid, &secattr); | 302 | rc = security_netlbl_sid_to_secattr(&selinux_state, |
303 | ep->secid, &secattr); | ||
301 | if (rc != 0) | 304 | if (rc != 0) |
302 | goto assoc_request_return; | 305 | goto assoc_request_return; |
303 | 306 | ||
@@ -345,7 +348,8 @@ int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family) | |||
345 | return 0; | 348 | return 0; |
346 | 349 | ||
347 | netlbl_secattr_init(&secattr); | 350 | netlbl_secattr_init(&secattr); |
348 | rc = security_netlbl_sid_to_secattr(req->secid, &secattr); | 351 | rc = security_netlbl_sid_to_secattr(&selinux_state, req->secid, |
352 | &secattr); | ||
349 | if (rc != 0) | 353 | if (rc != 0) |
350 | goto inet_conn_request_return; | 354 | goto inet_conn_request_return; |
351 | rc = netlbl_req_setattr(req, &secattr); | 355 | rc = netlbl_req_setattr(req, &secattr); |
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c index da923f89d2a9..6dd89b89bc1f 100644 --- a/security/selinux/netnode.c +++ b/security/selinux/netnode.c | |||
@@ -215,12 +215,12 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) | |||
215 | goto out; | 215 | goto out; |
216 | switch (family) { | 216 | switch (family) { |
217 | case PF_INET: | 217 | case PF_INET: |
218 | ret = security_node_sid(PF_INET, | 218 | ret = security_node_sid(&selinux_state, PF_INET, |
219 | addr, sizeof(struct in_addr), sid); | 219 | addr, sizeof(struct in_addr), sid); |
220 | new->nsec.addr.ipv4 = *(__be32 *)addr; | 220 | new->nsec.addr.ipv4 = *(__be32 *)addr; |
221 | break; | 221 | break; |
222 | case PF_INET6: | 222 | case PF_INET6: |
223 | ret = security_node_sid(PF_INET6, | 223 | ret = security_node_sid(&selinux_state, PF_INET6, |
224 | addr, sizeof(struct in6_addr), sid); | 224 | addr, sizeof(struct in6_addr), sid); |
225 | new->nsec.addr.ipv6 = *(struct in6_addr *)addr; | 225 | new->nsec.addr.ipv6 = *(struct in6_addr *)addr; |
226 | break; | 226 | break; |
diff --git a/security/selinux/netport.c b/security/selinux/netport.c index 3311cc393cb4..9ed4c5064a5e 100644 --- a/security/selinux/netport.c +++ b/security/selinux/netport.c | |||
@@ -161,7 +161,7 @@ static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid) | |||
161 | new = kzalloc(sizeof(*new), GFP_ATOMIC); | 161 | new = kzalloc(sizeof(*new), GFP_ATOMIC); |
162 | if (new == NULL) | 162 | if (new == NULL) |
163 | goto out; | 163 | goto out; |
164 | ret = security_port_sid(protocol, pnum, sid); | 164 | ret = security_port_sid(&selinux_state, protocol, pnum, sid); |
165 | if (ret != 0) | 165 | if (ret != 0) |
166 | goto out; | 166 | goto out; |
167 | 167 | ||
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 00eed842c491..98492755adbf 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -41,17 +41,6 @@ | |||
41 | #include "objsec.h" | 41 | #include "objsec.h" |
42 | #include "conditional.h" | 42 | #include "conditional.h" |
43 | 43 | ||
44 | unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; | ||
45 | |||
46 | static int __init checkreqprot_setup(char *str) | ||
47 | { | ||
48 | unsigned long checkreqprot; | ||
49 | if (!kstrtoul(str, 0, &checkreqprot)) | ||
50 | selinux_checkreqprot = checkreqprot ? 1 : 0; | ||
51 | return 1; | ||
52 | } | ||
53 | __setup("checkreqprot=", checkreqprot_setup); | ||
54 | |||
55 | static DEFINE_MUTEX(sel_mutex); | 44 | static DEFINE_MUTEX(sel_mutex); |
56 | 45 | ||
57 | /* global data for booleans */ | 46 | /* global data for booleans */ |
@@ -108,7 +97,8 @@ static ssize_t sel_read_enforce(struct file *filp, char __user *buf, | |||
108 | char tmpbuf[TMPBUFLEN]; | 97 | char tmpbuf[TMPBUFLEN]; |
109 | ssize_t length; | 98 | ssize_t length; |
110 | 99 | ||
111 | length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_enforcing); | 100 | length = scnprintf(tmpbuf, TMPBUFLEN, "%d", |
101 | is_enforcing(&selinux_state)); | ||
112 | return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); | 102 | return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); |
113 | } | 103 | } |
114 | 104 | ||
@@ -119,7 +109,7 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf, | |||
119 | { | 109 | { |
120 | char *page = NULL; | 110 | char *page = NULL; |
121 | ssize_t length; | 111 | ssize_t length; |
122 | int new_value; | 112 | int old_value, new_value; |
123 | 113 | ||
124 | if (count >= PAGE_SIZE) | 114 | if (count >= PAGE_SIZE) |
125 | return -ENOMEM; | 115 | return -ENOMEM; |
@@ -138,7 +128,9 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf, | |||
138 | 128 | ||
139 | new_value = !!new_value; | 129 | new_value = !!new_value; |
140 | 130 | ||
141 | if (new_value != selinux_enforcing) { | 131 | old_value = is_enforcing(&selinux_state); |
132 | |||
133 | if (new_value != old_value) { | ||
142 | length = avc_has_perm(current_sid(), SECINITSID_SECURITY, | 134 | length = avc_has_perm(current_sid(), SECINITSID_SECURITY, |
143 | SECCLASS_SECURITY, SECURITY__SETENFORCE, | 135 | SECCLASS_SECURITY, SECURITY__SETENFORCE, |
144 | NULL); | 136 | NULL); |
@@ -146,15 +138,16 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf, | |||
146 | goto out; | 138 | goto out; |
147 | audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, | 139 | audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, |
148 | "enforcing=%d old_enforcing=%d auid=%u ses=%u", | 140 | "enforcing=%d old_enforcing=%d auid=%u ses=%u", |
149 | new_value, selinux_enforcing, | 141 | new_value, old_value, |
150 | from_kuid(&init_user_ns, audit_get_loginuid(current)), | 142 | from_kuid(&init_user_ns, audit_get_loginuid(current)), |
151 | audit_get_sessionid(current)); | 143 | audit_get_sessionid(current)); |
152 | selinux_enforcing = new_value; | 144 | set_enforcing(&selinux_state, new_value); |
153 | if (selinux_enforcing) | 145 | if (new_value) |
154 | avc_ss_reset(0); | 146 | avc_ss_reset(0); |
155 | selnl_notify_setenforce(selinux_enforcing); | 147 | selnl_notify_setenforce(new_value); |
156 | selinux_status_update_setenforce(selinux_enforcing); | 148 | selinux_status_update_setenforce(&selinux_state, |
157 | if (!selinux_enforcing) | 149 | new_value); |
150 | if (!new_value) | ||
158 | call_lsm_notifier(LSM_POLICY_CHANGE, NULL); | 151 | call_lsm_notifier(LSM_POLICY_CHANGE, NULL); |
159 | } | 152 | } |
160 | length = count; | 153 | length = count; |
@@ -179,7 +172,8 @@ static ssize_t sel_read_handle_unknown(struct file *filp, char __user *buf, | |||
179 | ssize_t length; | 172 | ssize_t length; |
180 | ino_t ino = file_inode(filp)->i_ino; | 173 | ino_t ino = file_inode(filp)->i_ino; |
181 | int handle_unknown = (ino == SEL_REJECT_UNKNOWN) ? | 174 | int handle_unknown = (ino == SEL_REJECT_UNKNOWN) ? |
182 | security_get_reject_unknown() : !security_get_allow_unknown(); | 175 | security_get_reject_unknown(&selinux_state) : |
176 | !security_get_allow_unknown(&selinux_state); | ||
183 | 177 | ||
184 | length = scnprintf(tmpbuf, TMPBUFLEN, "%d", handle_unknown); | 178 | length = scnprintf(tmpbuf, TMPBUFLEN, "%d", handle_unknown); |
185 | return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); | 179 | return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); |
@@ -192,7 +186,7 @@ static const struct file_operations sel_handle_unknown_ops = { | |||
192 | 186 | ||
193 | static int sel_open_handle_status(struct inode *inode, struct file *filp) | 187 | static int sel_open_handle_status(struct inode *inode, struct file *filp) |
194 | { | 188 | { |
195 | struct page *status = selinux_kernel_status_page(); | 189 | struct page *status = selinux_kernel_status_page(&selinux_state); |
196 | 190 | ||
197 | if (!status) | 191 | if (!status) |
198 | return -ENOMEM; | 192 | return -ENOMEM; |
@@ -268,7 +262,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf, | |||
268 | goto out; | 262 | goto out; |
269 | 263 | ||
270 | if (new_value) { | 264 | if (new_value) { |
271 | length = selinux_disable(); | 265 | length = selinux_disable(&selinux_state); |
272 | if (length) | 266 | if (length) |
273 | goto out; | 267 | goto out; |
274 | audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, | 268 | audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, |
@@ -322,7 +316,7 @@ static ssize_t sel_read_mls(struct file *filp, char __user *buf, | |||
322 | ssize_t length; | 316 | ssize_t length; |
323 | 317 | ||
324 | length = scnprintf(tmpbuf, TMPBUFLEN, "%d", | 318 | length = scnprintf(tmpbuf, TMPBUFLEN, "%d", |
325 | security_mls_enabled()); | 319 | security_mls_enabled(&selinux_state)); |
326 | return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); | 320 | return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); |
327 | } | 321 | } |
328 | 322 | ||
@@ -359,13 +353,13 @@ static int sel_open_policy(struct inode *inode, struct file *filp) | |||
359 | if (!plm) | 353 | if (!plm) |
360 | goto err; | 354 | goto err; |
361 | 355 | ||
362 | if (i_size_read(inode) != security_policydb_len()) { | 356 | if (i_size_read(inode) != security_policydb_len(&selinux_state)) { |
363 | inode_lock(inode); | 357 | inode_lock(inode); |
364 | i_size_write(inode, security_policydb_len()); | 358 | i_size_write(inode, security_policydb_len(&selinux_state)); |
365 | inode_unlock(inode); | 359 | inode_unlock(inode); |
366 | } | 360 | } |
367 | 361 | ||
368 | rc = security_read_policy(&plm->data, &plm->len); | 362 | rc = security_read_policy(&selinux_state, &plm->data, &plm->len); |
369 | if (rc) | 363 | if (rc) |
370 | goto err; | 364 | goto err; |
371 | 365 | ||
@@ -500,7 +494,7 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf, | |||
500 | if (copy_from_user(data, buf, count) != 0) | 494 | if (copy_from_user(data, buf, count) != 0) |
501 | goto out; | 495 | goto out; |
502 | 496 | ||
503 | length = security_load_policy(data, count); | 497 | length = security_load_policy(&selinux_state, data, count); |
504 | if (length) { | 498 | if (length) { |
505 | pr_warn_ratelimited("SELinux: failed to load policy\n"); | 499 | pr_warn_ratelimited("SELinux: failed to load policy\n"); |
506 | goto out; | 500 | goto out; |
@@ -553,11 +547,12 @@ static ssize_t sel_write_context(struct file *file, char *buf, size_t size) | |||
553 | if (length) | 547 | if (length) |
554 | goto out; | 548 | goto out; |
555 | 549 | ||
556 | length = security_context_to_sid(buf, size, &sid, GFP_KERNEL); | 550 | length = security_context_to_sid(&selinux_state, buf, size, |
551 | &sid, GFP_KERNEL); | ||
557 | if (length) | 552 | if (length) |
558 | goto out; | 553 | goto out; |
559 | 554 | ||
560 | length = security_sid_to_context(sid, &canon, &len); | 555 | length = security_sid_to_context(&selinux_state, sid, &canon, &len); |
561 | if (length) | 556 | if (length) |
562 | goto out; | 557 | goto out; |
563 | 558 | ||
@@ -581,7 +576,7 @@ static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf, | |||
581 | char tmpbuf[TMPBUFLEN]; | 576 | char tmpbuf[TMPBUFLEN]; |
582 | ssize_t length; | 577 | ssize_t length; |
583 | 578 | ||
584 | length = scnprintf(tmpbuf, TMPBUFLEN, "%u", selinux_checkreqprot); | 579 | length = scnprintf(tmpbuf, TMPBUFLEN, "%u", selinux_state.checkreqprot); |
585 | return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); | 580 | return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); |
586 | } | 581 | } |
587 | 582 | ||
@@ -613,7 +608,7 @@ static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf, | |||
613 | if (sscanf(page, "%u", &new_value) != 1) | 608 | if (sscanf(page, "%u", &new_value) != 1) |
614 | goto out; | 609 | goto out; |
615 | 610 | ||
616 | selinux_checkreqprot = new_value ? 1 : 0; | 611 | selinux_state.checkreqprot = new_value ? 1 : 0; |
617 | length = count; | 612 | length = count; |
618 | out: | 613 | out: |
619 | kfree(page); | 614 | kfree(page); |
@@ -673,19 +668,23 @@ static ssize_t sel_write_validatetrans(struct file *file, | |||
673 | if (sscanf(req, "%s %s %hu %s", oldcon, newcon, &tclass, taskcon) != 4) | 668 | if (sscanf(req, "%s %s %hu %s", oldcon, newcon, &tclass, taskcon) != 4) |
674 | goto out; | 669 | goto out; |
675 | 670 | ||
676 | rc = security_context_str_to_sid(oldcon, &osid, GFP_KERNEL); | 671 | rc = security_context_str_to_sid(&selinux_state, oldcon, &osid, |
672 | GFP_KERNEL); | ||
677 | if (rc) | 673 | if (rc) |
678 | goto out; | 674 | goto out; |
679 | 675 | ||
680 | rc = security_context_str_to_sid(newcon, &nsid, GFP_KERNEL); | 676 | rc = security_context_str_to_sid(&selinux_state, newcon, &nsid, |
677 | GFP_KERNEL); | ||
681 | if (rc) | 678 | if (rc) |
682 | goto out; | 679 | goto out; |
683 | 680 | ||
684 | rc = security_context_str_to_sid(taskcon, &tsid, GFP_KERNEL); | 681 | rc = security_context_str_to_sid(&selinux_state, taskcon, &tsid, |
682 | GFP_KERNEL); | ||
685 | if (rc) | 683 | if (rc) |
686 | goto out; | 684 | goto out; |
687 | 685 | ||
688 | rc = security_validate_transition_user(osid, nsid, tsid, tclass); | 686 | rc = security_validate_transition_user(&selinux_state, osid, nsid, |
687 | tsid, tclass); | ||
689 | if (!rc) | 688 | if (!rc) |
690 | rc = count; | 689 | rc = count; |
691 | out: | 690 | out: |
@@ -780,15 +779,17 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size) | |||
780 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) | 779 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) |
781 | goto out; | 780 | goto out; |
782 | 781 | ||
783 | length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL); | 782 | length = security_context_str_to_sid(&selinux_state, scon, &ssid, |
783 | GFP_KERNEL); | ||
784 | if (length) | 784 | if (length) |
785 | goto out; | 785 | goto out; |
786 | 786 | ||
787 | length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL); | 787 | length = security_context_str_to_sid(&selinux_state, tcon, &tsid, |
788 | GFP_KERNEL); | ||
788 | if (length) | 789 | if (length) |
789 | goto out; | 790 | goto out; |
790 | 791 | ||
791 | security_compute_av_user(ssid, tsid, tclass, &avd); | 792 | security_compute_av_user(&selinux_state, ssid, tsid, tclass, &avd); |
792 | 793 | ||
793 | length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, | 794 | length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, |
794 | "%x %x %x %x %u %x", | 795 | "%x %x %x %x %u %x", |
@@ -868,20 +869,23 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) | |||
868 | objname = namebuf; | 869 | objname = namebuf; |
869 | } | 870 | } |
870 | 871 | ||
871 | length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL); | 872 | length = security_context_str_to_sid(&selinux_state, scon, &ssid, |
873 | GFP_KERNEL); | ||
872 | if (length) | 874 | if (length) |
873 | goto out; | 875 | goto out; |
874 | 876 | ||
875 | length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL); | 877 | length = security_context_str_to_sid(&selinux_state, tcon, &tsid, |
878 | GFP_KERNEL); | ||
876 | if (length) | 879 | if (length) |
877 | goto out; | 880 | goto out; |
878 | 881 | ||
879 | length = security_transition_sid_user(ssid, tsid, tclass, | 882 | length = security_transition_sid_user(&selinux_state, ssid, tsid, |
880 | objname, &newsid); | 883 | tclass, objname, &newsid); |
881 | if (length) | 884 | if (length) |
882 | goto out; | 885 | goto out; |
883 | 886 | ||
884 | length = security_sid_to_context(newsid, &newcon, &len); | 887 | length = security_sid_to_context(&selinux_state, newsid, &newcon, |
888 | &len); | ||
885 | if (length) | 889 | if (length) |
886 | goto out; | 890 | goto out; |
887 | 891 | ||
@@ -931,19 +935,23 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size) | |||
931 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) | 935 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) |
932 | goto out; | 936 | goto out; |
933 | 937 | ||
934 | length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL); | 938 | length = security_context_str_to_sid(&selinux_state, scon, &ssid, |
939 | GFP_KERNEL); | ||
935 | if (length) | 940 | if (length) |
936 | goto out; | 941 | goto out; |
937 | 942 | ||
938 | length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL); | 943 | length = security_context_str_to_sid(&selinux_state, tcon, &tsid, |
944 | GFP_KERNEL); | ||
939 | if (length) | 945 | if (length) |
940 | goto out; | 946 | goto out; |
941 | 947 | ||
942 | length = security_change_sid(ssid, tsid, tclass, &newsid); | 948 | length = security_change_sid(&selinux_state, ssid, tsid, tclass, |
949 | &newsid); | ||
943 | if (length) | 950 | if (length) |
944 | goto out; | 951 | goto out; |
945 | 952 | ||
946 | length = security_sid_to_context(newsid, &newcon, &len); | 953 | length = security_sid_to_context(&selinux_state, newsid, &newcon, |
954 | &len); | ||
947 | if (length) | 955 | if (length) |
948 | goto out; | 956 | goto out; |
949 | 957 | ||
@@ -989,18 +997,21 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size) | |||
989 | if (sscanf(buf, "%s %s", con, user) != 2) | 997 | if (sscanf(buf, "%s %s", con, user) != 2) |
990 | goto out; | 998 | goto out; |
991 | 999 | ||
992 | length = security_context_str_to_sid(con, &sid, GFP_KERNEL); | 1000 | length = security_context_str_to_sid(&selinux_state, con, &sid, |
1001 | GFP_KERNEL); | ||
993 | if (length) | 1002 | if (length) |
994 | goto out; | 1003 | goto out; |
995 | 1004 | ||
996 | length = security_get_user_sids(sid, user, &sids, &nsids); | 1005 | length = security_get_user_sids(&selinux_state, sid, user, &sids, |
1006 | &nsids); | ||
997 | if (length) | 1007 | if (length) |
998 | goto out; | 1008 | goto out; |
999 | 1009 | ||
1000 | length = sprintf(buf, "%u", nsids) + 1; | 1010 | length = sprintf(buf, "%u", nsids) + 1; |
1001 | ptr = buf + length; | 1011 | ptr = buf + length; |
1002 | for (i = 0; i < nsids; i++) { | 1012 | for (i = 0; i < nsids; i++) { |
1003 | rc = security_sid_to_context(sids[i], &newcon, &len); | 1013 | rc = security_sid_to_context(&selinux_state, sids[i], |
1014 | &newcon, &len); | ||
1004 | if (rc) { | 1015 | if (rc) { |
1005 | length = rc; | 1016 | length = rc; |
1006 | goto out; | 1017 | goto out; |
@@ -1051,19 +1062,23 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size) | |||
1051 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) | 1062 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) |
1052 | goto out; | 1063 | goto out; |
1053 | 1064 | ||
1054 | length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL); | 1065 | length = security_context_str_to_sid(&selinux_state, scon, &ssid, |
1066 | GFP_KERNEL); | ||
1055 | if (length) | 1067 | if (length) |
1056 | goto out; | 1068 | goto out; |
1057 | 1069 | ||
1058 | length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL); | 1070 | length = security_context_str_to_sid(&selinux_state, tcon, &tsid, |
1071 | GFP_KERNEL); | ||
1059 | if (length) | 1072 | if (length) |
1060 | goto out; | 1073 | goto out; |
1061 | 1074 | ||
1062 | length = security_member_sid(ssid, tsid, tclass, &newsid); | 1075 | length = security_member_sid(&selinux_state, ssid, tsid, tclass, |
1076 | &newsid); | ||
1063 | if (length) | 1077 | if (length) |
1064 | goto out; | 1078 | goto out; |
1065 | 1079 | ||
1066 | length = security_sid_to_context(newsid, &newcon, &len); | 1080 | length = security_sid_to_context(&selinux_state, newsid, &newcon, |
1081 | &len); | ||
1067 | if (length) | 1082 | if (length) |
1068 | goto out; | 1083 | goto out; |
1069 | 1084 | ||
@@ -1115,7 +1130,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf, | |||
1115 | if (!page) | 1130 | if (!page) |
1116 | goto out; | 1131 | goto out; |
1117 | 1132 | ||
1118 | cur_enforcing = security_get_bool_value(index); | 1133 | cur_enforcing = security_get_bool_value(&selinux_state, index); |
1119 | if (cur_enforcing < 0) { | 1134 | if (cur_enforcing < 0) { |
1120 | ret = cur_enforcing; | 1135 | ret = cur_enforcing; |
1121 | goto out; | 1136 | goto out; |
@@ -1226,7 +1241,8 @@ static ssize_t sel_commit_bools_write(struct file *filep, | |||
1226 | 1241 | ||
1227 | length = 0; | 1242 | length = 0; |
1228 | if (new_value && bool_pending_values) | 1243 | if (new_value && bool_pending_values) |
1229 | length = security_set_bools(bool_num, bool_pending_values); | 1244 | length = security_set_bools(&selinux_state, bool_num, |
1245 | bool_pending_values); | ||
1230 | 1246 | ||
1231 | if (!length) | 1247 | if (!length) |
1232 | length = count; | 1248 | length = count; |
@@ -1279,7 +1295,7 @@ static int sel_make_bools(void) | |||
1279 | if (!page) | 1295 | if (!page) |
1280 | goto out; | 1296 | goto out; |
1281 | 1297 | ||
1282 | ret = security_get_bools(&num, &names, &values); | 1298 | ret = security_get_bools(&selinux_state, &num, &names, &values); |
1283 | if (ret) | 1299 | if (ret) |
1284 | goto out; | 1300 | goto out; |
1285 | 1301 | ||
@@ -1300,7 +1316,8 @@ static int sel_make_bools(void) | |||
1300 | goto out; | 1316 | goto out; |
1301 | 1317 | ||
1302 | isec = (struct inode_security_struct *)inode->i_security; | 1318 | isec = (struct inode_security_struct *)inode->i_security; |
1303 | ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid); | 1319 | ret = security_genfs_sid(&selinux_state, "selinuxfs", page, |
1320 | SECCLASS_FILE, &sid); | ||
1304 | if (ret) { | 1321 | if (ret) { |
1305 | pr_warn_ratelimited("SELinux: no sid found, defaulting to security isid for %s\n", | 1322 | pr_warn_ratelimited("SELinux: no sid found, defaulting to security isid for %s\n", |
1306 | page); | 1323 | page); |
@@ -1524,7 +1541,7 @@ static ssize_t sel_read_initcon(struct file *file, char __user *buf, | |||
1524 | ssize_t ret; | 1541 | ssize_t ret; |
1525 | 1542 | ||
1526 | sid = file_inode(file)->i_ino&SEL_INO_MASK; | 1543 | sid = file_inode(file)->i_ino&SEL_INO_MASK; |
1527 | ret = security_sid_to_context(sid, &con, &len); | 1544 | ret = security_sid_to_context(&selinux_state, sid, &con, &len); |
1528 | if (ret) | 1545 | if (ret) |
1529 | return ret; | 1546 | return ret; |
1530 | 1547 | ||
@@ -1617,7 +1634,8 @@ static ssize_t sel_read_policycap(struct file *file, char __user *buf, | |||
1617 | ssize_t length; | 1634 | ssize_t length; |
1618 | unsigned long i_ino = file_inode(file)->i_ino; | 1635 | unsigned long i_ino = file_inode(file)->i_ino; |
1619 | 1636 | ||
1620 | value = security_policycap_supported(i_ino & SEL_INO_MASK); | 1637 | value = security_policycap_supported(&selinux_state, |
1638 | i_ino & SEL_INO_MASK); | ||
1621 | length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value); | 1639 | length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value); |
1622 | 1640 | ||
1623 | return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); | 1641 | return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); |
@@ -1634,7 +1652,8 @@ static int sel_make_perm_files(char *objclass, int classvalue, | |||
1634 | int i, rc, nperms; | 1652 | int i, rc, nperms; |
1635 | char **perms; | 1653 | char **perms; |
1636 | 1654 | ||
1637 | rc = security_get_permissions(objclass, &perms, &nperms); | 1655 | rc = security_get_permissions(&selinux_state, objclass, &perms, |
1656 | &nperms); | ||
1638 | if (rc) | 1657 | if (rc) |
1639 | return rc; | 1658 | return rc; |
1640 | 1659 | ||
@@ -1701,7 +1720,7 @@ static int sel_make_classes(void) | |||
1701 | /* delete any existing entries */ | 1720 | /* delete any existing entries */ |
1702 | sel_remove_entries(class_dir); | 1721 | sel_remove_entries(class_dir); |
1703 | 1722 | ||
1704 | rc = security_get_classes(&classes, &nclasses); | 1723 | rc = security_get_classes(&selinux_state, &classes, &nclasses); |
1705 | if (rc) | 1724 | if (rc) |
1706 | return rc; | 1725 | return rc; |
1707 | 1726 | ||
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index 2c3c7d010d8a..a2c9148b0662 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c | |||
@@ -655,7 +655,8 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp) | |||
655 | 655 | ||
656 | return rc; | 656 | return rc; |
657 | } | 657 | } |
658 | void avtab_cache_init(void) | 658 | |
659 | void __init avtab_cache_init(void) | ||
659 | { | 660 | { |
660 | avtab_node_cachep = kmem_cache_create("avtab_node", | 661 | avtab_node_cachep = kmem_cache_create("avtab_node", |
661 | sizeof(struct avtab_node), | 662 | sizeof(struct avtab_node), |
@@ -664,9 +665,3 @@ void avtab_cache_init(void) | |||
664 | sizeof(struct avtab_extended_perms), | 665 | sizeof(struct avtab_extended_perms), |
665 | 0, SLAB_PANIC, NULL); | 666 | 0, SLAB_PANIC, NULL); |
666 | } | 667 | } |
667 | |||
668 | void avtab_cache_destroy(void) | ||
669 | { | ||
670 | kmem_cache_destroy(avtab_node_cachep); | ||
671 | kmem_cache_destroy(avtab_xperms_cachep); | ||
672 | } | ||
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h index 725853cadc42..0d652fad5319 100644 --- a/security/selinux/ss/avtab.h +++ b/security/selinux/ss/avtab.h | |||
@@ -114,9 +114,6 @@ struct avtab_node *avtab_search_node(struct avtab *h, struct avtab_key *key); | |||
114 | 114 | ||
115 | struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified); | 115 | struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified); |
116 | 116 | ||
117 | void avtab_cache_init(void); | ||
118 | void avtab_cache_destroy(void); | ||
119 | |||
120 | #define MAX_AVTAB_HASH_BITS 16 | 117 | #define MAX_AVTAB_HASH_BITS 16 |
121 | #define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) | 118 | #define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) |
122 | 119 | ||
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c index b6a78b09235c..5ae8c61b75bf 100644 --- a/security/selinux/ss/ebitmap.c +++ b/security/selinux/ss/ebitmap.c | |||
@@ -523,14 +523,9 @@ int ebitmap_write(struct ebitmap *e, void *fp) | |||
523 | return 0; | 523 | return 0; |
524 | } | 524 | } |
525 | 525 | ||
526 | void ebitmap_cache_init(void) | 526 | void __init ebitmap_cache_init(void) |
527 | { | 527 | { |
528 | ebitmap_node_cachep = kmem_cache_create("ebitmap_node", | 528 | ebitmap_node_cachep = kmem_cache_create("ebitmap_node", |
529 | sizeof(struct ebitmap_node), | 529 | sizeof(struct ebitmap_node), |
530 | 0, SLAB_PANIC, NULL); | 530 | 0, SLAB_PANIC, NULL); |
531 | } | 531 | } |
532 | |||
533 | void ebitmap_cache_destroy(void) | ||
534 | { | ||
535 | kmem_cache_destroy(ebitmap_node_cachep); | ||
536 | } | ||
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h index edf4fa39c60a..6aa7cf6a2197 100644 --- a/security/selinux/ss/ebitmap.h +++ b/security/selinux/ss/ebitmap.h | |||
@@ -131,9 +131,6 @@ void ebitmap_destroy(struct ebitmap *e); | |||
131 | int ebitmap_read(struct ebitmap *e, void *fp); | 131 | int ebitmap_read(struct ebitmap *e, void *fp); |
132 | int ebitmap_write(struct ebitmap *e, void *fp); | 132 | int ebitmap_write(struct ebitmap *e, void *fp); |
133 | 133 | ||
134 | void ebitmap_cache_init(void); | ||
135 | void ebitmap_cache_destroy(void); | ||
136 | |||
137 | #ifdef CONFIG_NETLABEL | 134 | #ifdef CONFIG_NETLABEL |
138 | int ebitmap_netlbl_export(struct ebitmap *ebmap, | 135 | int ebitmap_netlbl_export(struct ebitmap *ebmap, |
139 | struct netlbl_lsm_catmap **catmap); | 136 | struct netlbl_lsm_catmap **catmap); |
diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c index fe25b3fb2154..ebfdaa31ee32 100644 --- a/security/selinux/ss/hashtab.c +++ b/security/selinux/ss/hashtab.c | |||
@@ -169,14 +169,10 @@ void hashtab_stat(struct hashtab *h, struct hashtab_info *info) | |||
169 | info->slots_used = slots_used; | 169 | info->slots_used = slots_used; |
170 | info->max_chain_len = max_chain_len; | 170 | info->max_chain_len = max_chain_len; |
171 | } | 171 | } |
172 | void hashtab_cache_init(void) | 172 | |
173 | void __init hashtab_cache_init(void) | ||
173 | { | 174 | { |
174 | hashtab_node_cachep = kmem_cache_create("hashtab_node", | 175 | hashtab_node_cachep = kmem_cache_create("hashtab_node", |
175 | sizeof(struct hashtab_node), | 176 | sizeof(struct hashtab_node), |
176 | 0, SLAB_PANIC, NULL); | 177 | 0, SLAB_PANIC, NULL); |
177 | } | 178 | } |
178 | |||
179 | void hashtab_cache_destroy(void) | ||
180 | { | ||
181 | kmem_cache_destroy(hashtab_node_cachep); | ||
182 | } | ||
diff --git a/security/selinux/ss/hashtab.h b/security/selinux/ss/hashtab.h index 6183ee2a2e7a..3e3e42bfd150 100644 --- a/security/selinux/ss/hashtab.h +++ b/security/selinux/ss/hashtab.h | |||
@@ -85,8 +85,4 @@ int hashtab_map(struct hashtab *h, | |||
85 | /* Fill info with some hash table statistics */ | 85 | /* Fill info with some hash table statistics */ |
86 | void hashtab_stat(struct hashtab *h, struct hashtab_info *info); | 86 | void hashtab_stat(struct hashtab *h, struct hashtab_info *info); |
87 | 87 | ||
88 | /* Use kmem_cache for hashtab_node */ | ||
89 | void hashtab_cache_init(void); | ||
90 | void hashtab_cache_destroy(void); | ||
91 | |||
92 | #endif /* _SS_HASHTAB_H */ | 88 | #endif /* _SS_HASHTAB_H */ |
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index ad982ce8bfa4..39475fb455bc 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c | |||
@@ -33,20 +33,20 @@ | |||
33 | * Return the length in bytes for the MLS fields of the | 33 | * Return the length in bytes for the MLS fields of the |
34 | * security context string representation of `context'. | 34 | * security context string representation of `context'. |
35 | */ | 35 | */ |
36 | int mls_compute_context_len(struct context *context) | 36 | int mls_compute_context_len(struct policydb *p, struct context *context) |
37 | { | 37 | { |
38 | int i, l, len, head, prev; | 38 | int i, l, len, head, prev; |
39 | char *nm; | 39 | char *nm; |
40 | struct ebitmap *e; | 40 | struct ebitmap *e; |
41 | struct ebitmap_node *node; | 41 | struct ebitmap_node *node; |
42 | 42 | ||
43 | if (!policydb.mls_enabled) | 43 | if (!p->mls_enabled) |
44 | return 0; | 44 | return 0; |
45 | 45 | ||
46 | len = 1; /* for the beginning ":" */ | 46 | len = 1; /* for the beginning ":" */ |
47 | for (l = 0; l < 2; l++) { | 47 | for (l = 0; l < 2; l++) { |
48 | int index_sens = context->range.level[l].sens; | 48 | int index_sens = context->range.level[l].sens; |
49 | len += strlen(sym_name(&policydb, SYM_LEVELS, index_sens - 1)); | 49 | len += strlen(sym_name(p, SYM_LEVELS, index_sens - 1)); |
50 | 50 | ||
51 | /* categories */ | 51 | /* categories */ |
52 | head = -2; | 52 | head = -2; |
@@ -56,17 +56,17 @@ int mls_compute_context_len(struct context *context) | |||
56 | if (i - prev > 1) { | 56 | if (i - prev > 1) { |
57 | /* one or more negative bits are skipped */ | 57 | /* one or more negative bits are skipped */ |
58 | if (head != prev) { | 58 | if (head != prev) { |
59 | nm = sym_name(&policydb, SYM_CATS, prev); | 59 | nm = sym_name(p, SYM_CATS, prev); |
60 | len += strlen(nm) + 1; | 60 | len += strlen(nm) + 1; |
61 | } | 61 | } |
62 | nm = sym_name(&policydb, SYM_CATS, i); | 62 | nm = sym_name(p, SYM_CATS, i); |
63 | len += strlen(nm) + 1; | 63 | len += strlen(nm) + 1; |
64 | head = i; | 64 | head = i; |
65 | } | 65 | } |
66 | prev = i; | 66 | prev = i; |
67 | } | 67 | } |
68 | if (prev != head) { | 68 | if (prev != head) { |
69 | nm = sym_name(&policydb, SYM_CATS, prev); | 69 | nm = sym_name(p, SYM_CATS, prev); |
70 | len += strlen(nm) + 1; | 70 | len += strlen(nm) + 1; |
71 | } | 71 | } |
72 | if (l == 0) { | 72 | if (l == 0) { |
@@ -86,7 +86,8 @@ int mls_compute_context_len(struct context *context) | |||
86 | * the MLS fields of `context' into the string `*scontext'. | 86 | * the MLS fields of `context' into the string `*scontext'. |
87 | * Update `*scontext' to point to the end of the MLS fields. | 87 | * Update `*scontext' to point to the end of the MLS fields. |
88 | */ | 88 | */ |
89 | void mls_sid_to_context(struct context *context, | 89 | void mls_sid_to_context(struct policydb *p, |
90 | struct context *context, | ||
90 | char **scontext) | 91 | char **scontext) |
91 | { | 92 | { |
92 | char *scontextp, *nm; | 93 | char *scontextp, *nm; |
@@ -94,7 +95,7 @@ void mls_sid_to_context(struct context *context, | |||
94 | struct ebitmap *e; | 95 | struct ebitmap *e; |
95 | struct ebitmap_node *node; | 96 | struct ebitmap_node *node; |
96 | 97 | ||
97 | if (!policydb.mls_enabled) | 98 | if (!p->mls_enabled) |
98 | return; | 99 | return; |
99 | 100 | ||
100 | scontextp = *scontext; | 101 | scontextp = *scontext; |
@@ -103,7 +104,7 @@ void mls_sid_to_context(struct context *context, | |||
103 | scontextp++; | 104 | scontextp++; |
104 | 105 | ||
105 | for (l = 0; l < 2; l++) { | 106 | for (l = 0; l < 2; l++) { |
106 | strcpy(scontextp, sym_name(&policydb, SYM_LEVELS, | 107 | strcpy(scontextp, sym_name(p, SYM_LEVELS, |
107 | context->range.level[l].sens - 1)); | 108 | context->range.level[l].sens - 1)); |
108 | scontextp += strlen(scontextp); | 109 | scontextp += strlen(scontextp); |
109 | 110 | ||
@@ -119,7 +120,7 @@ void mls_sid_to_context(struct context *context, | |||
119 | *scontextp++ = '.'; | 120 | *scontextp++ = '.'; |
120 | else | 121 | else |
121 | *scontextp++ = ','; | 122 | *scontextp++ = ','; |
122 | nm = sym_name(&policydb, SYM_CATS, prev); | 123 | nm = sym_name(p, SYM_CATS, prev); |
123 | strcpy(scontextp, nm); | 124 | strcpy(scontextp, nm); |
124 | scontextp += strlen(nm); | 125 | scontextp += strlen(nm); |
125 | } | 126 | } |
@@ -127,7 +128,7 @@ void mls_sid_to_context(struct context *context, | |||
127 | *scontextp++ = ':'; | 128 | *scontextp++ = ':'; |
128 | else | 129 | else |
129 | *scontextp++ = ','; | 130 | *scontextp++ = ','; |
130 | nm = sym_name(&policydb, SYM_CATS, i); | 131 | nm = sym_name(p, SYM_CATS, i); |
131 | strcpy(scontextp, nm); | 132 | strcpy(scontextp, nm); |
132 | scontextp += strlen(nm); | 133 | scontextp += strlen(nm); |
133 | head = i; | 134 | head = i; |
@@ -140,7 +141,7 @@ void mls_sid_to_context(struct context *context, | |||
140 | *scontextp++ = '.'; | 141 | *scontextp++ = '.'; |
141 | else | 142 | else |
142 | *scontextp++ = ','; | 143 | *scontextp++ = ','; |
143 | nm = sym_name(&policydb, SYM_CATS, prev); | 144 | nm = sym_name(p, SYM_CATS, prev); |
144 | strcpy(scontextp, nm); | 145 | strcpy(scontextp, nm); |
145 | scontextp += strlen(nm); | 146 | scontextp += strlen(nm); |
146 | } | 147 | } |
@@ -375,12 +376,13 @@ out: | |||
375 | * the string `str'. This function will allocate temporary memory with the | 376 | * the string `str'. This function will allocate temporary memory with the |
376 | * given constraints of gfp_mask. | 377 | * given constraints of gfp_mask. |
377 | */ | 378 | */ |
378 | int mls_from_string(char *str, struct context *context, gfp_t gfp_mask) | 379 | int mls_from_string(struct policydb *p, char *str, struct context *context, |
380 | gfp_t gfp_mask) | ||
379 | { | 381 | { |
380 | char *tmpstr, *freestr; | 382 | char *tmpstr, *freestr; |
381 | int rc; | 383 | int rc; |
382 | 384 | ||
383 | if (!policydb.mls_enabled) | 385 | if (!p->mls_enabled) |
384 | return -EINVAL; | 386 | return -EINVAL; |
385 | 387 | ||
386 | /* we need freestr because mls_context_to_sid will change | 388 | /* we need freestr because mls_context_to_sid will change |
@@ -389,7 +391,7 @@ int mls_from_string(char *str, struct context *context, gfp_t gfp_mask) | |||
389 | if (!tmpstr) { | 391 | if (!tmpstr) { |
390 | rc = -ENOMEM; | 392 | rc = -ENOMEM; |
391 | } else { | 393 | } else { |
392 | rc = mls_context_to_sid(&policydb, ':', &tmpstr, context, | 394 | rc = mls_context_to_sid(p, ':', &tmpstr, context, |
393 | NULL, SECSID_NULL); | 395 | NULL, SECSID_NULL); |
394 | kfree(freestr); | 396 | kfree(freestr); |
395 | } | 397 | } |
@@ -417,10 +419,11 @@ int mls_range_set(struct context *context, | |||
417 | return rc; | 419 | return rc; |
418 | } | 420 | } |
419 | 421 | ||
420 | int mls_setup_user_range(struct context *fromcon, struct user_datum *user, | 422 | int mls_setup_user_range(struct policydb *p, |
423 | struct context *fromcon, struct user_datum *user, | ||
421 | struct context *usercon) | 424 | struct context *usercon) |
422 | { | 425 | { |
423 | if (policydb.mls_enabled) { | 426 | if (p->mls_enabled) { |
424 | struct mls_level *fromcon_sen = &(fromcon->range.level[0]); | 427 | struct mls_level *fromcon_sen = &(fromcon->range.level[0]); |
425 | struct mls_level *fromcon_clr = &(fromcon->range.level[1]); | 428 | struct mls_level *fromcon_clr = &(fromcon->range.level[1]); |
426 | struct mls_level *user_low = &(user->range.level[0]); | 429 | struct mls_level *user_low = &(user->range.level[0]); |
@@ -470,7 +473,7 @@ int mls_convert_context(struct policydb *oldp, | |||
470 | struct ebitmap_node *node; | 473 | struct ebitmap_node *node; |
471 | int l, i; | 474 | int l, i; |
472 | 475 | ||
473 | if (!policydb.mls_enabled) | 476 | if (!oldp->mls_enabled || !newp->mls_enabled) |
474 | return 0; | 477 | return 0; |
475 | 478 | ||
476 | for (l = 0; l < 2; l++) { | 479 | for (l = 0; l < 2; l++) { |
@@ -503,7 +506,8 @@ int mls_convert_context(struct policydb *oldp, | |||
503 | return 0; | 506 | return 0; |
504 | } | 507 | } |
505 | 508 | ||
506 | int mls_compute_sid(struct context *scontext, | 509 | int mls_compute_sid(struct policydb *p, |
510 | struct context *scontext, | ||
507 | struct context *tcontext, | 511 | struct context *tcontext, |
508 | u16 tclass, | 512 | u16 tclass, |
509 | u32 specified, | 513 | u32 specified, |
@@ -515,7 +519,7 @@ int mls_compute_sid(struct context *scontext, | |||
515 | struct class_datum *cladatum; | 519 | struct class_datum *cladatum; |
516 | int default_range = 0; | 520 | int default_range = 0; |
517 | 521 | ||
518 | if (!policydb.mls_enabled) | 522 | if (!p->mls_enabled) |
519 | return 0; | 523 | return 0; |
520 | 524 | ||
521 | switch (specified) { | 525 | switch (specified) { |
@@ -524,12 +528,12 @@ int mls_compute_sid(struct context *scontext, | |||
524 | rtr.source_type = scontext->type; | 528 | rtr.source_type = scontext->type; |
525 | rtr.target_type = tcontext->type; | 529 | rtr.target_type = tcontext->type; |
526 | rtr.target_class = tclass; | 530 | rtr.target_class = tclass; |
527 | r = hashtab_search(policydb.range_tr, &rtr); | 531 | r = hashtab_search(p->range_tr, &rtr); |
528 | if (r) | 532 | if (r) |
529 | return mls_range_set(newcontext, r); | 533 | return mls_range_set(newcontext, r); |
530 | 534 | ||
531 | if (tclass && tclass <= policydb.p_classes.nprim) { | 535 | if (tclass && tclass <= p->p_classes.nprim) { |
532 | cladatum = policydb.class_val_to_struct[tclass - 1]; | 536 | cladatum = p->class_val_to_struct[tclass - 1]; |
533 | if (cladatum) | 537 | if (cladatum) |
534 | default_range = cladatum->default_range; | 538 | default_range = cladatum->default_range; |
535 | } | 539 | } |
@@ -551,7 +555,7 @@ int mls_compute_sid(struct context *scontext, | |||
551 | 555 | ||
552 | /* Fallthrough */ | 556 | /* Fallthrough */ |
553 | case AVTAB_CHANGE: | 557 | case AVTAB_CHANGE: |
554 | if ((tclass == policydb.process_class) || (sock == true)) | 558 | if ((tclass == p->process_class) || (sock == true)) |
555 | /* Use the process MLS attributes. */ | 559 | /* Use the process MLS attributes. */ |
556 | return mls_context_cpy(newcontext, scontext); | 560 | return mls_context_cpy(newcontext, scontext); |
557 | else | 561 | else |
@@ -577,10 +581,11 @@ int mls_compute_sid(struct context *scontext, | |||
577 | * NetLabel MLS sensitivity level field. | 581 | * NetLabel MLS sensitivity level field. |
578 | * | 582 | * |
579 | */ | 583 | */ |
580 | void mls_export_netlbl_lvl(struct context *context, | 584 | void mls_export_netlbl_lvl(struct policydb *p, |
585 | struct context *context, | ||
581 | struct netlbl_lsm_secattr *secattr) | 586 | struct netlbl_lsm_secattr *secattr) |
582 | { | 587 | { |
583 | if (!policydb.mls_enabled) | 588 | if (!p->mls_enabled) |
584 | return; | 589 | return; |
585 | 590 | ||
586 | secattr->attr.mls.lvl = context->range.level[0].sens - 1; | 591 | secattr->attr.mls.lvl = context->range.level[0].sens - 1; |
@@ -597,10 +602,11 @@ void mls_export_netlbl_lvl(struct context *context, | |||
597 | * NetLabel MLS sensitivity level into the context. | 602 | * NetLabel MLS sensitivity level into the context. |
598 | * | 603 | * |
599 | */ | 604 | */ |
600 | void mls_import_netlbl_lvl(struct context *context, | 605 | void mls_import_netlbl_lvl(struct policydb *p, |
606 | struct context *context, | ||
601 | struct netlbl_lsm_secattr *secattr) | 607 | struct netlbl_lsm_secattr *secattr) |
602 | { | 608 | { |
603 | if (!policydb.mls_enabled) | 609 | if (!p->mls_enabled) |
604 | return; | 610 | return; |
605 | 611 | ||
606 | context->range.level[0].sens = secattr->attr.mls.lvl + 1; | 612 | context->range.level[0].sens = secattr->attr.mls.lvl + 1; |
@@ -617,12 +623,13 @@ void mls_import_netlbl_lvl(struct context *context, | |||
617 | * MLS category field. Returns zero on success, negative values on failure. | 623 | * MLS category field. Returns zero on success, negative values on failure. |
618 | * | 624 | * |
619 | */ | 625 | */ |
620 | int mls_export_netlbl_cat(struct context *context, | 626 | int mls_export_netlbl_cat(struct policydb *p, |
627 | struct context *context, | ||
621 | struct netlbl_lsm_secattr *secattr) | 628 | struct netlbl_lsm_secattr *secattr) |
622 | { | 629 | { |
623 | int rc; | 630 | int rc; |
624 | 631 | ||
625 | if (!policydb.mls_enabled) | 632 | if (!p->mls_enabled) |
626 | return 0; | 633 | return 0; |
627 | 634 | ||
628 | rc = ebitmap_netlbl_export(&context->range.level[0].cat, | 635 | rc = ebitmap_netlbl_export(&context->range.level[0].cat, |
@@ -645,12 +652,13 @@ int mls_export_netlbl_cat(struct context *context, | |||
645 | * negative values on failure. | 652 | * negative values on failure. |
646 | * | 653 | * |
647 | */ | 654 | */ |
648 | int mls_import_netlbl_cat(struct context *context, | 655 | int mls_import_netlbl_cat(struct policydb *p, |
656 | struct context *context, | ||
649 | struct netlbl_lsm_secattr *secattr) | 657 | struct netlbl_lsm_secattr *secattr) |
650 | { | 658 | { |
651 | int rc; | 659 | int rc; |
652 | 660 | ||
653 | if (!policydb.mls_enabled) | 661 | if (!p->mls_enabled) |
654 | return 0; | 662 | return 0; |
655 | 663 | ||
656 | rc = ebitmap_netlbl_import(&context->range.level[0].cat, | 664 | rc = ebitmap_netlbl_import(&context->range.level[0].cat, |
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index 131d76266ea5..9a3ff7af70ad 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h | |||
@@ -25,8 +25,9 @@ | |||
25 | #include "context.h" | 25 | #include "context.h" |
26 | #include "policydb.h" | 26 | #include "policydb.h" |
27 | 27 | ||
28 | int mls_compute_context_len(struct context *context); | 28 | int mls_compute_context_len(struct policydb *p, struct context *context); |
29 | void mls_sid_to_context(struct context *context, char **scontext); | 29 | void mls_sid_to_context(struct policydb *p, struct context *context, |
30 | char **scontext); | ||
30 | int mls_context_isvalid(struct policydb *p, struct context *c); | 31 | int mls_context_isvalid(struct policydb *p, struct context *c); |
31 | int mls_range_isvalid(struct policydb *p, struct mls_range *r); | 32 | int mls_range_isvalid(struct policydb *p, struct mls_range *r); |
32 | int mls_level_isvalid(struct policydb *p, struct mls_level *l); | 33 | int mls_level_isvalid(struct policydb *p, struct mls_level *l); |
@@ -38,7 +39,8 @@ int mls_context_to_sid(struct policydb *p, | |||
38 | struct sidtab *s, | 39 | struct sidtab *s, |
39 | u32 def_sid); | 40 | u32 def_sid); |
40 | 41 | ||
41 | int mls_from_string(char *str, struct context *context, gfp_t gfp_mask); | 42 | int mls_from_string(struct policydb *p, char *str, struct context *context, |
43 | gfp_t gfp_mask); | ||
42 | 44 | ||
43 | int mls_range_set(struct context *context, struct mls_range *range); | 45 | int mls_range_set(struct context *context, struct mls_range *range); |
44 | 46 | ||
@@ -46,42 +48,52 @@ int mls_convert_context(struct policydb *oldp, | |||
46 | struct policydb *newp, | 48 | struct policydb *newp, |
47 | struct context *context); | 49 | struct context *context); |
48 | 50 | ||
49 | int mls_compute_sid(struct context *scontext, | 51 | int mls_compute_sid(struct policydb *p, |
52 | struct context *scontext, | ||
50 | struct context *tcontext, | 53 | struct context *tcontext, |
51 | u16 tclass, | 54 | u16 tclass, |
52 | u32 specified, | 55 | u32 specified, |
53 | struct context *newcontext, | 56 | struct context *newcontext, |
54 | bool sock); | 57 | bool sock); |
55 | 58 | ||
56 | int mls_setup_user_range(struct context *fromcon, struct user_datum *user, | 59 | int mls_setup_user_range(struct policydb *p, |
60 | struct context *fromcon, struct user_datum *user, | ||
57 | struct context *usercon); | 61 | struct context *usercon); |
58 | 62 | ||
59 | #ifdef CONFIG_NETLABEL | 63 | #ifdef CONFIG_NETLABEL |
60 | void mls_export_netlbl_lvl(struct context *context, | 64 | void mls_export_netlbl_lvl(struct policydb *p, |
65 | struct context *context, | ||
61 | struct netlbl_lsm_secattr *secattr); | 66 | struct netlbl_lsm_secattr *secattr); |
62 | void mls_import_netlbl_lvl(struct context *context, | 67 | void mls_import_netlbl_lvl(struct policydb *p, |
68 | struct context *context, | ||
63 | struct netlbl_lsm_secattr *secattr); | 69 | struct netlbl_lsm_secattr *secattr); |
64 | int mls_export_netlbl_cat(struct context *context, | 70 | int mls_export_netlbl_cat(struct policydb *p, |
71 | struct context *context, | ||
65 | struct netlbl_lsm_secattr *secattr); | 72 | struct netlbl_lsm_secattr *secattr); |
66 | int mls_import_netlbl_cat(struct context *context, | 73 | int mls_import_netlbl_cat(struct policydb *p, |
74 | struct context *context, | ||
67 | struct netlbl_lsm_secattr *secattr); | 75 | struct netlbl_lsm_secattr *secattr); |
68 | #else | 76 | #else |
69 | static inline void mls_export_netlbl_lvl(struct context *context, | 77 | static inline void mls_export_netlbl_lvl(struct policydb *p, |
78 | struct context *context, | ||
70 | struct netlbl_lsm_secattr *secattr) | 79 | struct netlbl_lsm_secattr *secattr) |
71 | { | 80 | { |
72 | return; | 81 | return; |
73 | } | 82 | } |
74 | static inline void mls_import_netlbl_lvl(struct context *context, | 83 | static inline void mls_import_netlbl_lvl(struct policydb *p, |
84 | struct context *context, | ||
75 | struct netlbl_lsm_secattr *secattr) | 85 | struct netlbl_lsm_secattr *secattr) |
76 | { | 86 | { |
77 | return; | 87 | return; |
78 | } | 88 | } |
79 | static inline int mls_export_netlbl_cat(struct context *context, | 89 | static inline int mls_export_netlbl_cat(struct policydb *p, |
90 | struct context *context, | ||
80 | struct netlbl_lsm_secattr *secattr) | 91 | struct netlbl_lsm_secattr *secattr) |
81 | { | 92 | { |
82 | return -ENOMEM; | 93 | return -ENOMEM; |
83 | } | 94 | } |
84 | static inline int mls_import_netlbl_cat(struct context *context, | 95 | static inline int mls_import_netlbl_cat(struct policydb *p, |
96 | struct context *context, | ||
85 | struct netlbl_lsm_secattr *secattr) | 97 | struct netlbl_lsm_secattr *secattr) |
86 | { | 98 | { |
87 | return -ENOMEM; | 99 | return -ENOMEM; |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 8900ea5cbabf..3698352213d7 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -80,53 +80,32 @@ char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX] = { | |||
80 | "nnp_nosuid_transition" | 80 | "nnp_nosuid_transition" |
81 | }; | 81 | }; |
82 | 82 | ||
83 | int selinux_policycap_netpeer; | 83 | static struct selinux_ss selinux_ss; |
84 | int selinux_policycap_openperm; | ||
85 | int selinux_policycap_extsockclass; | ||
86 | int selinux_policycap_alwaysnetwork; | ||
87 | int selinux_policycap_cgroupseclabel; | ||
88 | int selinux_policycap_nnp_nosuid_transition; | ||
89 | 84 | ||
90 | static DEFINE_RWLOCK(policy_rwlock); | 85 | void selinux_ss_init(struct selinux_ss **ss) |
91 | 86 | { | |
92 | static struct sidtab sidtab; | 87 | rwlock_init(&selinux_ss.policy_rwlock); |
93 | struct policydb policydb; | 88 | mutex_init(&selinux_ss.status_lock); |
94 | int ss_initialized; | 89 | *ss = &selinux_ss; |
95 | 90 | } | |
96 | /* | ||
97 | * The largest sequence number that has been used when | ||
98 | * providing an access decision to the access vector cache. | ||
99 | * The sequence number only changes when a policy change | ||
100 | * occurs. | ||
101 | */ | ||
102 | static u32 latest_granting; | ||
103 | 91 | ||
104 | /* Forward declaration. */ | 92 | /* Forward declaration. */ |
105 | static int context_struct_to_string(struct context *context, char **scontext, | 93 | static int context_struct_to_string(struct policydb *policydb, |
94 | struct context *context, | ||
95 | char **scontext, | ||
106 | u32 *scontext_len); | 96 | u32 *scontext_len); |
107 | 97 | ||
108 | static void context_struct_compute_av(struct context *scontext, | 98 | static void context_struct_compute_av(struct policydb *policydb, |
109 | struct context *tcontext, | 99 | struct context *scontext, |
110 | u16 tclass, | 100 | struct context *tcontext, |
111 | struct av_decision *avd, | 101 | u16 tclass, |
112 | struct extended_perms *xperms); | 102 | struct av_decision *avd, |
113 | 103 | struct extended_perms *xperms); | |
114 | struct selinux_mapping { | ||
115 | u16 value; /* policy value */ | ||
116 | unsigned num_perms; | ||
117 | u32 perms[sizeof(u32) * 8]; | ||
118 | }; | ||
119 | |||
120 | static struct selinux_mapping *current_mapping; | ||
121 | static u16 current_mapping_size; | ||
122 | 104 | ||
123 | static int selinux_set_mapping(struct policydb *pol, | 105 | static int selinux_set_mapping(struct policydb *pol, |
124 | struct security_class_mapping *map, | 106 | struct security_class_mapping *map, |
125 | struct selinux_mapping **out_map_p, | 107 | struct selinux_map *out_map) |
126 | u16 *out_map_size) | ||
127 | { | 108 | { |
128 | struct selinux_mapping *out_map = NULL; | ||
129 | size_t size = sizeof(struct selinux_mapping); | ||
130 | u16 i, j; | 109 | u16 i, j; |
131 | unsigned k; | 110 | unsigned k; |
132 | bool print_unknown_handle = false; | 111 | bool print_unknown_handle = false; |
@@ -139,15 +118,15 @@ static int selinux_set_mapping(struct policydb *pol, | |||
139 | i++; | 118 | i++; |
140 | 119 | ||
141 | /* Allocate space for the class records, plus one for class zero */ | 120 | /* Allocate space for the class records, plus one for class zero */ |
142 | out_map = kcalloc(++i, size, GFP_ATOMIC); | 121 | out_map->mapping = kcalloc(++i, sizeof(*out_map->mapping), GFP_ATOMIC); |
143 | if (!out_map) | 122 | if (!out_map->mapping) |
144 | return -ENOMEM; | 123 | return -ENOMEM; |
145 | 124 | ||
146 | /* Store the raw class and permission values */ | 125 | /* Store the raw class and permission values */ |
147 | j = 0; | 126 | j = 0; |
148 | while (map[j].name) { | 127 | while (map[j].name) { |
149 | struct security_class_mapping *p_in = map + (j++); | 128 | struct security_class_mapping *p_in = map + (j++); |
150 | struct selinux_mapping *p_out = out_map + j; | 129 | struct selinux_mapping *p_out = out_map->mapping + j; |
151 | 130 | ||
152 | /* An empty class string skips ahead */ | 131 | /* An empty class string skips ahead */ |
153 | if (!strcmp(p_in->name, "")) { | 132 | if (!strcmp(p_in->name, "")) { |
@@ -194,11 +173,11 @@ static int selinux_set_mapping(struct policydb *pol, | |||
194 | printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n", | 173 | printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n", |
195 | pol->allow_unknown ? "allowed" : "denied"); | 174 | pol->allow_unknown ? "allowed" : "denied"); |
196 | 175 | ||
197 | *out_map_p = out_map; | 176 | out_map->size = i; |
198 | *out_map_size = i; | ||
199 | return 0; | 177 | return 0; |
200 | err: | 178 | err: |
201 | kfree(out_map); | 179 | kfree(out_map->mapping); |
180 | out_map->mapping = NULL; | ||
202 | return -EINVAL; | 181 | return -EINVAL; |
203 | } | 182 | } |
204 | 183 | ||
@@ -206,10 +185,10 @@ err: | |||
206 | * Get real, policy values from mapped values | 185 | * Get real, policy values from mapped values |
207 | */ | 186 | */ |
208 | 187 | ||
209 | static u16 unmap_class(u16 tclass) | 188 | static u16 unmap_class(struct selinux_map *map, u16 tclass) |
210 | { | 189 | { |
211 | if (tclass < current_mapping_size) | 190 | if (tclass < map->size) |
212 | return current_mapping[tclass].value; | 191 | return map->mapping[tclass].value; |
213 | 192 | ||
214 | return tclass; | 193 | return tclass; |
215 | } | 194 | } |
@@ -217,42 +196,44 @@ static u16 unmap_class(u16 tclass) | |||
217 | /* | 196 | /* |
218 | * Get kernel value for class from its policy value | 197 | * Get kernel value for class from its policy value |
219 | */ | 198 | */ |
220 | static u16 map_class(u16 pol_value) | 199 | static u16 map_class(struct selinux_map *map, u16 pol_value) |
221 | { | 200 | { |
222 | u16 i; | 201 | u16 i; |
223 | 202 | ||
224 | for (i = 1; i < current_mapping_size; i++) { | 203 | for (i = 1; i < map->size; i++) { |
225 | if (current_mapping[i].value == pol_value) | 204 | if (map->mapping[i].value == pol_value) |
226 | return i; | 205 | return i; |
227 | } | 206 | } |
228 | 207 | ||
229 | return SECCLASS_NULL; | 208 | return SECCLASS_NULL; |
230 | } | 209 | } |
231 | 210 | ||
232 | static void map_decision(u16 tclass, struct av_decision *avd, | 211 | static void map_decision(struct selinux_map *map, |
212 | u16 tclass, struct av_decision *avd, | ||
233 | int allow_unknown) | 213 | int allow_unknown) |
234 | { | 214 | { |
235 | if (tclass < current_mapping_size) { | 215 | if (tclass < map->size) { |
236 | unsigned i, n = current_mapping[tclass].num_perms; | 216 | struct selinux_mapping *mapping = &map->mapping[tclass]; |
217 | unsigned int i, n = mapping->num_perms; | ||
237 | u32 result; | 218 | u32 result; |
238 | 219 | ||
239 | for (i = 0, result = 0; i < n; i++) { | 220 | for (i = 0, result = 0; i < n; i++) { |
240 | if (avd->allowed & current_mapping[tclass].perms[i]) | 221 | if (avd->allowed & mapping->perms[i]) |
241 | result |= 1<<i; | 222 | result |= 1<<i; |
242 | if (allow_unknown && !current_mapping[tclass].perms[i]) | 223 | if (allow_unknown && !mapping->perms[i]) |
243 | result |= 1<<i; | 224 | result |= 1<<i; |
244 | } | 225 | } |
245 | avd->allowed = result; | 226 | avd->allowed = result; |
246 | 227 | ||
247 | for (i = 0, result = 0; i < n; i++) | 228 | for (i = 0, result = 0; i < n; i++) |
248 | if (avd->auditallow & current_mapping[tclass].perms[i]) | 229 | if (avd->auditallow & mapping->perms[i]) |
249 | result |= 1<<i; | 230 | result |= 1<<i; |
250 | avd->auditallow = result; | 231 | avd->auditallow = result; |
251 | 232 | ||
252 | for (i = 0, result = 0; i < n; i++) { | 233 | for (i = 0, result = 0; i < n; i++) { |
253 | if (avd->auditdeny & current_mapping[tclass].perms[i]) | 234 | if (avd->auditdeny & mapping->perms[i]) |
254 | result |= 1<<i; | 235 | result |= 1<<i; |
255 | if (!allow_unknown && !current_mapping[tclass].perms[i]) | 236 | if (!allow_unknown && !mapping->perms[i]) |
256 | result |= 1<<i; | 237 | result |= 1<<i; |
257 | } | 238 | } |
258 | /* | 239 | /* |
@@ -266,9 +247,11 @@ static void map_decision(u16 tclass, struct av_decision *avd, | |||
266 | } | 247 | } |
267 | } | 248 | } |
268 | 249 | ||
269 | int security_mls_enabled(void) | 250 | int security_mls_enabled(struct selinux_state *state) |
270 | { | 251 | { |
271 | return policydb.mls_enabled; | 252 | struct policydb *p = &state->ss->policydb; |
253 | |||
254 | return p->mls_enabled; | ||
272 | } | 255 | } |
273 | 256 | ||
274 | /* | 257 | /* |
@@ -282,7 +265,8 @@ int security_mls_enabled(void) | |||
282 | * of the process performing the transition. All other callers of | 265 | * of the process performing the transition. All other callers of |
283 | * constraint_expr_eval should pass in NULL for xcontext. | 266 | * constraint_expr_eval should pass in NULL for xcontext. |
284 | */ | 267 | */ |
285 | static int constraint_expr_eval(struct context *scontext, | 268 | static int constraint_expr_eval(struct policydb *policydb, |
269 | struct context *scontext, | ||
286 | struct context *tcontext, | 270 | struct context *tcontext, |
287 | struct context *xcontext, | 271 | struct context *xcontext, |
288 | struct constraint_expr *cexpr) | 272 | struct constraint_expr *cexpr) |
@@ -326,8 +310,8 @@ static int constraint_expr_eval(struct context *scontext, | |||
326 | case CEXPR_ROLE: | 310 | case CEXPR_ROLE: |
327 | val1 = scontext->role; | 311 | val1 = scontext->role; |
328 | val2 = tcontext->role; | 312 | val2 = tcontext->role; |
329 | r1 = policydb.role_val_to_struct[val1 - 1]; | 313 | r1 = policydb->role_val_to_struct[val1 - 1]; |
330 | r2 = policydb.role_val_to_struct[val2 - 1]; | 314 | r2 = policydb->role_val_to_struct[val2 - 1]; |
331 | switch (e->op) { | 315 | switch (e->op) { |
332 | case CEXPR_DOM: | 316 | case CEXPR_DOM: |
333 | s[++sp] = ebitmap_get_bit(&r1->dominates, | 317 | s[++sp] = ebitmap_get_bit(&r1->dominates, |
@@ -472,7 +456,8 @@ static int dump_masked_av_helper(void *k, void *d, void *args) | |||
472 | return 0; | 456 | return 0; |
473 | } | 457 | } |
474 | 458 | ||
475 | static void security_dump_masked_av(struct context *scontext, | 459 | static void security_dump_masked_av(struct policydb *policydb, |
460 | struct context *scontext, | ||
476 | struct context *tcontext, | 461 | struct context *tcontext, |
477 | u16 tclass, | 462 | u16 tclass, |
478 | u32 permissions, | 463 | u32 permissions, |
@@ -492,8 +477,8 @@ static void security_dump_masked_av(struct context *scontext, | |||
492 | if (!permissions) | 477 | if (!permissions) |
493 | return; | 478 | return; |
494 | 479 | ||
495 | tclass_name = sym_name(&policydb, SYM_CLASSES, tclass - 1); | 480 | tclass_name = sym_name(policydb, SYM_CLASSES, tclass - 1); |
496 | tclass_dat = policydb.class_val_to_struct[tclass - 1]; | 481 | tclass_dat = policydb->class_val_to_struct[tclass - 1]; |
497 | common_dat = tclass_dat->comdatum; | 482 | common_dat = tclass_dat->comdatum; |
498 | 483 | ||
499 | /* init permission_names */ | 484 | /* init permission_names */ |
@@ -507,11 +492,11 @@ static void security_dump_masked_av(struct context *scontext, | |||
507 | goto out; | 492 | goto out; |
508 | 493 | ||
509 | /* get scontext/tcontext in text form */ | 494 | /* get scontext/tcontext in text form */ |
510 | if (context_struct_to_string(scontext, | 495 | if (context_struct_to_string(policydb, scontext, |
511 | &scontext_name, &length) < 0) | 496 | &scontext_name, &length) < 0) |
512 | goto out; | 497 | goto out; |
513 | 498 | ||
514 | if (context_struct_to_string(tcontext, | 499 | if (context_struct_to_string(policydb, tcontext, |
515 | &tcontext_name, &length) < 0) | 500 | &tcontext_name, &length) < 0) |
516 | goto out; | 501 | goto out; |
517 | 502 | ||
@@ -550,7 +535,8 @@ out: | |||
550 | * security_boundary_permission - drops violated permissions | 535 | * security_boundary_permission - drops violated permissions |
551 | * on boundary constraint. | 536 | * on boundary constraint. |
552 | */ | 537 | */ |
553 | static void type_attribute_bounds_av(struct context *scontext, | 538 | static void type_attribute_bounds_av(struct policydb *policydb, |
539 | struct context *scontext, | ||
554 | struct context *tcontext, | 540 | struct context *tcontext, |
555 | u16 tclass, | 541 | u16 tclass, |
556 | struct av_decision *avd) | 542 | struct av_decision *avd) |
@@ -562,14 +548,14 @@ static void type_attribute_bounds_av(struct context *scontext, | |||
562 | struct type_datum *target; | 548 | struct type_datum *target; |
563 | u32 masked = 0; | 549 | u32 masked = 0; |
564 | 550 | ||
565 | source = flex_array_get_ptr(policydb.type_val_to_struct_array, | 551 | source = flex_array_get_ptr(policydb->type_val_to_struct_array, |
566 | scontext->type - 1); | 552 | scontext->type - 1); |
567 | BUG_ON(!source); | 553 | BUG_ON(!source); |
568 | 554 | ||
569 | if (!source->bounds) | 555 | if (!source->bounds) |
570 | return; | 556 | return; |
571 | 557 | ||
572 | target = flex_array_get_ptr(policydb.type_val_to_struct_array, | 558 | target = flex_array_get_ptr(policydb->type_val_to_struct_array, |
573 | tcontext->type - 1); | 559 | tcontext->type - 1); |
574 | BUG_ON(!target); | 560 | BUG_ON(!target); |
575 | 561 | ||
@@ -584,7 +570,7 @@ static void type_attribute_bounds_av(struct context *scontext, | |||
584 | tcontextp = &lo_tcontext; | 570 | tcontextp = &lo_tcontext; |
585 | } | 571 | } |
586 | 572 | ||
587 | context_struct_compute_av(&lo_scontext, | 573 | context_struct_compute_av(policydb, &lo_scontext, |
588 | tcontextp, | 574 | tcontextp, |
589 | tclass, | 575 | tclass, |
590 | &lo_avd, | 576 | &lo_avd, |
@@ -599,7 +585,7 @@ static void type_attribute_bounds_av(struct context *scontext, | |||
599 | avd->allowed &= ~masked; | 585 | avd->allowed &= ~masked; |
600 | 586 | ||
601 | /* audit masked permissions */ | 587 | /* audit masked permissions */ |
602 | security_dump_masked_av(scontext, tcontext, | 588 | security_dump_masked_av(policydb, scontext, tcontext, |
603 | tclass, masked, "bounds"); | 589 | tclass, masked, "bounds"); |
604 | } | 590 | } |
605 | 591 | ||
@@ -632,11 +618,12 @@ void services_compute_xperms_drivers( | |||
632 | * Compute access vectors and extended permissions based on a context | 618 | * Compute access vectors and extended permissions based on a context |
633 | * structure pair for the permissions in a particular class. | 619 | * structure pair for the permissions in a particular class. |
634 | */ | 620 | */ |
635 | static void context_struct_compute_av(struct context *scontext, | 621 | static void context_struct_compute_av(struct policydb *policydb, |
636 | struct context *tcontext, | 622 | struct context *scontext, |
637 | u16 tclass, | 623 | struct context *tcontext, |
638 | struct av_decision *avd, | 624 | u16 tclass, |
639 | struct extended_perms *xperms) | 625 | struct av_decision *avd, |
626 | struct extended_perms *xperms) | ||
640 | { | 627 | { |
641 | struct constraint_node *constraint; | 628 | struct constraint_node *constraint; |
642 | struct role_allow *ra; | 629 | struct role_allow *ra; |
@@ -655,13 +642,13 @@ static void context_struct_compute_av(struct context *scontext, | |||
655 | xperms->len = 0; | 642 | xperms->len = 0; |
656 | } | 643 | } |
657 | 644 | ||
658 | if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) { | 645 | if (unlikely(!tclass || tclass > policydb->p_classes.nprim)) { |
659 | if (printk_ratelimit()) | 646 | if (printk_ratelimit()) |
660 | printk(KERN_WARNING "SELinux: Invalid class %hu\n", tclass); | 647 | printk(KERN_WARNING "SELinux: Invalid class %hu\n", tclass); |
661 | return; | 648 | return; |
662 | } | 649 | } |
663 | 650 | ||
664 | tclass_datum = policydb.class_val_to_struct[tclass - 1]; | 651 | tclass_datum = policydb->class_val_to_struct[tclass - 1]; |
665 | 652 | ||
666 | /* | 653 | /* |
667 | * If a specific type enforcement rule was defined for | 654 | * If a specific type enforcement rule was defined for |
@@ -669,15 +656,18 @@ static void context_struct_compute_av(struct context *scontext, | |||
669 | */ | 656 | */ |
670 | avkey.target_class = tclass; | 657 | avkey.target_class = tclass; |
671 | avkey.specified = AVTAB_AV | AVTAB_XPERMS; | 658 | avkey.specified = AVTAB_AV | AVTAB_XPERMS; |
672 | sattr = flex_array_get(policydb.type_attr_map_array, scontext->type - 1); | 659 | sattr = flex_array_get(policydb->type_attr_map_array, |
660 | scontext->type - 1); | ||
673 | BUG_ON(!sattr); | 661 | BUG_ON(!sattr); |
674 | tattr = flex_array_get(policydb.type_attr_map_array, tcontext->type - 1); | 662 | tattr = flex_array_get(policydb->type_attr_map_array, |
663 | tcontext->type - 1); | ||
675 | BUG_ON(!tattr); | 664 | BUG_ON(!tattr); |
676 | ebitmap_for_each_positive_bit(sattr, snode, i) { | 665 | ebitmap_for_each_positive_bit(sattr, snode, i) { |
677 | ebitmap_for_each_positive_bit(tattr, tnode, j) { | 666 | ebitmap_for_each_positive_bit(tattr, tnode, j) { |
678 | avkey.source_type = i + 1; | 667 | avkey.source_type = i + 1; |
679 | avkey.target_type = j + 1; | 668 | avkey.target_type = j + 1; |
680 | for (node = avtab_search_node(&policydb.te_avtab, &avkey); | 669 | for (node = avtab_search_node(&policydb->te_avtab, |
670 | &avkey); | ||
681 | node; | 671 | node; |
682 | node = avtab_search_node_next(node, avkey.specified)) { | 672 | node = avtab_search_node_next(node, avkey.specified)) { |
683 | if (node->key.specified == AVTAB_ALLOWED) | 673 | if (node->key.specified == AVTAB_ALLOWED) |
@@ -691,7 +681,7 @@ static void context_struct_compute_av(struct context *scontext, | |||
691 | } | 681 | } |
692 | 682 | ||
693 | /* Check conditional av table for additional permissions */ | 683 | /* Check conditional av table for additional permissions */ |
694 | cond_compute_av(&policydb.te_cond_avtab, &avkey, | 684 | cond_compute_av(&policydb->te_cond_avtab, &avkey, |
695 | avd, xperms); | 685 | avd, xperms); |
696 | 686 | ||
697 | } | 687 | } |
@@ -704,7 +694,7 @@ static void context_struct_compute_av(struct context *scontext, | |||
704 | constraint = tclass_datum->constraints; | 694 | constraint = tclass_datum->constraints; |
705 | while (constraint) { | 695 | while (constraint) { |
706 | if ((constraint->permissions & (avd->allowed)) && | 696 | if ((constraint->permissions & (avd->allowed)) && |
707 | !constraint_expr_eval(scontext, tcontext, NULL, | 697 | !constraint_expr_eval(policydb, scontext, tcontext, NULL, |
708 | constraint->expr)) { | 698 | constraint->expr)) { |
709 | avd->allowed &= ~(constraint->permissions); | 699 | avd->allowed &= ~(constraint->permissions); |
710 | } | 700 | } |
@@ -716,16 +706,16 @@ static void context_struct_compute_av(struct context *scontext, | |||
716 | * role is changing, then check the (current_role, new_role) | 706 | * role is changing, then check the (current_role, new_role) |
717 | * pair. | 707 | * pair. |
718 | */ | 708 | */ |
719 | if (tclass == policydb.process_class && | 709 | if (tclass == policydb->process_class && |
720 | (avd->allowed & policydb.process_trans_perms) && | 710 | (avd->allowed & policydb->process_trans_perms) && |
721 | scontext->role != tcontext->role) { | 711 | scontext->role != tcontext->role) { |
722 | for (ra = policydb.role_allow; ra; ra = ra->next) { | 712 | for (ra = policydb->role_allow; ra; ra = ra->next) { |
723 | if (scontext->role == ra->role && | 713 | if (scontext->role == ra->role && |
724 | tcontext->role == ra->new_role) | 714 | tcontext->role == ra->new_role) |
725 | break; | 715 | break; |
726 | } | 716 | } |
727 | if (!ra) | 717 | if (!ra) |
728 | avd->allowed &= ~policydb.process_trans_perms; | 718 | avd->allowed &= ~policydb->process_trans_perms; |
729 | } | 719 | } |
730 | 720 | ||
731 | /* | 721 | /* |
@@ -733,41 +723,46 @@ static void context_struct_compute_av(struct context *scontext, | |||
733 | * constraint, lazy checks have to mask any violated | 723 | * constraint, lazy checks have to mask any violated |
734 | * permission and notice it to userspace via audit. | 724 | * permission and notice it to userspace via audit. |
735 | */ | 725 | */ |
736 | type_attribute_bounds_av(scontext, tcontext, | 726 | type_attribute_bounds_av(policydb, scontext, tcontext, |
737 | tclass, avd); | 727 | tclass, avd); |
738 | } | 728 | } |
739 | 729 | ||
740 | static int security_validtrans_handle_fail(struct context *ocontext, | 730 | static int security_validtrans_handle_fail(struct selinux_state *state, |
731 | struct context *ocontext, | ||
741 | struct context *ncontext, | 732 | struct context *ncontext, |
742 | struct context *tcontext, | 733 | struct context *tcontext, |
743 | u16 tclass) | 734 | u16 tclass) |
744 | { | 735 | { |
736 | struct policydb *p = &state->ss->policydb; | ||
745 | char *o = NULL, *n = NULL, *t = NULL; | 737 | char *o = NULL, *n = NULL, *t = NULL; |
746 | u32 olen, nlen, tlen; | 738 | u32 olen, nlen, tlen; |
747 | 739 | ||
748 | if (context_struct_to_string(ocontext, &o, &olen)) | 740 | if (context_struct_to_string(p, ocontext, &o, &olen)) |
749 | goto out; | 741 | goto out; |
750 | if (context_struct_to_string(ncontext, &n, &nlen)) | 742 | if (context_struct_to_string(p, ncontext, &n, &nlen)) |
751 | goto out; | 743 | goto out; |
752 | if (context_struct_to_string(tcontext, &t, &tlen)) | 744 | if (context_struct_to_string(p, tcontext, &t, &tlen)) |
753 | goto out; | 745 | goto out; |
754 | audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, | 746 | audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, |
755 | "op=security_validate_transition seresult=denied" | 747 | "op=security_validate_transition seresult=denied" |
756 | " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s", | 748 | " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s", |
757 | o, n, t, sym_name(&policydb, SYM_CLASSES, tclass-1)); | 749 | o, n, t, sym_name(p, SYM_CLASSES, tclass-1)); |
758 | out: | 750 | out: |
759 | kfree(o); | 751 | kfree(o); |
760 | kfree(n); | 752 | kfree(n); |
761 | kfree(t); | 753 | kfree(t); |
762 | 754 | ||
763 | if (!selinux_enforcing) | 755 | if (!is_enforcing(state)) |
764 | return 0; | 756 | return 0; |
765 | return -EPERM; | 757 | return -EPERM; |
766 | } | 758 | } |
767 | 759 | ||
768 | static int security_compute_validatetrans(u32 oldsid, u32 newsid, u32 tasksid, | 760 | static int security_compute_validatetrans(struct selinux_state *state, |
761 | u32 oldsid, u32 newsid, u32 tasksid, | ||
769 | u16 orig_tclass, bool user) | 762 | u16 orig_tclass, bool user) |
770 | { | 763 | { |
764 | struct policydb *policydb; | ||
765 | struct sidtab *sidtab; | ||
771 | struct context *ocontext; | 766 | struct context *ocontext; |
772 | struct context *ncontext; | 767 | struct context *ncontext; |
773 | struct context *tcontext; | 768 | struct context *tcontext; |
@@ -776,23 +771,27 @@ static int security_compute_validatetrans(u32 oldsid, u32 newsid, u32 tasksid, | |||
776 | u16 tclass; | 771 | u16 tclass; |
777 | int rc = 0; | 772 | int rc = 0; |
778 | 773 | ||
779 | if (!ss_initialized) | 774 | |
775 | if (!state->initialized) | ||
780 | return 0; | 776 | return 0; |
781 | 777 | ||
782 | read_lock(&policy_rwlock); | 778 | read_lock(&state->ss->policy_rwlock); |
779 | |||
780 | policydb = &state->ss->policydb; | ||
781 | sidtab = &state->ss->sidtab; | ||
783 | 782 | ||
784 | if (!user) | 783 | if (!user) |
785 | tclass = unmap_class(orig_tclass); | 784 | tclass = unmap_class(&state->ss->map, orig_tclass); |
786 | else | 785 | else |
787 | tclass = orig_tclass; | 786 | tclass = orig_tclass; |
788 | 787 | ||
789 | if (!tclass || tclass > policydb.p_classes.nprim) { | 788 | if (!tclass || tclass > policydb->p_classes.nprim) { |
790 | rc = -EINVAL; | 789 | rc = -EINVAL; |
791 | goto out; | 790 | goto out; |
792 | } | 791 | } |
793 | tclass_datum = policydb.class_val_to_struct[tclass - 1]; | 792 | tclass_datum = policydb->class_val_to_struct[tclass - 1]; |
794 | 793 | ||
795 | ocontext = sidtab_search(&sidtab, oldsid); | 794 | ocontext = sidtab_search(sidtab, oldsid); |
796 | if (!ocontext) { | 795 | if (!ocontext) { |
797 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 796 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
798 | __func__, oldsid); | 797 | __func__, oldsid); |
@@ -800,7 +799,7 @@ static int security_compute_validatetrans(u32 oldsid, u32 newsid, u32 tasksid, | |||
800 | goto out; | 799 | goto out; |
801 | } | 800 | } |
802 | 801 | ||
803 | ncontext = sidtab_search(&sidtab, newsid); | 802 | ncontext = sidtab_search(sidtab, newsid); |
804 | if (!ncontext) { | 803 | if (!ncontext) { |
805 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 804 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
806 | __func__, newsid); | 805 | __func__, newsid); |
@@ -808,7 +807,7 @@ static int security_compute_validatetrans(u32 oldsid, u32 newsid, u32 tasksid, | |||
808 | goto out; | 807 | goto out; |
809 | } | 808 | } |
810 | 809 | ||
811 | tcontext = sidtab_search(&sidtab, tasksid); | 810 | tcontext = sidtab_search(sidtab, tasksid); |
812 | if (!tcontext) { | 811 | if (!tcontext) { |
813 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 812 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
814 | __func__, tasksid); | 813 | __func__, tasksid); |
@@ -818,12 +817,13 @@ static int security_compute_validatetrans(u32 oldsid, u32 newsid, u32 tasksid, | |||
818 | 817 | ||
819 | constraint = tclass_datum->validatetrans; | 818 | constraint = tclass_datum->validatetrans; |
820 | while (constraint) { | 819 | while (constraint) { |
821 | if (!constraint_expr_eval(ocontext, ncontext, tcontext, | 820 | if (!constraint_expr_eval(policydb, ocontext, ncontext, |
822 | constraint->expr)) { | 821 | tcontext, constraint->expr)) { |
823 | if (user) | 822 | if (user) |
824 | rc = -EPERM; | 823 | rc = -EPERM; |
825 | else | 824 | else |
826 | rc = security_validtrans_handle_fail(ocontext, | 825 | rc = security_validtrans_handle_fail(state, |
826 | ocontext, | ||
827 | ncontext, | 827 | ncontext, |
828 | tcontext, | 828 | tcontext, |
829 | tclass); | 829 | tclass); |
@@ -833,22 +833,24 @@ static int security_compute_validatetrans(u32 oldsid, u32 newsid, u32 tasksid, | |||
833 | } | 833 | } |
834 | 834 | ||
835 | out: | 835 | out: |
836 | read_unlock(&policy_rwlock); | 836 | read_unlock(&state->ss->policy_rwlock); |
837 | return rc; | 837 | return rc; |
838 | } | 838 | } |
839 | 839 | ||
840 | int security_validate_transition_user(u32 oldsid, u32 newsid, u32 tasksid, | 840 | int security_validate_transition_user(struct selinux_state *state, |
841 | u16 tclass) | 841 | u32 oldsid, u32 newsid, u32 tasksid, |
842 | u16 tclass) | ||
842 | { | 843 | { |
843 | return security_compute_validatetrans(oldsid, newsid, tasksid, | 844 | return security_compute_validatetrans(state, oldsid, newsid, tasksid, |
844 | tclass, true); | 845 | tclass, true); |
845 | } | 846 | } |
846 | 847 | ||
847 | int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, | 848 | int security_validate_transition(struct selinux_state *state, |
849 | u32 oldsid, u32 newsid, u32 tasksid, | ||
848 | u16 orig_tclass) | 850 | u16 orig_tclass) |
849 | { | 851 | { |
850 | return security_compute_validatetrans(oldsid, newsid, tasksid, | 852 | return security_compute_validatetrans(state, oldsid, newsid, tasksid, |
851 | orig_tclass, false); | 853 | orig_tclass, false); |
852 | } | 854 | } |
853 | 855 | ||
854 | /* | 856 | /* |
@@ -860,20 +862,26 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, | |||
860 | * @oldsid : current security identifier | 862 | * @oldsid : current security identifier |
861 | * @newsid : destinated security identifier | 863 | * @newsid : destinated security identifier |
862 | */ | 864 | */ |
863 | int security_bounded_transition(u32 old_sid, u32 new_sid) | 865 | int security_bounded_transition(struct selinux_state *state, |
866 | u32 old_sid, u32 new_sid) | ||
864 | { | 867 | { |
868 | struct policydb *policydb; | ||
869 | struct sidtab *sidtab; | ||
865 | struct context *old_context, *new_context; | 870 | struct context *old_context, *new_context; |
866 | struct type_datum *type; | 871 | struct type_datum *type; |
867 | int index; | 872 | int index; |
868 | int rc; | 873 | int rc; |
869 | 874 | ||
870 | if (!ss_initialized) | 875 | if (!state->initialized) |
871 | return 0; | 876 | return 0; |
872 | 877 | ||
873 | read_lock(&policy_rwlock); | 878 | read_lock(&state->ss->policy_rwlock); |
879 | |||
880 | policydb = &state->ss->policydb; | ||
881 | sidtab = &state->ss->sidtab; | ||
874 | 882 | ||
875 | rc = -EINVAL; | 883 | rc = -EINVAL; |
876 | old_context = sidtab_search(&sidtab, old_sid); | 884 | old_context = sidtab_search(sidtab, old_sid); |
877 | if (!old_context) { | 885 | if (!old_context) { |
878 | printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", | 886 | printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", |
879 | __func__, old_sid); | 887 | __func__, old_sid); |
@@ -881,7 +889,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid) | |||
881 | } | 889 | } |
882 | 890 | ||
883 | rc = -EINVAL; | 891 | rc = -EINVAL; |
884 | new_context = sidtab_search(&sidtab, new_sid); | 892 | new_context = sidtab_search(sidtab, new_sid); |
885 | if (!new_context) { | 893 | if (!new_context) { |
886 | printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", | 894 | printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", |
887 | __func__, new_sid); | 895 | __func__, new_sid); |
@@ -895,7 +903,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid) | |||
895 | 903 | ||
896 | index = new_context->type; | 904 | index = new_context->type; |
897 | while (true) { | 905 | while (true) { |
898 | type = flex_array_get_ptr(policydb.type_val_to_struct_array, | 906 | type = flex_array_get_ptr(policydb->type_val_to_struct_array, |
899 | index - 1); | 907 | index - 1); |
900 | BUG_ON(!type); | 908 | BUG_ON(!type); |
901 | 909 | ||
@@ -917,9 +925,9 @@ int security_bounded_transition(u32 old_sid, u32 new_sid) | |||
917 | char *new_name = NULL; | 925 | char *new_name = NULL; |
918 | u32 length; | 926 | u32 length; |
919 | 927 | ||
920 | if (!context_struct_to_string(old_context, | 928 | if (!context_struct_to_string(policydb, old_context, |
921 | &old_name, &length) && | 929 | &old_name, &length) && |
922 | !context_struct_to_string(new_context, | 930 | !context_struct_to_string(policydb, new_context, |
923 | &new_name, &length)) { | 931 | &new_name, &length)) { |
924 | audit_log(current->audit_context, | 932 | audit_log(current->audit_context, |
925 | GFP_ATOMIC, AUDIT_SELINUX_ERR, | 933 | GFP_ATOMIC, AUDIT_SELINUX_ERR, |
@@ -932,17 +940,17 @@ int security_bounded_transition(u32 old_sid, u32 new_sid) | |||
932 | kfree(old_name); | 940 | kfree(old_name); |
933 | } | 941 | } |
934 | out: | 942 | out: |
935 | read_unlock(&policy_rwlock); | 943 | read_unlock(&state->ss->policy_rwlock); |
936 | 944 | ||
937 | return rc; | 945 | return rc; |
938 | } | 946 | } |
939 | 947 | ||
940 | static void avd_init(struct av_decision *avd) | 948 | static void avd_init(struct selinux_state *state, struct av_decision *avd) |
941 | { | 949 | { |
942 | avd->allowed = 0; | 950 | avd->allowed = 0; |
943 | avd->auditallow = 0; | 951 | avd->auditallow = 0; |
944 | avd->auditdeny = 0xffffffff; | 952 | avd->auditdeny = 0xffffffff; |
945 | avd->seqno = latest_granting; | 953 | avd->seqno = state->ss->latest_granting; |
946 | avd->flags = 0; | 954 | avd->flags = 0; |
947 | } | 955 | } |
948 | 956 | ||
@@ -1000,12 +1008,15 @@ void services_compute_xperms_decision(struct extended_perms_decision *xpermd, | |||
1000 | } | 1008 | } |
1001 | } | 1009 | } |
1002 | 1010 | ||
1003 | void security_compute_xperms_decision(u32 ssid, | 1011 | void security_compute_xperms_decision(struct selinux_state *state, |
1004 | u32 tsid, | 1012 | u32 ssid, |
1005 | u16 orig_tclass, | 1013 | u32 tsid, |
1006 | u8 driver, | 1014 | u16 orig_tclass, |
1007 | struct extended_perms_decision *xpermd) | 1015 | u8 driver, |
1016 | struct extended_perms_decision *xpermd) | ||
1008 | { | 1017 | { |
1018 | struct policydb *policydb; | ||
1019 | struct sidtab *sidtab; | ||
1009 | u16 tclass; | 1020 | u16 tclass; |
1010 | struct context *scontext, *tcontext; | 1021 | struct context *scontext, *tcontext; |
1011 | struct avtab_key avkey; | 1022 | struct avtab_key avkey; |
@@ -1020,60 +1031,64 @@ void security_compute_xperms_decision(u32 ssid, | |||
1020 | memset(xpermd->auditallow->p, 0, sizeof(xpermd->auditallow->p)); | 1031 | memset(xpermd->auditallow->p, 0, sizeof(xpermd->auditallow->p)); |
1021 | memset(xpermd->dontaudit->p, 0, sizeof(xpermd->dontaudit->p)); | 1032 | memset(xpermd->dontaudit->p, 0, sizeof(xpermd->dontaudit->p)); |
1022 | 1033 | ||
1023 | read_lock(&policy_rwlock); | 1034 | read_lock(&state->ss->policy_rwlock); |
1024 | if (!ss_initialized) | 1035 | if (!state->initialized) |
1025 | goto allow; | 1036 | goto allow; |
1026 | 1037 | ||
1027 | scontext = sidtab_search(&sidtab, ssid); | 1038 | policydb = &state->ss->policydb; |
1039 | sidtab = &state->ss->sidtab; | ||
1040 | |||
1041 | scontext = sidtab_search(sidtab, ssid); | ||
1028 | if (!scontext) { | 1042 | if (!scontext) { |
1029 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 1043 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
1030 | __func__, ssid); | 1044 | __func__, ssid); |
1031 | goto out; | 1045 | goto out; |
1032 | } | 1046 | } |
1033 | 1047 | ||
1034 | tcontext = sidtab_search(&sidtab, tsid); | 1048 | tcontext = sidtab_search(sidtab, tsid); |
1035 | if (!tcontext) { | 1049 | if (!tcontext) { |
1036 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 1050 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
1037 | __func__, tsid); | 1051 | __func__, tsid); |
1038 | goto out; | 1052 | goto out; |
1039 | } | 1053 | } |
1040 | 1054 | ||
1041 | tclass = unmap_class(orig_tclass); | 1055 | tclass = unmap_class(&state->ss->map, orig_tclass); |
1042 | if (unlikely(orig_tclass && !tclass)) { | 1056 | if (unlikely(orig_tclass && !tclass)) { |
1043 | if (policydb.allow_unknown) | 1057 | if (policydb->allow_unknown) |
1044 | goto allow; | 1058 | goto allow; |
1045 | goto out; | 1059 | goto out; |
1046 | } | 1060 | } |
1047 | 1061 | ||
1048 | 1062 | ||
1049 | if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) { | 1063 | if (unlikely(!tclass || tclass > policydb->p_classes.nprim)) { |
1050 | pr_warn_ratelimited("SELinux: Invalid class %hu\n", tclass); | 1064 | pr_warn_ratelimited("SELinux: Invalid class %hu\n", tclass); |
1051 | goto out; | 1065 | goto out; |
1052 | } | 1066 | } |
1053 | 1067 | ||
1054 | avkey.target_class = tclass; | 1068 | avkey.target_class = tclass; |
1055 | avkey.specified = AVTAB_XPERMS; | 1069 | avkey.specified = AVTAB_XPERMS; |
1056 | sattr = flex_array_get(policydb.type_attr_map_array, | 1070 | sattr = flex_array_get(policydb->type_attr_map_array, |
1057 | scontext->type - 1); | 1071 | scontext->type - 1); |
1058 | BUG_ON(!sattr); | 1072 | BUG_ON(!sattr); |
1059 | tattr = flex_array_get(policydb.type_attr_map_array, | 1073 | tattr = flex_array_get(policydb->type_attr_map_array, |
1060 | tcontext->type - 1); | 1074 | tcontext->type - 1); |
1061 | BUG_ON(!tattr); | 1075 | BUG_ON(!tattr); |
1062 | ebitmap_for_each_positive_bit(sattr, snode, i) { | 1076 | ebitmap_for_each_positive_bit(sattr, snode, i) { |
1063 | ebitmap_for_each_positive_bit(tattr, tnode, j) { | 1077 | ebitmap_for_each_positive_bit(tattr, tnode, j) { |
1064 | avkey.source_type = i + 1; | 1078 | avkey.source_type = i + 1; |
1065 | avkey.target_type = j + 1; | 1079 | avkey.target_type = j + 1; |
1066 | for (node = avtab_search_node(&policydb.te_avtab, &avkey); | 1080 | for (node = avtab_search_node(&policydb->te_avtab, |
1081 | &avkey); | ||
1067 | node; | 1082 | node; |
1068 | node = avtab_search_node_next(node, avkey.specified)) | 1083 | node = avtab_search_node_next(node, avkey.specified)) |
1069 | services_compute_xperms_decision(xpermd, node); | 1084 | services_compute_xperms_decision(xpermd, node); |
1070 | 1085 | ||
1071 | cond_compute_xperms(&policydb.te_cond_avtab, | 1086 | cond_compute_xperms(&policydb->te_cond_avtab, |
1072 | &avkey, xpermd); | 1087 | &avkey, xpermd); |
1073 | } | 1088 | } |
1074 | } | 1089 | } |
1075 | out: | 1090 | out: |
1076 | read_unlock(&policy_rwlock); | 1091 | read_unlock(&state->ss->policy_rwlock); |
1077 | return; | 1092 | return; |
1078 | allow: | 1093 | allow: |
1079 | memset(xpermd->allowed->p, 0xff, sizeof(xpermd->allowed->p)); | 1094 | memset(xpermd->allowed->p, 0xff, sizeof(xpermd->allowed->p)); |
@@ -1091,22 +1106,28 @@ allow: | |||
1091 | * Compute a set of access vector decisions based on the | 1106 | * Compute a set of access vector decisions based on the |
1092 | * SID pair (@ssid, @tsid) for the permissions in @tclass. | 1107 | * SID pair (@ssid, @tsid) for the permissions in @tclass. |
1093 | */ | 1108 | */ |
1094 | void security_compute_av(u32 ssid, | 1109 | void security_compute_av(struct selinux_state *state, |
1110 | u32 ssid, | ||
1095 | u32 tsid, | 1111 | u32 tsid, |
1096 | u16 orig_tclass, | 1112 | u16 orig_tclass, |
1097 | struct av_decision *avd, | 1113 | struct av_decision *avd, |
1098 | struct extended_perms *xperms) | 1114 | struct extended_perms *xperms) |
1099 | { | 1115 | { |
1116 | struct policydb *policydb; | ||
1117 | struct sidtab *sidtab; | ||
1100 | u16 tclass; | 1118 | u16 tclass; |
1101 | struct context *scontext = NULL, *tcontext = NULL; | 1119 | struct context *scontext = NULL, *tcontext = NULL; |
1102 | 1120 | ||
1103 | read_lock(&policy_rwlock); | 1121 | read_lock(&state->ss->policy_rwlock); |
1104 | avd_init(avd); | 1122 | avd_init(state, avd); |
1105 | xperms->len = 0; | 1123 | xperms->len = 0; |
1106 | if (!ss_initialized) | 1124 | if (!state->initialized) |
1107 | goto allow; | 1125 | goto allow; |
1108 | 1126 | ||
1109 | scontext = sidtab_search(&sidtab, ssid); | 1127 | policydb = &state->ss->policydb; |
1128 | sidtab = &state->ss->sidtab; | ||
1129 | |||
1130 | scontext = sidtab_search(sidtab, ssid); | ||
1110 | if (!scontext) { | 1131 | if (!scontext) { |
1111 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 1132 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
1112 | __func__, ssid); | 1133 | __func__, ssid); |
@@ -1114,45 +1135,53 @@ void security_compute_av(u32 ssid, | |||
1114 | } | 1135 | } |
1115 | 1136 | ||
1116 | /* permissive domain? */ | 1137 | /* permissive domain? */ |
1117 | if (ebitmap_get_bit(&policydb.permissive_map, scontext->type)) | 1138 | if (ebitmap_get_bit(&policydb->permissive_map, scontext->type)) |
1118 | avd->flags |= AVD_FLAGS_PERMISSIVE; | 1139 | avd->flags |= AVD_FLAGS_PERMISSIVE; |
1119 | 1140 | ||
1120 | tcontext = sidtab_search(&sidtab, tsid); | 1141 | tcontext = sidtab_search(sidtab, tsid); |
1121 | if (!tcontext) { | 1142 | if (!tcontext) { |
1122 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 1143 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
1123 | __func__, tsid); | 1144 | __func__, tsid); |
1124 | goto out; | 1145 | goto out; |
1125 | } | 1146 | } |
1126 | 1147 | ||
1127 | tclass = unmap_class(orig_tclass); | 1148 | tclass = unmap_class(&state->ss->map, orig_tclass); |
1128 | if (unlikely(orig_tclass && !tclass)) { | 1149 | if (unlikely(orig_tclass && !tclass)) { |
1129 | if (policydb.allow_unknown) | 1150 | if (policydb->allow_unknown) |
1130 | goto allow; | 1151 | goto allow; |
1131 | goto out; | 1152 | goto out; |
1132 | } | 1153 | } |
1133 | context_struct_compute_av(scontext, tcontext, tclass, avd, xperms); | 1154 | context_struct_compute_av(policydb, scontext, tcontext, tclass, avd, |
1134 | map_decision(orig_tclass, avd, policydb.allow_unknown); | 1155 | xperms); |
1156 | map_decision(&state->ss->map, orig_tclass, avd, | ||
1157 | policydb->allow_unknown); | ||
1135 | out: | 1158 | out: |
1136 | read_unlock(&policy_rwlock); | 1159 | read_unlock(&state->ss->policy_rwlock); |
1137 | return; | 1160 | return; |
1138 | allow: | 1161 | allow: |
1139 | avd->allowed = 0xffffffff; | 1162 | avd->allowed = 0xffffffff; |
1140 | goto out; | 1163 | goto out; |
1141 | } | 1164 | } |
1142 | 1165 | ||
1143 | void security_compute_av_user(u32 ssid, | 1166 | void security_compute_av_user(struct selinux_state *state, |
1167 | u32 ssid, | ||
1144 | u32 tsid, | 1168 | u32 tsid, |
1145 | u16 tclass, | 1169 | u16 tclass, |
1146 | struct av_decision *avd) | 1170 | struct av_decision *avd) |
1147 | { | 1171 | { |
1172 | struct policydb *policydb; | ||
1173 | struct sidtab *sidtab; | ||
1148 | struct context *scontext = NULL, *tcontext = NULL; | 1174 | struct context *scontext = NULL, *tcontext = NULL; |
1149 | 1175 | ||
1150 | read_lock(&policy_rwlock); | 1176 | read_lock(&state->ss->policy_rwlock); |
1151 | avd_init(avd); | 1177 | avd_init(state, avd); |
1152 | if (!ss_initialized) | 1178 | if (!state->initialized) |
1153 | goto allow; | 1179 | goto allow; |
1154 | 1180 | ||
1155 | scontext = sidtab_search(&sidtab, ssid); | 1181 | policydb = &state->ss->policydb; |
1182 | sidtab = &state->ss->sidtab; | ||
1183 | |||
1184 | scontext = sidtab_search(sidtab, ssid); | ||
1156 | if (!scontext) { | 1185 | if (!scontext) { |
1157 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 1186 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
1158 | __func__, ssid); | 1187 | __func__, ssid); |
@@ -1160,10 +1189,10 @@ void security_compute_av_user(u32 ssid, | |||
1160 | } | 1189 | } |
1161 | 1190 | ||
1162 | /* permissive domain? */ | 1191 | /* permissive domain? */ |
1163 | if (ebitmap_get_bit(&policydb.permissive_map, scontext->type)) | 1192 | if (ebitmap_get_bit(&policydb->permissive_map, scontext->type)) |
1164 | avd->flags |= AVD_FLAGS_PERMISSIVE; | 1193 | avd->flags |= AVD_FLAGS_PERMISSIVE; |
1165 | 1194 | ||
1166 | tcontext = sidtab_search(&sidtab, tsid); | 1195 | tcontext = sidtab_search(sidtab, tsid); |
1167 | if (!tcontext) { | 1196 | if (!tcontext) { |
1168 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 1197 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
1169 | __func__, tsid); | 1198 | __func__, tsid); |
@@ -1171,14 +1200,15 @@ void security_compute_av_user(u32 ssid, | |||
1171 | } | 1200 | } |
1172 | 1201 | ||
1173 | if (unlikely(!tclass)) { | 1202 | if (unlikely(!tclass)) { |
1174 | if (policydb.allow_unknown) | 1203 | if (policydb->allow_unknown) |
1175 | goto allow; | 1204 | goto allow; |
1176 | goto out; | 1205 | goto out; |
1177 | } | 1206 | } |
1178 | 1207 | ||
1179 | context_struct_compute_av(scontext, tcontext, tclass, avd, NULL); | 1208 | context_struct_compute_av(policydb, scontext, tcontext, tclass, avd, |
1209 | NULL); | ||
1180 | out: | 1210 | out: |
1181 | read_unlock(&policy_rwlock); | 1211 | read_unlock(&state->ss->policy_rwlock); |
1182 | return; | 1212 | return; |
1183 | allow: | 1213 | allow: |
1184 | avd->allowed = 0xffffffff; | 1214 | avd->allowed = 0xffffffff; |
@@ -1192,7 +1222,9 @@ allow: | |||
1192 | * to point to this string and set `*scontext_len' to | 1222 | * to point to this string and set `*scontext_len' to |
1193 | * the length of the string. | 1223 | * the length of the string. |
1194 | */ | 1224 | */ |
1195 | static int context_struct_to_string(struct context *context, char **scontext, u32 *scontext_len) | 1225 | static int context_struct_to_string(struct policydb *p, |
1226 | struct context *context, | ||
1227 | char **scontext, u32 *scontext_len) | ||
1196 | { | 1228 | { |
1197 | char *scontextp; | 1229 | char *scontextp; |
1198 | 1230 | ||
@@ -1211,10 +1243,10 @@ static int context_struct_to_string(struct context *context, char **scontext, u3 | |||
1211 | } | 1243 | } |
1212 | 1244 | ||
1213 | /* Compute the size of the context. */ | 1245 | /* Compute the size of the context. */ |
1214 | *scontext_len += strlen(sym_name(&policydb, SYM_USERS, context->user - 1)) + 1; | 1246 | *scontext_len += strlen(sym_name(p, SYM_USERS, context->user - 1)) + 1; |
1215 | *scontext_len += strlen(sym_name(&policydb, SYM_ROLES, context->role - 1)) + 1; | 1247 | *scontext_len += strlen(sym_name(p, SYM_ROLES, context->role - 1)) + 1; |
1216 | *scontext_len += strlen(sym_name(&policydb, SYM_TYPES, context->type - 1)) + 1; | 1248 | *scontext_len += strlen(sym_name(p, SYM_TYPES, context->type - 1)) + 1; |
1217 | *scontext_len += mls_compute_context_len(context); | 1249 | *scontext_len += mls_compute_context_len(p, context); |
1218 | 1250 | ||
1219 | if (!scontext) | 1251 | if (!scontext) |
1220 | return 0; | 1252 | return 0; |
@@ -1229,11 +1261,11 @@ static int context_struct_to_string(struct context *context, char **scontext, u3 | |||
1229 | * Copy the user name, role name and type name into the context. | 1261 | * Copy the user name, role name and type name into the context. |
1230 | */ | 1262 | */ |
1231 | scontextp += sprintf(scontextp, "%s:%s:%s", | 1263 | scontextp += sprintf(scontextp, "%s:%s:%s", |
1232 | sym_name(&policydb, SYM_USERS, context->user - 1), | 1264 | sym_name(p, SYM_USERS, context->user - 1), |
1233 | sym_name(&policydb, SYM_ROLES, context->role - 1), | 1265 | sym_name(p, SYM_ROLES, context->role - 1), |
1234 | sym_name(&policydb, SYM_TYPES, context->type - 1)); | 1266 | sym_name(p, SYM_TYPES, context->type - 1)); |
1235 | 1267 | ||
1236 | mls_sid_to_context(context, &scontextp); | 1268 | mls_sid_to_context(p, context, &scontextp); |
1237 | 1269 | ||
1238 | *scontextp = 0; | 1270 | *scontextp = 0; |
1239 | 1271 | ||
@@ -1249,9 +1281,12 @@ const char *security_get_initial_sid_context(u32 sid) | |||
1249 | return initial_sid_to_string[sid]; | 1281 | return initial_sid_to_string[sid]; |
1250 | } | 1282 | } |
1251 | 1283 | ||
1252 | static int security_sid_to_context_core(u32 sid, char **scontext, | 1284 | static int security_sid_to_context_core(struct selinux_state *state, |
1285 | u32 sid, char **scontext, | ||
1253 | u32 *scontext_len, int force) | 1286 | u32 *scontext_len, int force) |
1254 | { | 1287 | { |
1288 | struct policydb *policydb; | ||
1289 | struct sidtab *sidtab; | ||
1255 | struct context *context; | 1290 | struct context *context; |
1256 | int rc = 0; | 1291 | int rc = 0; |
1257 | 1292 | ||
@@ -1259,7 +1294,7 @@ static int security_sid_to_context_core(u32 sid, char **scontext, | |||
1259 | *scontext = NULL; | 1294 | *scontext = NULL; |
1260 | *scontext_len = 0; | 1295 | *scontext_len = 0; |
1261 | 1296 | ||
1262 | if (!ss_initialized) { | 1297 | if (!state->initialized) { |
1263 | if (sid <= SECINITSID_NUM) { | 1298 | if (sid <= SECINITSID_NUM) { |
1264 | char *scontextp; | 1299 | char *scontextp; |
1265 | 1300 | ||
@@ -1280,20 +1315,23 @@ static int security_sid_to_context_core(u32 sid, char **scontext, | |||
1280 | rc = -EINVAL; | 1315 | rc = -EINVAL; |
1281 | goto out; | 1316 | goto out; |
1282 | } | 1317 | } |
1283 | read_lock(&policy_rwlock); | 1318 | read_lock(&state->ss->policy_rwlock); |
1319 | policydb = &state->ss->policydb; | ||
1320 | sidtab = &state->ss->sidtab; | ||
1284 | if (force) | 1321 | if (force) |
1285 | context = sidtab_search_force(&sidtab, sid); | 1322 | context = sidtab_search_force(sidtab, sid); |
1286 | else | 1323 | else |
1287 | context = sidtab_search(&sidtab, sid); | 1324 | context = sidtab_search(sidtab, sid); |
1288 | if (!context) { | 1325 | if (!context) { |
1289 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 1326 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
1290 | __func__, sid); | 1327 | __func__, sid); |
1291 | rc = -EINVAL; | 1328 | rc = -EINVAL; |
1292 | goto out_unlock; | 1329 | goto out_unlock; |
1293 | } | 1330 | } |
1294 | rc = context_struct_to_string(context, scontext, scontext_len); | 1331 | rc = context_struct_to_string(policydb, context, scontext, |
1332 | scontext_len); | ||
1295 | out_unlock: | 1333 | out_unlock: |
1296 | read_unlock(&policy_rwlock); | 1334 | read_unlock(&state->ss->policy_rwlock); |
1297 | out: | 1335 | out: |
1298 | return rc; | 1336 | return rc; |
1299 | 1337 | ||
@@ -1309,14 +1347,18 @@ out: | |||
1309 | * into a dynamically allocated string of the correct size. Set @scontext | 1347 | * into a dynamically allocated string of the correct size. Set @scontext |
1310 | * to point to this string and set @scontext_len to the length of the string. | 1348 | * to point to this string and set @scontext_len to the length of the string. |
1311 | */ | 1349 | */ |
1312 | int security_sid_to_context(u32 sid, char **scontext, u32 *scontext_len) | 1350 | int security_sid_to_context(struct selinux_state *state, |
1351 | u32 sid, char **scontext, u32 *scontext_len) | ||
1313 | { | 1352 | { |
1314 | return security_sid_to_context_core(sid, scontext, scontext_len, 0); | 1353 | return security_sid_to_context_core(state, sid, scontext, |
1354 | scontext_len, 0); | ||
1315 | } | 1355 | } |
1316 | 1356 | ||
1317 | int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len) | 1357 | int security_sid_to_context_force(struct selinux_state *state, u32 sid, |
1358 | char **scontext, u32 *scontext_len) | ||
1318 | { | 1359 | { |
1319 | return security_sid_to_context_core(sid, scontext, scontext_len, 1); | 1360 | return security_sid_to_context_core(state, sid, scontext, |
1361 | scontext_len, 1); | ||
1320 | } | 1362 | } |
1321 | 1363 | ||
1322 | /* | 1364 | /* |
@@ -1404,10 +1446,13 @@ out: | |||
1404 | return rc; | 1446 | return rc; |
1405 | } | 1447 | } |
1406 | 1448 | ||
1407 | static int security_context_to_sid_core(const char *scontext, u32 scontext_len, | 1449 | static int security_context_to_sid_core(struct selinux_state *state, |
1450 | const char *scontext, u32 scontext_len, | ||
1408 | u32 *sid, u32 def_sid, gfp_t gfp_flags, | 1451 | u32 *sid, u32 def_sid, gfp_t gfp_flags, |
1409 | int force) | 1452 | int force) |
1410 | { | 1453 | { |
1454 | struct policydb *policydb; | ||
1455 | struct sidtab *sidtab; | ||
1411 | char *scontext2, *str = NULL; | 1456 | char *scontext2, *str = NULL; |
1412 | struct context context; | 1457 | struct context context; |
1413 | int rc = 0; | 1458 | int rc = 0; |
@@ -1421,7 +1466,7 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, | |||
1421 | if (!scontext2) | 1466 | if (!scontext2) |
1422 | return -ENOMEM; | 1467 | return -ENOMEM; |
1423 | 1468 | ||
1424 | if (!ss_initialized) { | 1469 | if (!state->initialized) { |
1425 | int i; | 1470 | int i; |
1426 | 1471 | ||
1427 | for (i = 1; i < SECINITSID_NUM; i++) { | 1472 | for (i = 1; i < SECINITSID_NUM; i++) { |
@@ -1442,9 +1487,10 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, | |||
1442 | if (!str) | 1487 | if (!str) |
1443 | goto out; | 1488 | goto out; |
1444 | } | 1489 | } |
1445 | 1490 | read_lock(&state->ss->policy_rwlock); | |
1446 | read_lock(&policy_rwlock); | 1491 | policydb = &state->ss->policydb; |
1447 | rc = string_to_context_struct(&policydb, &sidtab, scontext2, | 1492 | sidtab = &state->ss->sidtab; |
1493 | rc = string_to_context_struct(policydb, sidtab, scontext2, | ||
1448 | scontext_len, &context, def_sid); | 1494 | scontext_len, &context, def_sid); |
1449 | if (rc == -EINVAL && force) { | 1495 | if (rc == -EINVAL && force) { |
1450 | context.str = str; | 1496 | context.str = str; |
@@ -1452,10 +1498,10 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len, | |||
1452 | str = NULL; | 1498 | str = NULL; |
1453 | } else if (rc) | 1499 | } else if (rc) |
1454 | goto out_unlock; | 1500 | goto out_unlock; |
1455 | rc = sidtab_context_to_sid(&sidtab, &context, sid); | 1501 | rc = sidtab_context_to_sid(sidtab, &context, sid); |
1456 | context_destroy(&context); | 1502 | context_destroy(&context); |
1457 | out_unlock: | 1503 | out_unlock: |
1458 | read_unlock(&policy_rwlock); | 1504 | read_unlock(&state->ss->policy_rwlock); |
1459 | out: | 1505 | out: |
1460 | kfree(scontext2); | 1506 | kfree(scontext2); |
1461 | kfree(str); | 1507 | kfree(str); |
@@ -1474,16 +1520,19 @@ out: | |||
1474 | * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient | 1520 | * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient |
1475 | * memory is available, or 0 on success. | 1521 | * memory is available, or 0 on success. |
1476 | */ | 1522 | */ |
1477 | int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid, | 1523 | int security_context_to_sid(struct selinux_state *state, |
1524 | const char *scontext, u32 scontext_len, u32 *sid, | ||
1478 | gfp_t gfp) | 1525 | gfp_t gfp) |
1479 | { | 1526 | { |
1480 | return security_context_to_sid_core(scontext, scontext_len, | 1527 | return security_context_to_sid_core(state, scontext, scontext_len, |
1481 | sid, SECSID_NULL, gfp, 0); | 1528 | sid, SECSID_NULL, gfp, 0); |
1482 | } | 1529 | } |
1483 | 1530 | ||
1484 | int security_context_str_to_sid(const char *scontext, u32 *sid, gfp_t gfp) | 1531 | int security_context_str_to_sid(struct selinux_state *state, |
1532 | const char *scontext, u32 *sid, gfp_t gfp) | ||
1485 | { | 1533 | { |
1486 | return security_context_to_sid(scontext, strlen(scontext), sid, gfp); | 1534 | return security_context_to_sid(state, scontext, strlen(scontext), |
1535 | sid, gfp); | ||
1487 | } | 1536 | } |
1488 | 1537 | ||
1489 | /** | 1538 | /** |
@@ -1504,51 +1553,56 @@ int security_context_str_to_sid(const char *scontext, u32 *sid, gfp_t gfp) | |||
1504 | * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient | 1553 | * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient |
1505 | * memory is available, or 0 on success. | 1554 | * memory is available, or 0 on success. |
1506 | */ | 1555 | */ |
1507 | int security_context_to_sid_default(const char *scontext, u32 scontext_len, | 1556 | int security_context_to_sid_default(struct selinux_state *state, |
1557 | const char *scontext, u32 scontext_len, | ||
1508 | u32 *sid, u32 def_sid, gfp_t gfp_flags) | 1558 | u32 *sid, u32 def_sid, gfp_t gfp_flags) |
1509 | { | 1559 | { |
1510 | return security_context_to_sid_core(scontext, scontext_len, | 1560 | return security_context_to_sid_core(state, scontext, scontext_len, |
1511 | sid, def_sid, gfp_flags, 1); | 1561 | sid, def_sid, gfp_flags, 1); |
1512 | } | 1562 | } |
1513 | 1563 | ||
1514 | int security_context_to_sid_force(const char *scontext, u32 scontext_len, | 1564 | int security_context_to_sid_force(struct selinux_state *state, |
1565 | const char *scontext, u32 scontext_len, | ||
1515 | u32 *sid) | 1566 | u32 *sid) |
1516 | { | 1567 | { |
1517 | return security_context_to_sid_core(scontext, scontext_len, | 1568 | return security_context_to_sid_core(state, scontext, scontext_len, |
1518 | sid, SECSID_NULL, GFP_KERNEL, 1); | 1569 | sid, SECSID_NULL, GFP_KERNEL, 1); |
1519 | } | 1570 | } |
1520 | 1571 | ||
1521 | static int compute_sid_handle_invalid_context( | 1572 | static int compute_sid_handle_invalid_context( |
1573 | struct selinux_state *state, | ||
1522 | struct context *scontext, | 1574 | struct context *scontext, |
1523 | struct context *tcontext, | 1575 | struct context *tcontext, |
1524 | u16 tclass, | 1576 | u16 tclass, |
1525 | struct context *newcontext) | 1577 | struct context *newcontext) |
1526 | { | 1578 | { |
1579 | struct policydb *policydb = &state->ss->policydb; | ||
1527 | char *s = NULL, *t = NULL, *n = NULL; | 1580 | char *s = NULL, *t = NULL, *n = NULL; |
1528 | u32 slen, tlen, nlen; | 1581 | u32 slen, tlen, nlen; |
1529 | 1582 | ||
1530 | if (context_struct_to_string(scontext, &s, &slen)) | 1583 | if (context_struct_to_string(policydb, scontext, &s, &slen)) |
1531 | goto out; | 1584 | goto out; |
1532 | if (context_struct_to_string(tcontext, &t, &tlen)) | 1585 | if (context_struct_to_string(policydb, tcontext, &t, &tlen)) |
1533 | goto out; | 1586 | goto out; |
1534 | if (context_struct_to_string(newcontext, &n, &nlen)) | 1587 | if (context_struct_to_string(policydb, newcontext, &n, &nlen)) |
1535 | goto out; | 1588 | goto out; |
1536 | audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, | 1589 | audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, |
1537 | "op=security_compute_sid invalid_context=%s" | 1590 | "op=security_compute_sid invalid_context=%s" |
1538 | " scontext=%s" | 1591 | " scontext=%s" |
1539 | " tcontext=%s" | 1592 | " tcontext=%s" |
1540 | " tclass=%s", | 1593 | " tclass=%s", |
1541 | n, s, t, sym_name(&policydb, SYM_CLASSES, tclass-1)); | 1594 | n, s, t, sym_name(policydb, SYM_CLASSES, tclass-1)); |
1542 | out: | 1595 | out: |
1543 | kfree(s); | 1596 | kfree(s); |
1544 | kfree(t); | 1597 | kfree(t); |
1545 | kfree(n); | 1598 | kfree(n); |
1546 | if (!selinux_enforcing) | 1599 | if (!is_enforcing(state)) |
1547 | return 0; | 1600 | return 0; |
1548 | return -EACCES; | 1601 | return -EACCES; |
1549 | } | 1602 | } |
1550 | 1603 | ||
1551 | static void filename_compute_type(struct policydb *p, struct context *newcontext, | 1604 | static void filename_compute_type(struct policydb *policydb, |
1605 | struct context *newcontext, | ||
1552 | u32 stype, u32 ttype, u16 tclass, | 1606 | u32 stype, u32 ttype, u16 tclass, |
1553 | const char *objname) | 1607 | const char *objname) |
1554 | { | 1608 | { |
@@ -1560,7 +1614,7 @@ static void filename_compute_type(struct policydb *p, struct context *newcontext | |||
1560 | * like /dev or /var/run. This bitmap will quickly skip rule searches | 1614 | * like /dev or /var/run. This bitmap will quickly skip rule searches |
1561 | * if the ttype does not contain any rules. | 1615 | * if the ttype does not contain any rules. |
1562 | */ | 1616 | */ |
1563 | if (!ebitmap_get_bit(&p->filename_trans_ttypes, ttype)) | 1617 | if (!ebitmap_get_bit(&policydb->filename_trans_ttypes, ttype)) |
1564 | return; | 1618 | return; |
1565 | 1619 | ||
1566 | ft.stype = stype; | 1620 | ft.stype = stype; |
@@ -1568,12 +1622,13 @@ static void filename_compute_type(struct policydb *p, struct context *newcontext | |||
1568 | ft.tclass = tclass; | 1622 | ft.tclass = tclass; |
1569 | ft.name = objname; | 1623 | ft.name = objname; |
1570 | 1624 | ||
1571 | otype = hashtab_search(p->filename_trans, &ft); | 1625 | otype = hashtab_search(policydb->filename_trans, &ft); |
1572 | if (otype) | 1626 | if (otype) |
1573 | newcontext->type = otype->otype; | 1627 | newcontext->type = otype->otype; |
1574 | } | 1628 | } |
1575 | 1629 | ||
1576 | static int security_compute_sid(u32 ssid, | 1630 | static int security_compute_sid(struct selinux_state *state, |
1631 | u32 ssid, | ||
1577 | u32 tsid, | 1632 | u32 tsid, |
1578 | u16 orig_tclass, | 1633 | u16 orig_tclass, |
1579 | u32 specified, | 1634 | u32 specified, |
@@ -1581,6 +1636,8 @@ static int security_compute_sid(u32 ssid, | |||
1581 | u32 *out_sid, | 1636 | u32 *out_sid, |
1582 | bool kern) | 1637 | bool kern) |
1583 | { | 1638 | { |
1639 | struct policydb *policydb; | ||
1640 | struct sidtab *sidtab; | ||
1584 | struct class_datum *cladatum = NULL; | 1641 | struct class_datum *cladatum = NULL; |
1585 | struct context *scontext = NULL, *tcontext = NULL, newcontext; | 1642 | struct context *scontext = NULL, *tcontext = NULL, newcontext; |
1586 | struct role_trans *roletr = NULL; | 1643 | struct role_trans *roletr = NULL; |
@@ -1591,7 +1648,7 @@ static int security_compute_sid(u32 ssid, | |||
1591 | int rc = 0; | 1648 | int rc = 0; |
1592 | bool sock; | 1649 | bool sock; |
1593 | 1650 | ||
1594 | if (!ss_initialized) { | 1651 | if (!state->initialized) { |
1595 | switch (orig_tclass) { | 1652 | switch (orig_tclass) { |
1596 | case SECCLASS_PROCESS: /* kernel value */ | 1653 | case SECCLASS_PROCESS: /* kernel value */ |
1597 | *out_sid = ssid; | 1654 | *out_sid = ssid; |
@@ -1605,24 +1662,28 @@ static int security_compute_sid(u32 ssid, | |||
1605 | 1662 | ||
1606 | context_init(&newcontext); | 1663 | context_init(&newcontext); |
1607 | 1664 | ||
1608 | read_lock(&policy_rwlock); | 1665 | read_lock(&state->ss->policy_rwlock); |
1609 | 1666 | ||
1610 | if (kern) { | 1667 | if (kern) { |
1611 | tclass = unmap_class(orig_tclass); | 1668 | tclass = unmap_class(&state->ss->map, orig_tclass); |
1612 | sock = security_is_socket_class(orig_tclass); | 1669 | sock = security_is_socket_class(orig_tclass); |
1613 | } else { | 1670 | } else { |
1614 | tclass = orig_tclass; | 1671 | tclass = orig_tclass; |
1615 | sock = security_is_socket_class(map_class(tclass)); | 1672 | sock = security_is_socket_class(map_class(&state->ss->map, |
1673 | tclass)); | ||
1616 | } | 1674 | } |
1617 | 1675 | ||
1618 | scontext = sidtab_search(&sidtab, ssid); | 1676 | policydb = &state->ss->policydb; |
1677 | sidtab = &state->ss->sidtab; | ||
1678 | |||
1679 | scontext = sidtab_search(sidtab, ssid); | ||
1619 | if (!scontext) { | 1680 | if (!scontext) { |
1620 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 1681 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
1621 | __func__, ssid); | 1682 | __func__, ssid); |
1622 | rc = -EINVAL; | 1683 | rc = -EINVAL; |
1623 | goto out_unlock; | 1684 | goto out_unlock; |
1624 | } | 1685 | } |
1625 | tcontext = sidtab_search(&sidtab, tsid); | 1686 | tcontext = sidtab_search(sidtab, tsid); |
1626 | if (!tcontext) { | 1687 | if (!tcontext) { |
1627 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 1688 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
1628 | __func__, tsid); | 1689 | __func__, tsid); |
@@ -1630,8 +1691,8 @@ static int security_compute_sid(u32 ssid, | |||
1630 | goto out_unlock; | 1691 | goto out_unlock; |
1631 | } | 1692 | } |
1632 | 1693 | ||
1633 | if (tclass && tclass <= policydb.p_classes.nprim) | 1694 | if (tclass && tclass <= policydb->p_classes.nprim) |
1634 | cladatum = policydb.class_val_to_struct[tclass - 1]; | 1695 | cladatum = policydb->class_val_to_struct[tclass - 1]; |
1635 | 1696 | ||
1636 | /* Set the user identity. */ | 1697 | /* Set the user identity. */ |
1637 | switch (specified) { | 1698 | switch (specified) { |
@@ -1657,7 +1718,7 @@ static int security_compute_sid(u32 ssid, | |||
1657 | } else if (cladatum && cladatum->default_role == DEFAULT_TARGET) { | 1718 | } else if (cladatum && cladatum->default_role == DEFAULT_TARGET) { |
1658 | newcontext.role = tcontext->role; | 1719 | newcontext.role = tcontext->role; |
1659 | } else { | 1720 | } else { |
1660 | if ((tclass == policydb.process_class) || (sock == true)) | 1721 | if ((tclass == policydb->process_class) || (sock == true)) |
1661 | newcontext.role = scontext->role; | 1722 | newcontext.role = scontext->role; |
1662 | else | 1723 | else |
1663 | newcontext.role = OBJECT_R_VAL; | 1724 | newcontext.role = OBJECT_R_VAL; |
@@ -1669,7 +1730,7 @@ static int security_compute_sid(u32 ssid, | |||
1669 | } else if (cladatum && cladatum->default_type == DEFAULT_TARGET) { | 1730 | } else if (cladatum && cladatum->default_type == DEFAULT_TARGET) { |
1670 | newcontext.type = tcontext->type; | 1731 | newcontext.type = tcontext->type; |
1671 | } else { | 1732 | } else { |
1672 | if ((tclass == policydb.process_class) || (sock == true)) { | 1733 | if ((tclass == policydb->process_class) || (sock == true)) { |
1673 | /* Use the type of process. */ | 1734 | /* Use the type of process. */ |
1674 | newcontext.type = scontext->type; | 1735 | newcontext.type = scontext->type; |
1675 | } else { | 1736 | } else { |
@@ -1683,11 +1744,11 @@ static int security_compute_sid(u32 ssid, | |||
1683 | avkey.target_type = tcontext->type; | 1744 | avkey.target_type = tcontext->type; |
1684 | avkey.target_class = tclass; | 1745 | avkey.target_class = tclass; |
1685 | avkey.specified = specified; | 1746 | avkey.specified = specified; |
1686 | avdatum = avtab_search(&policydb.te_avtab, &avkey); | 1747 | avdatum = avtab_search(&policydb->te_avtab, &avkey); |
1687 | 1748 | ||
1688 | /* If no permanent rule, also check for enabled conditional rules */ | 1749 | /* If no permanent rule, also check for enabled conditional rules */ |
1689 | if (!avdatum) { | 1750 | if (!avdatum) { |
1690 | node = avtab_search_node(&policydb.te_cond_avtab, &avkey); | 1751 | node = avtab_search_node(&policydb->te_cond_avtab, &avkey); |
1691 | for (; node; node = avtab_search_node_next(node, specified)) { | 1752 | for (; node; node = avtab_search_node_next(node, specified)) { |
1692 | if (node->key.specified & AVTAB_ENABLED) { | 1753 | if (node->key.specified & AVTAB_ENABLED) { |
1693 | avdatum = &node->datum; | 1754 | avdatum = &node->datum; |
@@ -1703,13 +1764,14 @@ static int security_compute_sid(u32 ssid, | |||
1703 | 1764 | ||
1704 | /* if we have a objname this is a file trans check so check those rules */ | 1765 | /* if we have a objname this is a file trans check so check those rules */ |
1705 | if (objname) | 1766 | if (objname) |
1706 | filename_compute_type(&policydb, &newcontext, scontext->type, | 1767 | filename_compute_type(policydb, &newcontext, scontext->type, |
1707 | tcontext->type, tclass, objname); | 1768 | tcontext->type, tclass, objname); |
1708 | 1769 | ||
1709 | /* Check for class-specific changes. */ | 1770 | /* Check for class-specific changes. */ |
1710 | if (specified & AVTAB_TRANSITION) { | 1771 | if (specified & AVTAB_TRANSITION) { |
1711 | /* Look for a role transition rule. */ | 1772 | /* Look for a role transition rule. */ |
1712 | for (roletr = policydb.role_tr; roletr; roletr = roletr->next) { | 1773 | for (roletr = policydb->role_tr; roletr; |
1774 | roletr = roletr->next) { | ||
1713 | if ((roletr->role == scontext->role) && | 1775 | if ((roletr->role == scontext->role) && |
1714 | (roletr->type == tcontext->type) && | 1776 | (roletr->type == tcontext->type) && |
1715 | (roletr->tclass == tclass)) { | 1777 | (roletr->tclass == tclass)) { |
@@ -1722,14 +1784,14 @@ static int security_compute_sid(u32 ssid, | |||
1722 | 1784 | ||
1723 | /* Set the MLS attributes. | 1785 | /* Set the MLS attributes. |
1724 | This is done last because it may allocate memory. */ | 1786 | This is done last because it may allocate memory. */ |
1725 | rc = mls_compute_sid(scontext, tcontext, tclass, specified, | 1787 | rc = mls_compute_sid(policydb, scontext, tcontext, tclass, specified, |
1726 | &newcontext, sock); | 1788 | &newcontext, sock); |
1727 | if (rc) | 1789 | if (rc) |
1728 | goto out_unlock; | 1790 | goto out_unlock; |
1729 | 1791 | ||
1730 | /* Check the validity of the context. */ | 1792 | /* Check the validity of the context. */ |
1731 | if (!policydb_context_isvalid(&policydb, &newcontext)) { | 1793 | if (!policydb_context_isvalid(policydb, &newcontext)) { |
1732 | rc = compute_sid_handle_invalid_context(scontext, | 1794 | rc = compute_sid_handle_invalid_context(state, scontext, |
1733 | tcontext, | 1795 | tcontext, |
1734 | tclass, | 1796 | tclass, |
1735 | &newcontext); | 1797 | &newcontext); |
@@ -1737,9 +1799,9 @@ static int security_compute_sid(u32 ssid, | |||
1737 | goto out_unlock; | 1799 | goto out_unlock; |
1738 | } | 1800 | } |
1739 | /* Obtain the sid for the context. */ | 1801 | /* Obtain the sid for the context. */ |
1740 | rc = sidtab_context_to_sid(&sidtab, &newcontext, out_sid); | 1802 | rc = sidtab_context_to_sid(sidtab, &newcontext, out_sid); |
1741 | out_unlock: | 1803 | out_unlock: |
1742 | read_unlock(&policy_rwlock); | 1804 | read_unlock(&state->ss->policy_rwlock); |
1743 | context_destroy(&newcontext); | 1805 | context_destroy(&newcontext); |
1744 | out: | 1806 | out: |
1745 | return rc; | 1807 | return rc; |
@@ -1758,17 +1820,21 @@ out: | |||
1758 | * if insufficient memory is available, or %0 if the new SID was | 1820 | * if insufficient memory is available, or %0 if the new SID was |
1759 | * computed successfully. | 1821 | * computed successfully. |
1760 | */ | 1822 | */ |
1761 | int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, | 1823 | int security_transition_sid(struct selinux_state *state, |
1824 | u32 ssid, u32 tsid, u16 tclass, | ||
1762 | const struct qstr *qstr, u32 *out_sid) | 1825 | const struct qstr *qstr, u32 *out_sid) |
1763 | { | 1826 | { |
1764 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, | 1827 | return security_compute_sid(state, ssid, tsid, tclass, |
1828 | AVTAB_TRANSITION, | ||
1765 | qstr ? qstr->name : NULL, out_sid, true); | 1829 | qstr ? qstr->name : NULL, out_sid, true); |
1766 | } | 1830 | } |
1767 | 1831 | ||
1768 | int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, | 1832 | int security_transition_sid_user(struct selinux_state *state, |
1833 | u32 ssid, u32 tsid, u16 tclass, | ||
1769 | const char *objname, u32 *out_sid) | 1834 | const char *objname, u32 *out_sid) |
1770 | { | 1835 | { |
1771 | return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, | 1836 | return security_compute_sid(state, ssid, tsid, tclass, |
1837 | AVTAB_TRANSITION, | ||
1772 | objname, out_sid, false); | 1838 | objname, out_sid, false); |
1773 | } | 1839 | } |
1774 | 1840 | ||
@@ -1785,12 +1851,14 @@ int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, | |||
1785 | * if insufficient memory is available, or %0 if the SID was | 1851 | * if insufficient memory is available, or %0 if the SID was |
1786 | * computed successfully. | 1852 | * computed successfully. |
1787 | */ | 1853 | */ |
1788 | int security_member_sid(u32 ssid, | 1854 | int security_member_sid(struct selinux_state *state, |
1855 | u32 ssid, | ||
1789 | u32 tsid, | 1856 | u32 tsid, |
1790 | u16 tclass, | 1857 | u16 tclass, |
1791 | u32 *out_sid) | 1858 | u32 *out_sid) |
1792 | { | 1859 | { |
1793 | return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, NULL, | 1860 | return security_compute_sid(state, ssid, tsid, tclass, |
1861 | AVTAB_MEMBER, NULL, | ||
1794 | out_sid, false); | 1862 | out_sid, false); |
1795 | } | 1863 | } |
1796 | 1864 | ||
@@ -1807,12 +1875,14 @@ int security_member_sid(u32 ssid, | |||
1807 | * if insufficient memory is available, or %0 if the SID was | 1875 | * if insufficient memory is available, or %0 if the SID was |
1808 | * computed successfully. | 1876 | * computed successfully. |
1809 | */ | 1877 | */ |
1810 | int security_change_sid(u32 ssid, | 1878 | int security_change_sid(struct selinux_state *state, |
1879 | u32 ssid, | ||
1811 | u32 tsid, | 1880 | u32 tsid, |
1812 | u16 tclass, | 1881 | u16 tclass, |
1813 | u32 *out_sid) | 1882 | u32 *out_sid) |
1814 | { | 1883 | { |
1815 | return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, NULL, | 1884 | return security_compute_sid(state, |
1885 | ssid, tsid, tclass, AVTAB_CHANGE, NULL, | ||
1816 | out_sid, false); | 1886 | out_sid, false); |
1817 | } | 1887 | } |
1818 | 1888 | ||
@@ -1829,15 +1899,18 @@ static int clone_sid(u32 sid, | |||
1829 | return 0; | 1899 | return 0; |
1830 | } | 1900 | } |
1831 | 1901 | ||
1832 | static inline int convert_context_handle_invalid_context(struct context *context) | 1902 | static inline int convert_context_handle_invalid_context( |
1903 | struct selinux_state *state, | ||
1904 | struct context *context) | ||
1833 | { | 1905 | { |
1906 | struct policydb *policydb = &state->ss->policydb; | ||
1834 | char *s; | 1907 | char *s; |
1835 | u32 len; | 1908 | u32 len; |
1836 | 1909 | ||
1837 | if (selinux_enforcing) | 1910 | if (is_enforcing(state)) |
1838 | return -EINVAL; | 1911 | return -EINVAL; |
1839 | 1912 | ||
1840 | if (!context_struct_to_string(context, &s, &len)) { | 1913 | if (!context_struct_to_string(policydb, context, &s, &len)) { |
1841 | printk(KERN_WARNING "SELinux: Context %s would be invalid if enforcing\n", s); | 1914 | printk(KERN_WARNING "SELinux: Context %s would be invalid if enforcing\n", s); |
1842 | kfree(s); | 1915 | kfree(s); |
1843 | } | 1916 | } |
@@ -1845,6 +1918,7 @@ static inline int convert_context_handle_invalid_context(struct context *context | |||
1845 | } | 1918 | } |
1846 | 1919 | ||
1847 | struct convert_context_args { | 1920 | struct convert_context_args { |
1921 | struct selinux_state *state; | ||
1848 | struct policydb *oldp; | 1922 | struct policydb *oldp; |
1849 | struct policydb *newp; | 1923 | struct policydb *newp; |
1850 | }; | 1924 | }; |
@@ -1971,7 +2045,8 @@ static int convert_context(u32 key, | |||
1971 | 2045 | ||
1972 | /* Check the validity of the new context. */ | 2046 | /* Check the validity of the new context. */ |
1973 | if (!policydb_context_isvalid(args->newp, c)) { | 2047 | if (!policydb_context_isvalid(args->newp, c)) { |
1974 | rc = convert_context_handle_invalid_context(&oldc); | 2048 | rc = convert_context_handle_invalid_context(args->state, |
2049 | &oldc); | ||
1975 | if (rc) | 2050 | if (rc) |
1976 | goto bad; | 2051 | goto bad; |
1977 | } | 2052 | } |
@@ -1983,7 +2058,7 @@ out: | |||
1983 | return rc; | 2058 | return rc; |
1984 | bad: | 2059 | bad: |
1985 | /* Map old representation to string and save it. */ | 2060 | /* Map old representation to string and save it. */ |
1986 | rc = context_struct_to_string(&oldc, &s, &len); | 2061 | rc = context_struct_to_string(args->oldp, &oldc, &s, &len); |
1987 | if (rc) | 2062 | if (rc) |
1988 | return rc; | 2063 | return rc; |
1989 | context_destroy(&oldc); | 2064 | context_destroy(&oldc); |
@@ -1996,39 +2071,29 @@ bad: | |||
1996 | goto out; | 2071 | goto out; |
1997 | } | 2072 | } |
1998 | 2073 | ||
1999 | static void security_load_policycaps(void) | 2074 | static void security_load_policycaps(struct selinux_state *state) |
2000 | { | 2075 | { |
2076 | struct policydb *p = &state->ss->policydb; | ||
2001 | unsigned int i; | 2077 | unsigned int i; |
2002 | struct ebitmap_node *node; | 2078 | struct ebitmap_node *node; |
2003 | 2079 | ||
2004 | selinux_policycap_netpeer = ebitmap_get_bit(&policydb.policycaps, | 2080 | for (i = 0; i < ARRAY_SIZE(state->policycap); i++) |
2005 | POLICYDB_CAPABILITY_NETPEER); | 2081 | state->policycap[i] = ebitmap_get_bit(&p->policycaps, i); |
2006 | selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps, | ||
2007 | POLICYDB_CAPABILITY_OPENPERM); | ||
2008 | selinux_policycap_extsockclass = ebitmap_get_bit(&policydb.policycaps, | ||
2009 | POLICYDB_CAPABILITY_EXTSOCKCLASS); | ||
2010 | selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps, | ||
2011 | POLICYDB_CAPABILITY_ALWAYSNETWORK); | ||
2012 | selinux_policycap_cgroupseclabel = | ||
2013 | ebitmap_get_bit(&policydb.policycaps, | ||
2014 | POLICYDB_CAPABILITY_CGROUPSECLABEL); | ||
2015 | selinux_policycap_nnp_nosuid_transition = | ||
2016 | ebitmap_get_bit(&policydb.policycaps, | ||
2017 | POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION); | ||
2018 | 2082 | ||
2019 | for (i = 0; i < ARRAY_SIZE(selinux_policycap_names); i++) | 2083 | for (i = 0; i < ARRAY_SIZE(selinux_policycap_names); i++) |
2020 | pr_info("SELinux: policy capability %s=%d\n", | 2084 | pr_info("SELinux: policy capability %s=%d\n", |
2021 | selinux_policycap_names[i], | 2085 | selinux_policycap_names[i], |
2022 | ebitmap_get_bit(&policydb.policycaps, i)); | 2086 | ebitmap_get_bit(&p->policycaps, i)); |
2023 | 2087 | ||
2024 | ebitmap_for_each_positive_bit(&policydb.policycaps, node, i) { | 2088 | ebitmap_for_each_positive_bit(&p->policycaps, node, i) { |
2025 | if (i >= ARRAY_SIZE(selinux_policycap_names)) | 2089 | if (i >= ARRAY_SIZE(selinux_policycap_names)) |
2026 | pr_info("SELinux: unknown policy capability %u\n", | 2090 | pr_info("SELinux: unknown policy capability %u\n", |
2027 | i); | 2091 | i); |
2028 | } | 2092 | } |
2029 | } | 2093 | } |
2030 | 2094 | ||
2031 | static int security_preserve_bools(struct policydb *p); | 2095 | static int security_preserve_bools(struct selinux_state *state, |
2096 | struct policydb *newpolicydb); | ||
2032 | 2097 | ||
2033 | /** | 2098 | /** |
2034 | * security_load_policy - Load a security policy configuration. | 2099 | * security_load_policy - Load a security policy configuration. |
@@ -2040,14 +2105,16 @@ static int security_preserve_bools(struct policydb *p); | |||
2040 | * This function will flush the access vector cache after | 2105 | * This function will flush the access vector cache after |
2041 | * loading the new policy. | 2106 | * loading the new policy. |
2042 | */ | 2107 | */ |
2043 | int security_load_policy(void *data, size_t len) | 2108 | int security_load_policy(struct selinux_state *state, void *data, size_t len) |
2044 | { | 2109 | { |
2110 | struct policydb *policydb; | ||
2111 | struct sidtab *sidtab; | ||
2045 | struct policydb *oldpolicydb, *newpolicydb; | 2112 | struct policydb *oldpolicydb, *newpolicydb; |
2046 | struct sidtab oldsidtab, newsidtab; | 2113 | struct sidtab oldsidtab, newsidtab; |
2047 | struct selinux_mapping *oldmap, *map = NULL; | 2114 | struct selinux_mapping *oldmapping; |
2115 | struct selinux_map newmap; | ||
2048 | struct convert_context_args args; | 2116 | struct convert_context_args args; |
2049 | u32 seqno; | 2117 | u32 seqno; |
2050 | u16 map_size; | ||
2051 | int rc = 0; | 2118 | int rc = 0; |
2052 | struct policy_file file = { data, len }, *fp = &file; | 2119 | struct policy_file file = { data, len }, *fp = &file; |
2053 | 2120 | ||
@@ -2058,53 +2125,42 @@ int security_load_policy(void *data, size_t len) | |||
2058 | } | 2125 | } |
2059 | newpolicydb = oldpolicydb + 1; | 2126 | newpolicydb = oldpolicydb + 1; |
2060 | 2127 | ||
2061 | if (!ss_initialized) { | 2128 | policydb = &state->ss->policydb; |
2062 | avtab_cache_init(); | 2129 | sidtab = &state->ss->sidtab; |
2063 | ebitmap_cache_init(); | 2130 | |
2064 | hashtab_cache_init(); | 2131 | if (!state->initialized) { |
2065 | rc = policydb_read(&policydb, fp); | 2132 | rc = policydb_read(policydb, fp); |
2066 | if (rc) { | 2133 | if (rc) |
2067 | avtab_cache_destroy(); | ||
2068 | ebitmap_cache_destroy(); | ||
2069 | hashtab_cache_destroy(); | ||
2070 | goto out; | 2134 | goto out; |
2071 | } | ||
2072 | 2135 | ||
2073 | policydb.len = len; | 2136 | policydb->len = len; |
2074 | rc = selinux_set_mapping(&policydb, secclass_map, | 2137 | rc = selinux_set_mapping(policydb, secclass_map, |
2075 | ¤t_mapping, | 2138 | &state->ss->map); |
2076 | ¤t_mapping_size); | ||
2077 | if (rc) { | 2139 | if (rc) { |
2078 | policydb_destroy(&policydb); | 2140 | policydb_destroy(policydb); |
2079 | avtab_cache_destroy(); | ||
2080 | ebitmap_cache_destroy(); | ||
2081 | hashtab_cache_destroy(); | ||
2082 | goto out; | 2141 | goto out; |
2083 | } | 2142 | } |
2084 | 2143 | ||
2085 | rc = policydb_load_isids(&policydb, &sidtab); | 2144 | rc = policydb_load_isids(policydb, sidtab); |
2086 | if (rc) { | 2145 | if (rc) { |
2087 | policydb_destroy(&policydb); | 2146 | policydb_destroy(policydb); |
2088 | avtab_cache_destroy(); | ||
2089 | ebitmap_cache_destroy(); | ||
2090 | hashtab_cache_destroy(); | ||
2091 | goto out; | 2147 | goto out; |
2092 | } | 2148 | } |
2093 | 2149 | ||
2094 | security_load_policycaps(); | 2150 | security_load_policycaps(state); |
2095 | ss_initialized = 1; | 2151 | state->initialized = 1; |
2096 | seqno = ++latest_granting; | 2152 | seqno = ++state->ss->latest_granting; |
2097 | selinux_complete_init(); | 2153 | selinux_complete_init(); |
2098 | avc_ss_reset(seqno); | 2154 | avc_ss_reset(seqno); |
2099 | selnl_notify_policyload(seqno); | 2155 | selnl_notify_policyload(seqno); |
2100 | selinux_status_update_policyload(seqno); | 2156 | selinux_status_update_policyload(state, seqno); |
2101 | selinux_netlbl_cache_invalidate(); | 2157 | selinux_netlbl_cache_invalidate(); |
2102 | selinux_xfrm_notify_policyload(); | 2158 | selinux_xfrm_notify_policyload(); |
2103 | goto out; | 2159 | goto out; |
2104 | } | 2160 | } |
2105 | 2161 | ||
2106 | #if 0 | 2162 | #if 0 |
2107 | sidtab_hash_eval(&sidtab, "sids"); | 2163 | sidtab_hash_eval(sidtab, "sids"); |
2108 | #endif | 2164 | #endif |
2109 | 2165 | ||
2110 | rc = policydb_read(newpolicydb, fp); | 2166 | rc = policydb_read(newpolicydb, fp); |
@@ -2113,9 +2169,9 @@ int security_load_policy(void *data, size_t len) | |||
2113 | 2169 | ||
2114 | newpolicydb->len = len; | 2170 | newpolicydb->len = len; |
2115 | /* If switching between different policy types, log MLS status */ | 2171 | /* If switching between different policy types, log MLS status */ |
2116 | if (policydb.mls_enabled && !newpolicydb->mls_enabled) | 2172 | if (policydb->mls_enabled && !newpolicydb->mls_enabled) |
2117 | printk(KERN_INFO "SELinux: Disabling MLS support...\n"); | 2173 | printk(KERN_INFO "SELinux: Disabling MLS support...\n"); |
2118 | else if (!policydb.mls_enabled && newpolicydb->mls_enabled) | 2174 | else if (!policydb->mls_enabled && newpolicydb->mls_enabled) |
2119 | printk(KERN_INFO "SELinux: Enabling MLS support...\n"); | 2175 | printk(KERN_INFO "SELinux: Enabling MLS support...\n"); |
2120 | 2176 | ||
2121 | rc = policydb_load_isids(newpolicydb, &newsidtab); | 2177 | rc = policydb_load_isids(newpolicydb, &newsidtab); |
@@ -2125,20 +2181,20 @@ int security_load_policy(void *data, size_t len) | |||
2125 | goto out; | 2181 | goto out; |
2126 | } | 2182 | } |
2127 | 2183 | ||
2128 | rc = selinux_set_mapping(newpolicydb, secclass_map, &map, &map_size); | 2184 | rc = selinux_set_mapping(newpolicydb, secclass_map, &newmap); |
2129 | if (rc) | 2185 | if (rc) |
2130 | goto err; | 2186 | goto err; |
2131 | 2187 | ||
2132 | rc = security_preserve_bools(newpolicydb); | 2188 | rc = security_preserve_bools(state, newpolicydb); |
2133 | if (rc) { | 2189 | if (rc) { |
2134 | printk(KERN_ERR "SELinux: unable to preserve booleans\n"); | 2190 | printk(KERN_ERR "SELinux: unable to preserve booleans\n"); |
2135 | goto err; | 2191 | goto err; |
2136 | } | 2192 | } |
2137 | 2193 | ||
2138 | /* Clone the SID table. */ | 2194 | /* Clone the SID table. */ |
2139 | sidtab_shutdown(&sidtab); | 2195 | sidtab_shutdown(sidtab); |
2140 | 2196 | ||
2141 | rc = sidtab_map(&sidtab, clone_sid, &newsidtab); | 2197 | rc = sidtab_map(sidtab, clone_sid, &newsidtab); |
2142 | if (rc) | 2198 | if (rc) |
2143 | goto err; | 2199 | goto err; |
2144 | 2200 | ||
@@ -2146,7 +2202,8 @@ int security_load_policy(void *data, size_t len) | |||
2146 | * Convert the internal representations of contexts | 2202 | * Convert the internal representations of contexts |
2147 | * in the new SID table. | 2203 | * in the new SID table. |
2148 | */ | 2204 | */ |
2149 | args.oldp = &policydb; | 2205 | args.state = state; |
2206 | args.oldp = policydb; | ||
2150 | args.newp = newpolicydb; | 2207 | args.newp = newpolicydb; |
2151 | rc = sidtab_map(&newsidtab, convert_context, &args); | 2208 | rc = sidtab_map(&newsidtab, convert_context, &args); |
2152 | if (rc) { | 2209 | if (rc) { |
@@ -2157,28 +2214,28 @@ int security_load_policy(void *data, size_t len) | |||
2157 | } | 2214 | } |
2158 | 2215 | ||
2159 | /* Save the old policydb and SID table to free later. */ | 2216 | /* Save the old policydb and SID table to free later. */ |
2160 | memcpy(oldpolicydb, &policydb, sizeof(policydb)); | 2217 | memcpy(oldpolicydb, policydb, sizeof(*policydb)); |
2161 | sidtab_set(&oldsidtab, &sidtab); | 2218 | sidtab_set(&oldsidtab, sidtab); |
2162 | 2219 | ||
2163 | /* Install the new policydb and SID table. */ | 2220 | /* Install the new policydb and SID table. */ |
2164 | write_lock_irq(&policy_rwlock); | 2221 | write_lock_irq(&state->ss->policy_rwlock); |
2165 | memcpy(&policydb, newpolicydb, sizeof(policydb)); | 2222 | memcpy(policydb, newpolicydb, sizeof(*policydb)); |
2166 | sidtab_set(&sidtab, &newsidtab); | 2223 | sidtab_set(sidtab, &newsidtab); |
2167 | security_load_policycaps(); | 2224 | security_load_policycaps(state); |
2168 | oldmap = current_mapping; | 2225 | oldmapping = state->ss->map.mapping; |
2169 | current_mapping = map; | 2226 | state->ss->map.mapping = newmap.mapping; |
2170 | current_mapping_size = map_size; | 2227 | state->ss->map.size = newmap.size; |
2171 | seqno = ++latest_granting; | 2228 | seqno = ++state->ss->latest_granting; |
2172 | write_unlock_irq(&policy_rwlock); | 2229 | write_unlock_irq(&state->ss->policy_rwlock); |
2173 | 2230 | ||
2174 | /* Free the old policydb and SID table. */ | 2231 | /* Free the old policydb and SID table. */ |
2175 | policydb_destroy(oldpolicydb); | 2232 | policydb_destroy(oldpolicydb); |
2176 | sidtab_destroy(&oldsidtab); | 2233 | sidtab_destroy(&oldsidtab); |
2177 | kfree(oldmap); | 2234 | kfree(oldmapping); |
2178 | 2235 | ||
2179 | avc_ss_reset(seqno); | 2236 | avc_ss_reset(seqno); |
2180 | selnl_notify_policyload(seqno); | 2237 | selnl_notify_policyload(seqno); |
2181 | selinux_status_update_policyload(seqno); | 2238 | selinux_status_update_policyload(state, seqno); |
2182 | selinux_netlbl_cache_invalidate(); | 2239 | selinux_netlbl_cache_invalidate(); |
2183 | selinux_xfrm_notify_policyload(); | 2240 | selinux_xfrm_notify_policyload(); |
2184 | 2241 | ||
@@ -2186,7 +2243,7 @@ int security_load_policy(void *data, size_t len) | |||
2186 | goto out; | 2243 | goto out; |
2187 | 2244 | ||
2188 | err: | 2245 | err: |
2189 | kfree(map); | 2246 | kfree(newmap.mapping); |
2190 | sidtab_destroy(&newsidtab); | 2247 | sidtab_destroy(&newsidtab); |
2191 | policydb_destroy(newpolicydb); | 2248 | policydb_destroy(newpolicydb); |
2192 | 2249 | ||
@@ -2195,13 +2252,14 @@ out: | |||
2195 | return rc; | 2252 | return rc; |
2196 | } | 2253 | } |
2197 | 2254 | ||
2198 | size_t security_policydb_len(void) | 2255 | size_t security_policydb_len(struct selinux_state *state) |
2199 | { | 2256 | { |
2257 | struct policydb *p = &state->ss->policydb; | ||
2200 | size_t len; | 2258 | size_t len; |
2201 | 2259 | ||
2202 | read_lock(&policy_rwlock); | 2260 | read_lock(&state->ss->policy_rwlock); |
2203 | len = policydb.len; | 2261 | len = p->len; |
2204 | read_unlock(&policy_rwlock); | 2262 | read_unlock(&state->ss->policy_rwlock); |
2205 | 2263 | ||
2206 | return len; | 2264 | return len; |
2207 | } | 2265 | } |
@@ -2212,14 +2270,20 @@ size_t security_policydb_len(void) | |||
2212 | * @port: port number | 2270 | * @port: port number |
2213 | * @out_sid: security identifier | 2271 | * @out_sid: security identifier |
2214 | */ | 2272 | */ |
2215 | int security_port_sid(u8 protocol, u16 port, u32 *out_sid) | 2273 | int security_port_sid(struct selinux_state *state, |
2274 | u8 protocol, u16 port, u32 *out_sid) | ||
2216 | { | 2275 | { |
2276 | struct policydb *policydb; | ||
2277 | struct sidtab *sidtab; | ||
2217 | struct ocontext *c; | 2278 | struct ocontext *c; |
2218 | int rc = 0; | 2279 | int rc = 0; |
2219 | 2280 | ||
2220 | read_lock(&policy_rwlock); | 2281 | read_lock(&state->ss->policy_rwlock); |
2282 | |||
2283 | policydb = &state->ss->policydb; | ||
2284 | sidtab = &state->ss->sidtab; | ||
2221 | 2285 | ||
2222 | c = policydb.ocontexts[OCON_PORT]; | 2286 | c = policydb->ocontexts[OCON_PORT]; |
2223 | while (c) { | 2287 | while (c) { |
2224 | if (c->u.port.protocol == protocol && | 2288 | if (c->u.port.protocol == protocol && |
2225 | c->u.port.low_port <= port && | 2289 | c->u.port.low_port <= port && |
@@ -2230,7 +2294,7 @@ int security_port_sid(u8 protocol, u16 port, u32 *out_sid) | |||
2230 | 2294 | ||
2231 | if (c) { | 2295 | if (c) { |
2232 | if (!c->sid[0]) { | 2296 | if (!c->sid[0]) { |
2233 | rc = sidtab_context_to_sid(&sidtab, | 2297 | rc = sidtab_context_to_sid(sidtab, |
2234 | &c->context[0], | 2298 | &c->context[0], |
2235 | &c->sid[0]); | 2299 | &c->sid[0]); |
2236 | if (rc) | 2300 | if (rc) |
@@ -2242,7 +2306,7 @@ int security_port_sid(u8 protocol, u16 port, u32 *out_sid) | |||
2242 | } | 2306 | } |
2243 | 2307 | ||
2244 | out: | 2308 | out: |
2245 | read_unlock(&policy_rwlock); | 2309 | read_unlock(&state->ss->policy_rwlock); |
2246 | return rc; | 2310 | return rc; |
2247 | } | 2311 | } |
2248 | 2312 | ||
@@ -2252,14 +2316,20 @@ out: | |||
2252 | * @pkey_num: pkey number | 2316 | * @pkey_num: pkey number |
2253 | * @out_sid: security identifier | 2317 | * @out_sid: security identifier |
2254 | */ | 2318 | */ |
2255 | int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid) | 2319 | int security_ib_pkey_sid(struct selinux_state *state, |
2320 | u64 subnet_prefix, u16 pkey_num, u32 *out_sid) | ||
2256 | { | 2321 | { |
2322 | struct policydb *policydb; | ||
2323 | struct sidtab *sidtab; | ||
2257 | struct ocontext *c; | 2324 | struct ocontext *c; |
2258 | int rc = 0; | 2325 | int rc = 0; |
2259 | 2326 | ||
2260 | read_lock(&policy_rwlock); | 2327 | read_lock(&state->ss->policy_rwlock); |
2328 | |||
2329 | policydb = &state->ss->policydb; | ||
2330 | sidtab = &state->ss->sidtab; | ||
2261 | 2331 | ||
2262 | c = policydb.ocontexts[OCON_IBPKEY]; | 2332 | c = policydb->ocontexts[OCON_IBPKEY]; |
2263 | while (c) { | 2333 | while (c) { |
2264 | if (c->u.ibpkey.low_pkey <= pkey_num && | 2334 | if (c->u.ibpkey.low_pkey <= pkey_num && |
2265 | c->u.ibpkey.high_pkey >= pkey_num && | 2335 | c->u.ibpkey.high_pkey >= pkey_num && |
@@ -2271,7 +2341,7 @@ int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid) | |||
2271 | 2341 | ||
2272 | if (c) { | 2342 | if (c) { |
2273 | if (!c->sid[0]) { | 2343 | if (!c->sid[0]) { |
2274 | rc = sidtab_context_to_sid(&sidtab, | 2344 | rc = sidtab_context_to_sid(sidtab, |
2275 | &c->context[0], | 2345 | &c->context[0], |
2276 | &c->sid[0]); | 2346 | &c->sid[0]); |
2277 | if (rc) | 2347 | if (rc) |
@@ -2282,7 +2352,7 @@ int security_ib_pkey_sid(u64 subnet_prefix, u16 pkey_num, u32 *out_sid) | |||
2282 | *out_sid = SECINITSID_UNLABELED; | 2352 | *out_sid = SECINITSID_UNLABELED; |
2283 | 2353 | ||
2284 | out: | 2354 | out: |
2285 | read_unlock(&policy_rwlock); | 2355 | read_unlock(&state->ss->policy_rwlock); |
2286 | return rc; | 2356 | return rc; |
2287 | } | 2357 | } |
2288 | 2358 | ||
@@ -2292,14 +2362,20 @@ out: | |||
2292 | * @port: port number | 2362 | * @port: port number |
2293 | * @out_sid: security identifier | 2363 | * @out_sid: security identifier |
2294 | */ | 2364 | */ |
2295 | int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid) | 2365 | int security_ib_endport_sid(struct selinux_state *state, |
2366 | const char *dev_name, u8 port_num, u32 *out_sid) | ||
2296 | { | 2367 | { |
2368 | struct policydb *policydb; | ||
2369 | struct sidtab *sidtab; | ||
2297 | struct ocontext *c; | 2370 | struct ocontext *c; |
2298 | int rc = 0; | 2371 | int rc = 0; |
2299 | 2372 | ||
2300 | read_lock(&policy_rwlock); | 2373 | read_lock(&state->ss->policy_rwlock); |
2301 | 2374 | ||
2302 | c = policydb.ocontexts[OCON_IBENDPORT]; | 2375 | policydb = &state->ss->policydb; |
2376 | sidtab = &state->ss->sidtab; | ||
2377 | |||
2378 | c = policydb->ocontexts[OCON_IBENDPORT]; | ||
2303 | while (c) { | 2379 | while (c) { |
2304 | if (c->u.ibendport.port == port_num && | 2380 | if (c->u.ibendport.port == port_num && |
2305 | !strncmp(c->u.ibendport.dev_name, | 2381 | !strncmp(c->u.ibendport.dev_name, |
@@ -2312,7 +2388,7 @@ int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid) | |||
2312 | 2388 | ||
2313 | if (c) { | 2389 | if (c) { |
2314 | if (!c->sid[0]) { | 2390 | if (!c->sid[0]) { |
2315 | rc = sidtab_context_to_sid(&sidtab, | 2391 | rc = sidtab_context_to_sid(sidtab, |
2316 | &c->context[0], | 2392 | &c->context[0], |
2317 | &c->sid[0]); | 2393 | &c->sid[0]); |
2318 | if (rc) | 2394 | if (rc) |
@@ -2323,7 +2399,7 @@ int security_ib_endport_sid(const char *dev_name, u8 port_num, u32 *out_sid) | |||
2323 | *out_sid = SECINITSID_UNLABELED; | 2399 | *out_sid = SECINITSID_UNLABELED; |
2324 | 2400 | ||
2325 | out: | 2401 | out: |
2326 | read_unlock(&policy_rwlock); | 2402 | read_unlock(&state->ss->policy_rwlock); |
2327 | return rc; | 2403 | return rc; |
2328 | } | 2404 | } |
2329 | 2405 | ||
@@ -2332,14 +2408,20 @@ out: | |||
2332 | * @name: interface name | 2408 | * @name: interface name |
2333 | * @if_sid: interface SID | 2409 | * @if_sid: interface SID |
2334 | */ | 2410 | */ |
2335 | int security_netif_sid(char *name, u32 *if_sid) | 2411 | int security_netif_sid(struct selinux_state *state, |
2412 | char *name, u32 *if_sid) | ||
2336 | { | 2413 | { |
2414 | struct policydb *policydb; | ||
2415 | struct sidtab *sidtab; | ||
2337 | int rc = 0; | 2416 | int rc = 0; |
2338 | struct ocontext *c; | 2417 | struct ocontext *c; |
2339 | 2418 | ||
2340 | read_lock(&policy_rwlock); | 2419 | read_lock(&state->ss->policy_rwlock); |
2420 | |||
2421 | policydb = &state->ss->policydb; | ||
2422 | sidtab = &state->ss->sidtab; | ||
2341 | 2423 | ||
2342 | c = policydb.ocontexts[OCON_NETIF]; | 2424 | c = policydb->ocontexts[OCON_NETIF]; |
2343 | while (c) { | 2425 | while (c) { |
2344 | if (strcmp(name, c->u.name) == 0) | 2426 | if (strcmp(name, c->u.name) == 0) |
2345 | break; | 2427 | break; |
@@ -2348,12 +2430,12 @@ int security_netif_sid(char *name, u32 *if_sid) | |||
2348 | 2430 | ||
2349 | if (c) { | 2431 | if (c) { |
2350 | if (!c->sid[0] || !c->sid[1]) { | 2432 | if (!c->sid[0] || !c->sid[1]) { |
2351 | rc = sidtab_context_to_sid(&sidtab, | 2433 | rc = sidtab_context_to_sid(sidtab, |
2352 | &c->context[0], | 2434 | &c->context[0], |
2353 | &c->sid[0]); | 2435 | &c->sid[0]); |
2354 | if (rc) | 2436 | if (rc) |
2355 | goto out; | 2437 | goto out; |
2356 | rc = sidtab_context_to_sid(&sidtab, | 2438 | rc = sidtab_context_to_sid(sidtab, |
2357 | &c->context[1], | 2439 | &c->context[1], |
2358 | &c->sid[1]); | 2440 | &c->sid[1]); |
2359 | if (rc) | 2441 | if (rc) |
@@ -2364,7 +2446,7 @@ int security_netif_sid(char *name, u32 *if_sid) | |||
2364 | *if_sid = SECINITSID_NETIF; | 2446 | *if_sid = SECINITSID_NETIF; |
2365 | 2447 | ||
2366 | out: | 2448 | out: |
2367 | read_unlock(&policy_rwlock); | 2449 | read_unlock(&state->ss->policy_rwlock); |
2368 | return rc; | 2450 | return rc; |
2369 | } | 2451 | } |
2370 | 2452 | ||
@@ -2388,15 +2470,21 @@ static int match_ipv6_addrmask(u32 *input, u32 *addr, u32 *mask) | |||
2388 | * @addrlen: address length in bytes | 2470 | * @addrlen: address length in bytes |
2389 | * @out_sid: security identifier | 2471 | * @out_sid: security identifier |
2390 | */ | 2472 | */ |
2391 | int security_node_sid(u16 domain, | 2473 | int security_node_sid(struct selinux_state *state, |
2474 | u16 domain, | ||
2392 | void *addrp, | 2475 | void *addrp, |
2393 | u32 addrlen, | 2476 | u32 addrlen, |
2394 | u32 *out_sid) | 2477 | u32 *out_sid) |
2395 | { | 2478 | { |
2479 | struct policydb *policydb; | ||
2480 | struct sidtab *sidtab; | ||
2396 | int rc; | 2481 | int rc; |
2397 | struct ocontext *c; | 2482 | struct ocontext *c; |
2398 | 2483 | ||
2399 | read_lock(&policy_rwlock); | 2484 | read_lock(&state->ss->policy_rwlock); |
2485 | |||
2486 | policydb = &state->ss->policydb; | ||
2487 | sidtab = &state->ss->sidtab; | ||
2400 | 2488 | ||
2401 | switch (domain) { | 2489 | switch (domain) { |
2402 | case AF_INET: { | 2490 | case AF_INET: { |
@@ -2408,7 +2496,7 @@ int security_node_sid(u16 domain, | |||
2408 | 2496 | ||
2409 | addr = *((u32 *)addrp); | 2497 | addr = *((u32 *)addrp); |
2410 | 2498 | ||
2411 | c = policydb.ocontexts[OCON_NODE]; | 2499 | c = policydb->ocontexts[OCON_NODE]; |
2412 | while (c) { | 2500 | while (c) { |
2413 | if (c->u.node.addr == (addr & c->u.node.mask)) | 2501 | if (c->u.node.addr == (addr & c->u.node.mask)) |
2414 | break; | 2502 | break; |
@@ -2421,7 +2509,7 @@ int security_node_sid(u16 domain, | |||
2421 | rc = -EINVAL; | 2509 | rc = -EINVAL; |
2422 | if (addrlen != sizeof(u64) * 2) | 2510 | if (addrlen != sizeof(u64) * 2) |
2423 | goto out; | 2511 | goto out; |
2424 | c = policydb.ocontexts[OCON_NODE6]; | 2512 | c = policydb->ocontexts[OCON_NODE6]; |
2425 | while (c) { | 2513 | while (c) { |
2426 | if (match_ipv6_addrmask(addrp, c->u.node6.addr, | 2514 | if (match_ipv6_addrmask(addrp, c->u.node6.addr, |
2427 | c->u.node6.mask)) | 2515 | c->u.node6.mask)) |
@@ -2438,7 +2526,7 @@ int security_node_sid(u16 domain, | |||
2438 | 2526 | ||
2439 | if (c) { | 2527 | if (c) { |
2440 | if (!c->sid[0]) { | 2528 | if (!c->sid[0]) { |
2441 | rc = sidtab_context_to_sid(&sidtab, | 2529 | rc = sidtab_context_to_sid(sidtab, |
2442 | &c->context[0], | 2530 | &c->context[0], |
2443 | &c->sid[0]); | 2531 | &c->sid[0]); |
2444 | if (rc) | 2532 | if (rc) |
@@ -2451,7 +2539,7 @@ int security_node_sid(u16 domain, | |||
2451 | 2539 | ||
2452 | rc = 0; | 2540 | rc = 0; |
2453 | out: | 2541 | out: |
2454 | read_unlock(&policy_rwlock); | 2542 | read_unlock(&state->ss->policy_rwlock); |
2455 | return rc; | 2543 | return rc; |
2456 | } | 2544 | } |
2457 | 2545 | ||
@@ -2471,11 +2559,14 @@ out: | |||
2471 | * number of elements in the array. | 2559 | * number of elements in the array. |
2472 | */ | 2560 | */ |
2473 | 2561 | ||
2474 | int security_get_user_sids(u32 fromsid, | 2562 | int security_get_user_sids(struct selinux_state *state, |
2563 | u32 fromsid, | ||
2475 | char *username, | 2564 | char *username, |
2476 | u32 **sids, | 2565 | u32 **sids, |
2477 | u32 *nel) | 2566 | u32 *nel) |
2478 | { | 2567 | { |
2568 | struct policydb *policydb; | ||
2569 | struct sidtab *sidtab; | ||
2479 | struct context *fromcon, usercon; | 2570 | struct context *fromcon, usercon; |
2480 | u32 *mysids = NULL, *mysids2, sid; | 2571 | u32 *mysids = NULL, *mysids2, sid; |
2481 | u32 mynel = 0, maxnel = SIDS_NEL; | 2572 | u32 mynel = 0, maxnel = SIDS_NEL; |
@@ -2487,20 +2578,23 @@ int security_get_user_sids(u32 fromsid, | |||
2487 | *sids = NULL; | 2578 | *sids = NULL; |
2488 | *nel = 0; | 2579 | *nel = 0; |
2489 | 2580 | ||
2490 | if (!ss_initialized) | 2581 | if (!state->initialized) |
2491 | goto out; | 2582 | goto out; |
2492 | 2583 | ||
2493 | read_lock(&policy_rwlock); | 2584 | read_lock(&state->ss->policy_rwlock); |
2585 | |||
2586 | policydb = &state->ss->policydb; | ||
2587 | sidtab = &state->ss->sidtab; | ||
2494 | 2588 | ||
2495 | context_init(&usercon); | 2589 | context_init(&usercon); |
2496 | 2590 | ||
2497 | rc = -EINVAL; | 2591 | rc = -EINVAL; |
2498 | fromcon = sidtab_search(&sidtab, fromsid); | 2592 | fromcon = sidtab_search(sidtab, fromsid); |
2499 | if (!fromcon) | 2593 | if (!fromcon) |
2500 | goto out_unlock; | 2594 | goto out_unlock; |
2501 | 2595 | ||
2502 | rc = -EINVAL; | 2596 | rc = -EINVAL; |
2503 | user = hashtab_search(policydb.p_users.table, username); | 2597 | user = hashtab_search(policydb->p_users.table, username); |
2504 | if (!user) | 2598 | if (!user) |
2505 | goto out_unlock; | 2599 | goto out_unlock; |
2506 | 2600 | ||
@@ -2512,15 +2606,16 @@ int security_get_user_sids(u32 fromsid, | |||
2512 | goto out_unlock; | 2606 | goto out_unlock; |
2513 | 2607 | ||
2514 | ebitmap_for_each_positive_bit(&user->roles, rnode, i) { | 2608 | ebitmap_for_each_positive_bit(&user->roles, rnode, i) { |
2515 | role = policydb.role_val_to_struct[i]; | 2609 | role = policydb->role_val_to_struct[i]; |
2516 | usercon.role = i + 1; | 2610 | usercon.role = i + 1; |
2517 | ebitmap_for_each_positive_bit(&role->types, tnode, j) { | 2611 | ebitmap_for_each_positive_bit(&role->types, tnode, j) { |
2518 | usercon.type = j + 1; | 2612 | usercon.type = j + 1; |
2519 | 2613 | ||
2520 | if (mls_setup_user_range(fromcon, user, &usercon)) | 2614 | if (mls_setup_user_range(policydb, fromcon, user, |
2615 | &usercon)) | ||
2521 | continue; | 2616 | continue; |
2522 | 2617 | ||
2523 | rc = sidtab_context_to_sid(&sidtab, &usercon, &sid); | 2618 | rc = sidtab_context_to_sid(sidtab, &usercon, &sid); |
2524 | if (rc) | 2619 | if (rc) |
2525 | goto out_unlock; | 2620 | goto out_unlock; |
2526 | if (mynel < maxnel) { | 2621 | if (mynel < maxnel) { |
@@ -2540,7 +2635,7 @@ int security_get_user_sids(u32 fromsid, | |||
2540 | } | 2635 | } |
2541 | rc = 0; | 2636 | rc = 0; |
2542 | out_unlock: | 2637 | out_unlock: |
2543 | read_unlock(&policy_rwlock); | 2638 | read_unlock(&state->ss->policy_rwlock); |
2544 | if (rc || !mynel) { | 2639 | if (rc || !mynel) { |
2545 | kfree(mysids); | 2640 | kfree(mysids); |
2546 | goto out; | 2641 | goto out; |
@@ -2583,11 +2678,14 @@ out: | |||
2583 | * | 2678 | * |
2584 | * The caller must acquire the policy_rwlock before calling this function. | 2679 | * The caller must acquire the policy_rwlock before calling this function. |
2585 | */ | 2680 | */ |
2586 | static inline int __security_genfs_sid(const char *fstype, | 2681 | static inline int __security_genfs_sid(struct selinux_state *state, |
2682 | const char *fstype, | ||
2587 | char *path, | 2683 | char *path, |
2588 | u16 orig_sclass, | 2684 | u16 orig_sclass, |
2589 | u32 *sid) | 2685 | u32 *sid) |
2590 | { | 2686 | { |
2687 | struct policydb *policydb = &state->ss->policydb; | ||
2688 | struct sidtab *sidtab = &state->ss->sidtab; | ||
2591 | int len; | 2689 | int len; |
2592 | u16 sclass; | 2690 | u16 sclass; |
2593 | struct genfs *genfs; | 2691 | struct genfs *genfs; |
@@ -2597,10 +2695,10 @@ static inline int __security_genfs_sid(const char *fstype, | |||
2597 | while (path[0] == '/' && path[1] == '/') | 2695 | while (path[0] == '/' && path[1] == '/') |
2598 | path++; | 2696 | path++; |
2599 | 2697 | ||
2600 | sclass = unmap_class(orig_sclass); | 2698 | sclass = unmap_class(&state->ss->map, orig_sclass); |
2601 | *sid = SECINITSID_UNLABELED; | 2699 | *sid = SECINITSID_UNLABELED; |
2602 | 2700 | ||
2603 | for (genfs = policydb.genfs; genfs; genfs = genfs->next) { | 2701 | for (genfs = policydb->genfs; genfs; genfs = genfs->next) { |
2604 | cmp = strcmp(fstype, genfs->fstype); | 2702 | cmp = strcmp(fstype, genfs->fstype); |
2605 | if (cmp <= 0) | 2703 | if (cmp <= 0) |
2606 | break; | 2704 | break; |
@@ -2622,7 +2720,7 @@ static inline int __security_genfs_sid(const char *fstype, | |||
2622 | goto out; | 2720 | goto out; |
2623 | 2721 | ||
2624 | if (!c->sid[0]) { | 2722 | if (!c->sid[0]) { |
2625 | rc = sidtab_context_to_sid(&sidtab, &c->context[0], &c->sid[0]); | 2723 | rc = sidtab_context_to_sid(sidtab, &c->context[0], &c->sid[0]); |
2626 | if (rc) | 2724 | if (rc) |
2627 | goto out; | 2725 | goto out; |
2628 | } | 2726 | } |
@@ -2643,16 +2741,17 @@ out: | |||
2643 | * Acquire policy_rwlock before calling __security_genfs_sid() and release | 2741 | * Acquire policy_rwlock before calling __security_genfs_sid() and release |
2644 | * it afterward. | 2742 | * it afterward. |
2645 | */ | 2743 | */ |
2646 | int security_genfs_sid(const char *fstype, | 2744 | int security_genfs_sid(struct selinux_state *state, |
2745 | const char *fstype, | ||
2647 | char *path, | 2746 | char *path, |
2648 | u16 orig_sclass, | 2747 | u16 orig_sclass, |
2649 | u32 *sid) | 2748 | u32 *sid) |
2650 | { | 2749 | { |
2651 | int retval; | 2750 | int retval; |
2652 | 2751 | ||
2653 | read_lock(&policy_rwlock); | 2752 | read_lock(&state->ss->policy_rwlock); |
2654 | retval = __security_genfs_sid(fstype, path, orig_sclass, sid); | 2753 | retval = __security_genfs_sid(state, fstype, path, orig_sclass, sid); |
2655 | read_unlock(&policy_rwlock); | 2754 | read_unlock(&state->ss->policy_rwlock); |
2656 | return retval; | 2755 | return retval; |
2657 | } | 2756 | } |
2658 | 2757 | ||
@@ -2660,16 +2759,21 @@ int security_genfs_sid(const char *fstype, | |||
2660 | * security_fs_use - Determine how to handle labeling for a filesystem. | 2759 | * security_fs_use - Determine how to handle labeling for a filesystem. |
2661 | * @sb: superblock in question | 2760 | * @sb: superblock in question |
2662 | */ | 2761 | */ |
2663 | int security_fs_use(struct super_block *sb) | 2762 | int security_fs_use(struct selinux_state *state, struct super_block *sb) |
2664 | { | 2763 | { |
2764 | struct policydb *policydb; | ||
2765 | struct sidtab *sidtab; | ||
2665 | int rc = 0; | 2766 | int rc = 0; |
2666 | struct ocontext *c; | 2767 | struct ocontext *c; |
2667 | struct superblock_security_struct *sbsec = sb->s_security; | 2768 | struct superblock_security_struct *sbsec = sb->s_security; |
2668 | const char *fstype = sb->s_type->name; | 2769 | const char *fstype = sb->s_type->name; |
2669 | 2770 | ||
2670 | read_lock(&policy_rwlock); | 2771 | read_lock(&state->ss->policy_rwlock); |
2772 | |||
2773 | policydb = &state->ss->policydb; | ||
2774 | sidtab = &state->ss->sidtab; | ||
2671 | 2775 | ||
2672 | c = policydb.ocontexts[OCON_FSUSE]; | 2776 | c = policydb->ocontexts[OCON_FSUSE]; |
2673 | while (c) { | 2777 | while (c) { |
2674 | if (strcmp(fstype, c->u.name) == 0) | 2778 | if (strcmp(fstype, c->u.name) == 0) |
2675 | break; | 2779 | break; |
@@ -2679,14 +2783,14 @@ int security_fs_use(struct super_block *sb) | |||
2679 | if (c) { | 2783 | if (c) { |
2680 | sbsec->behavior = c->v.behavior; | 2784 | sbsec->behavior = c->v.behavior; |
2681 | if (!c->sid[0]) { | 2785 | if (!c->sid[0]) { |
2682 | rc = sidtab_context_to_sid(&sidtab, &c->context[0], | 2786 | rc = sidtab_context_to_sid(sidtab, &c->context[0], |
2683 | &c->sid[0]); | 2787 | &c->sid[0]); |
2684 | if (rc) | 2788 | if (rc) |
2685 | goto out; | 2789 | goto out; |
2686 | } | 2790 | } |
2687 | sbsec->sid = c->sid[0]; | 2791 | sbsec->sid = c->sid[0]; |
2688 | } else { | 2792 | } else { |
2689 | rc = __security_genfs_sid(fstype, "/", SECCLASS_DIR, | 2793 | rc = __security_genfs_sid(state, fstype, "/", SECCLASS_DIR, |
2690 | &sbsec->sid); | 2794 | &sbsec->sid); |
2691 | if (rc) { | 2795 | if (rc) { |
2692 | sbsec->behavior = SECURITY_FS_USE_NONE; | 2796 | sbsec->behavior = SECURITY_FS_USE_NONE; |
@@ -2697,20 +2801,25 @@ int security_fs_use(struct super_block *sb) | |||
2697 | } | 2801 | } |
2698 | 2802 | ||
2699 | out: | 2803 | out: |
2700 | read_unlock(&policy_rwlock); | 2804 | read_unlock(&state->ss->policy_rwlock); |
2701 | return rc; | 2805 | return rc; |
2702 | } | 2806 | } |
2703 | 2807 | ||
2704 | int security_get_bools(int *len, char ***names, int **values) | 2808 | int security_get_bools(struct selinux_state *state, |
2809 | int *len, char ***names, int **values) | ||
2705 | { | 2810 | { |
2811 | struct policydb *policydb; | ||
2706 | int i, rc; | 2812 | int i, rc; |
2707 | 2813 | ||
2708 | read_lock(&policy_rwlock); | 2814 | read_lock(&state->ss->policy_rwlock); |
2815 | |||
2816 | policydb = &state->ss->policydb; | ||
2817 | |||
2709 | *names = NULL; | 2818 | *names = NULL; |
2710 | *values = NULL; | 2819 | *values = NULL; |
2711 | 2820 | ||
2712 | rc = 0; | 2821 | rc = 0; |
2713 | *len = policydb.p_bools.nprim; | 2822 | *len = policydb->p_bools.nprim; |
2714 | if (!*len) | 2823 | if (!*len) |
2715 | goto out; | 2824 | goto out; |
2716 | 2825 | ||
@@ -2725,16 +2834,17 @@ int security_get_bools(int *len, char ***names, int **values) | |||
2725 | goto err; | 2834 | goto err; |
2726 | 2835 | ||
2727 | for (i = 0; i < *len; i++) { | 2836 | for (i = 0; i < *len; i++) { |
2728 | (*values)[i] = policydb.bool_val_to_struct[i]->state; | 2837 | (*values)[i] = policydb->bool_val_to_struct[i]->state; |
2729 | 2838 | ||
2730 | rc = -ENOMEM; | 2839 | rc = -ENOMEM; |
2731 | (*names)[i] = kstrdup(sym_name(&policydb, SYM_BOOLS, i), GFP_ATOMIC); | 2840 | (*names)[i] = kstrdup(sym_name(policydb, SYM_BOOLS, i), |
2841 | GFP_ATOMIC); | ||
2732 | if (!(*names)[i]) | 2842 | if (!(*names)[i]) |
2733 | goto err; | 2843 | goto err; |
2734 | } | 2844 | } |
2735 | rc = 0; | 2845 | rc = 0; |
2736 | out: | 2846 | out: |
2737 | read_unlock(&policy_rwlock); | 2847 | read_unlock(&state->ss->policy_rwlock); |
2738 | return rc; | 2848 | return rc; |
2739 | err: | 2849 | err: |
2740 | if (*names) { | 2850 | if (*names) { |
@@ -2746,90 +2856,98 @@ err: | |||
2746 | } | 2856 | } |
2747 | 2857 | ||
2748 | 2858 | ||
2749 | int security_set_bools(int len, int *values) | 2859 | int security_set_bools(struct selinux_state *state, int len, int *values) |
2750 | { | 2860 | { |
2861 | struct policydb *policydb; | ||
2751 | int i, rc; | 2862 | int i, rc; |
2752 | int lenp, seqno = 0; | 2863 | int lenp, seqno = 0; |
2753 | struct cond_node *cur; | 2864 | struct cond_node *cur; |
2754 | 2865 | ||
2755 | write_lock_irq(&policy_rwlock); | 2866 | write_lock_irq(&state->ss->policy_rwlock); |
2867 | |||
2868 | policydb = &state->ss->policydb; | ||
2756 | 2869 | ||
2757 | rc = -EFAULT; | 2870 | rc = -EFAULT; |
2758 | lenp = policydb.p_bools.nprim; | 2871 | lenp = policydb->p_bools.nprim; |
2759 | if (len != lenp) | 2872 | if (len != lenp) |
2760 | goto out; | 2873 | goto out; |
2761 | 2874 | ||
2762 | for (i = 0; i < len; i++) { | 2875 | for (i = 0; i < len; i++) { |
2763 | if (!!values[i] != policydb.bool_val_to_struct[i]->state) { | 2876 | if (!!values[i] != policydb->bool_val_to_struct[i]->state) { |
2764 | audit_log(current->audit_context, GFP_ATOMIC, | 2877 | audit_log(current->audit_context, GFP_ATOMIC, |
2765 | AUDIT_MAC_CONFIG_CHANGE, | 2878 | AUDIT_MAC_CONFIG_CHANGE, |
2766 | "bool=%s val=%d old_val=%d auid=%u ses=%u", | 2879 | "bool=%s val=%d old_val=%d auid=%u ses=%u", |
2767 | sym_name(&policydb, SYM_BOOLS, i), | 2880 | sym_name(policydb, SYM_BOOLS, i), |
2768 | !!values[i], | 2881 | !!values[i], |
2769 | policydb.bool_val_to_struct[i]->state, | 2882 | policydb->bool_val_to_struct[i]->state, |
2770 | from_kuid(&init_user_ns, audit_get_loginuid(current)), | 2883 | from_kuid(&init_user_ns, audit_get_loginuid(current)), |
2771 | audit_get_sessionid(current)); | 2884 | audit_get_sessionid(current)); |
2772 | } | 2885 | } |
2773 | if (values[i]) | 2886 | if (values[i]) |
2774 | policydb.bool_val_to_struct[i]->state = 1; | 2887 | policydb->bool_val_to_struct[i]->state = 1; |
2775 | else | 2888 | else |
2776 | policydb.bool_val_to_struct[i]->state = 0; | 2889 | policydb->bool_val_to_struct[i]->state = 0; |
2777 | } | 2890 | } |
2778 | 2891 | ||
2779 | for (cur = policydb.cond_list; cur; cur = cur->next) { | 2892 | for (cur = policydb->cond_list; cur; cur = cur->next) { |
2780 | rc = evaluate_cond_node(&policydb, cur); | 2893 | rc = evaluate_cond_node(policydb, cur); |
2781 | if (rc) | 2894 | if (rc) |
2782 | goto out; | 2895 | goto out; |
2783 | } | 2896 | } |
2784 | 2897 | ||
2785 | seqno = ++latest_granting; | 2898 | seqno = ++state->ss->latest_granting; |
2786 | rc = 0; | 2899 | rc = 0; |
2787 | out: | 2900 | out: |
2788 | write_unlock_irq(&policy_rwlock); | 2901 | write_unlock_irq(&state->ss->policy_rwlock); |
2789 | if (!rc) { | 2902 | if (!rc) { |
2790 | avc_ss_reset(seqno); | 2903 | avc_ss_reset(seqno); |
2791 | selnl_notify_policyload(seqno); | 2904 | selnl_notify_policyload(seqno); |
2792 | selinux_status_update_policyload(seqno); | 2905 | selinux_status_update_policyload(state, seqno); |
2793 | selinux_xfrm_notify_policyload(); | 2906 | selinux_xfrm_notify_policyload(); |
2794 | } | 2907 | } |
2795 | return rc; | 2908 | return rc; |
2796 | } | 2909 | } |
2797 | 2910 | ||
2798 | int security_get_bool_value(int index) | 2911 | int security_get_bool_value(struct selinux_state *state, |
2912 | int index) | ||
2799 | { | 2913 | { |
2914 | struct policydb *policydb; | ||
2800 | int rc; | 2915 | int rc; |
2801 | int len; | 2916 | int len; |
2802 | 2917 | ||
2803 | read_lock(&policy_rwlock); | 2918 | read_lock(&state->ss->policy_rwlock); |
2919 | |||
2920 | policydb = &state->ss->policydb; | ||
2804 | 2921 | ||
2805 | rc = -EFAULT; | 2922 | rc = -EFAULT; |
2806 | len = policydb.p_bools.nprim; | 2923 | len = policydb->p_bools.nprim; |
2807 | if (index >= len) | 2924 | if (index >= len) |
2808 | goto out; | 2925 | goto out; |
2809 | 2926 | ||
2810 | rc = policydb.bool_val_to_struct[index]->state; | 2927 | rc = policydb->bool_val_to_struct[index]->state; |
2811 | out: | 2928 | out: |
2812 | read_unlock(&policy_rwlock); | 2929 | read_unlock(&state->ss->policy_rwlock); |
2813 | return rc; | 2930 | return rc; |
2814 | } | 2931 | } |
2815 | 2932 | ||
2816 | static int security_preserve_bools(struct policydb *p) | 2933 | static int security_preserve_bools(struct selinux_state *state, |
2934 | struct policydb *policydb) | ||
2817 | { | 2935 | { |
2818 | int rc, nbools = 0, *bvalues = NULL, i; | 2936 | int rc, nbools = 0, *bvalues = NULL, i; |
2819 | char **bnames = NULL; | 2937 | char **bnames = NULL; |
2820 | struct cond_bool_datum *booldatum; | 2938 | struct cond_bool_datum *booldatum; |
2821 | struct cond_node *cur; | 2939 | struct cond_node *cur; |
2822 | 2940 | ||
2823 | rc = security_get_bools(&nbools, &bnames, &bvalues); | 2941 | rc = security_get_bools(state, &nbools, &bnames, &bvalues); |
2824 | if (rc) | 2942 | if (rc) |
2825 | goto out; | 2943 | goto out; |
2826 | for (i = 0; i < nbools; i++) { | 2944 | for (i = 0; i < nbools; i++) { |
2827 | booldatum = hashtab_search(p->p_bools.table, bnames[i]); | 2945 | booldatum = hashtab_search(policydb->p_bools.table, bnames[i]); |
2828 | if (booldatum) | 2946 | if (booldatum) |
2829 | booldatum->state = bvalues[i]; | 2947 | booldatum->state = bvalues[i]; |
2830 | } | 2948 | } |
2831 | for (cur = p->cond_list; cur; cur = cur->next) { | 2949 | for (cur = policydb->cond_list; cur; cur = cur->next) { |
2832 | rc = evaluate_cond_node(p, cur); | 2950 | rc = evaluate_cond_node(policydb, cur); |
2833 | if (rc) | 2951 | if (rc) |
2834 | goto out; | 2952 | goto out; |
2835 | } | 2953 | } |
@@ -2848,8 +2966,11 @@ out: | |||
2848 | * security_sid_mls_copy() - computes a new sid based on the given | 2966 | * security_sid_mls_copy() - computes a new sid based on the given |
2849 | * sid and the mls portion of mls_sid. | 2967 | * sid and the mls portion of mls_sid. |
2850 | */ | 2968 | */ |
2851 | int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) | 2969 | int security_sid_mls_copy(struct selinux_state *state, |
2970 | u32 sid, u32 mls_sid, u32 *new_sid) | ||
2852 | { | 2971 | { |
2972 | struct policydb *policydb = &state->ss->policydb; | ||
2973 | struct sidtab *sidtab = &state->ss->sidtab; | ||
2853 | struct context *context1; | 2974 | struct context *context1; |
2854 | struct context *context2; | 2975 | struct context *context2; |
2855 | struct context newcon; | 2976 | struct context newcon; |
@@ -2858,17 +2979,17 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) | |||
2858 | int rc; | 2979 | int rc; |
2859 | 2980 | ||
2860 | rc = 0; | 2981 | rc = 0; |
2861 | if (!ss_initialized || !policydb.mls_enabled) { | 2982 | if (!state->initialized || !policydb->mls_enabled) { |
2862 | *new_sid = sid; | 2983 | *new_sid = sid; |
2863 | goto out; | 2984 | goto out; |
2864 | } | 2985 | } |
2865 | 2986 | ||
2866 | context_init(&newcon); | 2987 | context_init(&newcon); |
2867 | 2988 | ||
2868 | read_lock(&policy_rwlock); | 2989 | read_lock(&state->ss->policy_rwlock); |
2869 | 2990 | ||
2870 | rc = -EINVAL; | 2991 | rc = -EINVAL; |
2871 | context1 = sidtab_search(&sidtab, sid); | 2992 | context1 = sidtab_search(sidtab, sid); |
2872 | if (!context1) { | 2993 | if (!context1) { |
2873 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 2994 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
2874 | __func__, sid); | 2995 | __func__, sid); |
@@ -2876,7 +2997,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) | |||
2876 | } | 2997 | } |
2877 | 2998 | ||
2878 | rc = -EINVAL; | 2999 | rc = -EINVAL; |
2879 | context2 = sidtab_search(&sidtab, mls_sid); | 3000 | context2 = sidtab_search(sidtab, mls_sid); |
2880 | if (!context2) { | 3001 | if (!context2) { |
2881 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 3002 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
2882 | __func__, mls_sid); | 3003 | __func__, mls_sid); |
@@ -2891,10 +3012,11 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) | |||
2891 | goto out_unlock; | 3012 | goto out_unlock; |
2892 | 3013 | ||
2893 | /* Check the validity of the new context. */ | 3014 | /* Check the validity of the new context. */ |
2894 | if (!policydb_context_isvalid(&policydb, &newcon)) { | 3015 | if (!policydb_context_isvalid(policydb, &newcon)) { |
2895 | rc = convert_context_handle_invalid_context(&newcon); | 3016 | rc = convert_context_handle_invalid_context(state, &newcon); |
2896 | if (rc) { | 3017 | if (rc) { |
2897 | if (!context_struct_to_string(&newcon, &s, &len)) { | 3018 | if (!context_struct_to_string(policydb, &newcon, &s, |
3019 | &len)) { | ||
2898 | audit_log(current->audit_context, | 3020 | audit_log(current->audit_context, |
2899 | GFP_ATOMIC, AUDIT_SELINUX_ERR, | 3021 | GFP_ATOMIC, AUDIT_SELINUX_ERR, |
2900 | "op=security_sid_mls_copy " | 3022 | "op=security_sid_mls_copy " |
@@ -2905,9 +3027,9 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid) | |||
2905 | } | 3027 | } |
2906 | } | 3028 | } |
2907 | 3029 | ||
2908 | rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid); | 3030 | rc = sidtab_context_to_sid(sidtab, &newcon, new_sid); |
2909 | out_unlock: | 3031 | out_unlock: |
2910 | read_unlock(&policy_rwlock); | 3032 | read_unlock(&state->ss->policy_rwlock); |
2911 | context_destroy(&newcon); | 3033 | context_destroy(&newcon); |
2912 | out: | 3034 | out: |
2913 | return rc; | 3035 | return rc; |
@@ -2933,10 +3055,13 @@ out: | |||
2933 | * multiple, inconsistent labels | -<errno> | SECSID_NULL | 3055 | * multiple, inconsistent labels | -<errno> | SECSID_NULL |
2934 | * | 3056 | * |
2935 | */ | 3057 | */ |
2936 | int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, | 3058 | int security_net_peersid_resolve(struct selinux_state *state, |
3059 | u32 nlbl_sid, u32 nlbl_type, | ||
2937 | u32 xfrm_sid, | 3060 | u32 xfrm_sid, |
2938 | u32 *peer_sid) | 3061 | u32 *peer_sid) |
2939 | { | 3062 | { |
3063 | struct policydb *policydb = &state->ss->policydb; | ||
3064 | struct sidtab *sidtab = &state->ss->sidtab; | ||
2940 | int rc; | 3065 | int rc; |
2941 | struct context *nlbl_ctx; | 3066 | struct context *nlbl_ctx; |
2942 | struct context *xfrm_ctx; | 3067 | struct context *xfrm_ctx; |
@@ -2958,23 +3083,25 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, | |||
2958 | return 0; | 3083 | return 0; |
2959 | } | 3084 | } |
2960 | 3085 | ||
2961 | /* we don't need to check ss_initialized here since the only way both | 3086 | /* |
3087 | * We don't need to check initialized here since the only way both | ||
2962 | * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the | 3088 | * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the |
2963 | * security server was initialized and ss_initialized was true */ | 3089 | * security server was initialized and state->initialized was true. |
2964 | if (!policydb.mls_enabled) | 3090 | */ |
3091 | if (!policydb->mls_enabled) | ||
2965 | return 0; | 3092 | return 0; |
2966 | 3093 | ||
2967 | read_lock(&policy_rwlock); | 3094 | read_lock(&state->ss->policy_rwlock); |
2968 | 3095 | ||
2969 | rc = -EINVAL; | 3096 | rc = -EINVAL; |
2970 | nlbl_ctx = sidtab_search(&sidtab, nlbl_sid); | 3097 | nlbl_ctx = sidtab_search(sidtab, nlbl_sid); |
2971 | if (!nlbl_ctx) { | 3098 | if (!nlbl_ctx) { |
2972 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 3099 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
2973 | __func__, nlbl_sid); | 3100 | __func__, nlbl_sid); |
2974 | goto out; | 3101 | goto out; |
2975 | } | 3102 | } |
2976 | rc = -EINVAL; | 3103 | rc = -EINVAL; |
2977 | xfrm_ctx = sidtab_search(&sidtab, xfrm_sid); | 3104 | xfrm_ctx = sidtab_search(sidtab, xfrm_sid); |
2978 | if (!xfrm_ctx) { | 3105 | if (!xfrm_ctx) { |
2979 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", | 3106 | printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", |
2980 | __func__, xfrm_sid); | 3107 | __func__, xfrm_sid); |
@@ -2991,7 +3118,7 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type, | |||
2991 | * expressive */ | 3118 | * expressive */ |
2992 | *peer_sid = xfrm_sid; | 3119 | *peer_sid = xfrm_sid; |
2993 | out: | 3120 | out: |
2994 | read_unlock(&policy_rwlock); | 3121 | read_unlock(&state->ss->policy_rwlock); |
2995 | return rc; | 3122 | return rc; |
2996 | } | 3123 | } |
2997 | 3124 | ||
@@ -3008,19 +3135,21 @@ static int get_classes_callback(void *k, void *d, void *args) | |||
3008 | return 0; | 3135 | return 0; |
3009 | } | 3136 | } |
3010 | 3137 | ||
3011 | int security_get_classes(char ***classes, int *nclasses) | 3138 | int security_get_classes(struct selinux_state *state, |
3139 | char ***classes, int *nclasses) | ||
3012 | { | 3140 | { |
3141 | struct policydb *policydb = &state->ss->policydb; | ||
3013 | int rc; | 3142 | int rc; |
3014 | 3143 | ||
3015 | read_lock(&policy_rwlock); | 3144 | read_lock(&state->ss->policy_rwlock); |
3016 | 3145 | ||
3017 | rc = -ENOMEM; | 3146 | rc = -ENOMEM; |
3018 | *nclasses = policydb.p_classes.nprim; | 3147 | *nclasses = policydb->p_classes.nprim; |
3019 | *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC); | 3148 | *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC); |
3020 | if (!*classes) | 3149 | if (!*classes) |
3021 | goto out; | 3150 | goto out; |
3022 | 3151 | ||
3023 | rc = hashtab_map(policydb.p_classes.table, get_classes_callback, | 3152 | rc = hashtab_map(policydb->p_classes.table, get_classes_callback, |
3024 | *classes); | 3153 | *classes); |
3025 | if (rc) { | 3154 | if (rc) { |
3026 | int i; | 3155 | int i; |
@@ -3030,7 +3159,7 @@ int security_get_classes(char ***classes, int *nclasses) | |||
3030 | } | 3159 | } |
3031 | 3160 | ||
3032 | out: | 3161 | out: |
3033 | read_unlock(&policy_rwlock); | 3162 | read_unlock(&state->ss->policy_rwlock); |
3034 | return rc; | 3163 | return rc; |
3035 | } | 3164 | } |
3036 | 3165 | ||
@@ -3047,15 +3176,17 @@ static int get_permissions_callback(void *k, void *d, void *args) | |||
3047 | return 0; | 3176 | return 0; |
3048 | } | 3177 | } |
3049 | 3178 | ||
3050 | int security_get_permissions(char *class, char ***perms, int *nperms) | 3179 | int security_get_permissions(struct selinux_state *state, |
3180 | char *class, char ***perms, int *nperms) | ||
3051 | { | 3181 | { |
3182 | struct policydb *policydb = &state->ss->policydb; | ||
3052 | int rc, i; | 3183 | int rc, i; |
3053 | struct class_datum *match; | 3184 | struct class_datum *match; |
3054 | 3185 | ||
3055 | read_lock(&policy_rwlock); | 3186 | read_lock(&state->ss->policy_rwlock); |
3056 | 3187 | ||
3057 | rc = -EINVAL; | 3188 | rc = -EINVAL; |
3058 | match = hashtab_search(policydb.p_classes.table, class); | 3189 | match = hashtab_search(policydb->p_classes.table, class); |
3059 | if (!match) { | 3190 | if (!match) { |
3060 | printk(KERN_ERR "SELinux: %s: unrecognized class %s\n", | 3191 | printk(KERN_ERR "SELinux: %s: unrecognized class %s\n", |
3061 | __func__, class); | 3192 | __func__, class); |
@@ -3081,25 +3212,25 @@ int security_get_permissions(char *class, char ***perms, int *nperms) | |||
3081 | goto err; | 3212 | goto err; |
3082 | 3213 | ||
3083 | out: | 3214 | out: |
3084 | read_unlock(&policy_rwlock); | 3215 | read_unlock(&state->ss->policy_rwlock); |
3085 | return rc; | 3216 | return rc; |
3086 | 3217 | ||
3087 | err: | 3218 | err: |
3088 | read_unlock(&policy_rwlock); | 3219 | read_unlock(&state->ss->policy_rwlock); |
3089 | for (i = 0; i < *nperms; i++) | 3220 | for (i = 0; i < *nperms; i++) |
3090 | kfree((*perms)[i]); | 3221 | kfree((*perms)[i]); |
3091 | kfree(*perms); | 3222 | kfree(*perms); |
3092 | return rc; | 3223 | return rc; |
3093 | } | 3224 | } |
3094 | 3225 | ||
3095 | int security_get_reject_unknown(void) | 3226 | int security_get_reject_unknown(struct selinux_state *state) |
3096 | { | 3227 | { |
3097 | return policydb.reject_unknown; | 3228 | return state->ss->policydb.reject_unknown; |
3098 | } | 3229 | } |
3099 | 3230 | ||
3100 | int security_get_allow_unknown(void) | 3231 | int security_get_allow_unknown(struct selinux_state *state) |
3101 | { | 3232 | { |
3102 | return policydb.allow_unknown; | 3233 | return state->ss->policydb.allow_unknown; |
3103 | } | 3234 | } |
3104 | 3235 | ||
3105 | /** | 3236 | /** |
@@ -3112,13 +3243,15 @@ int security_get_allow_unknown(void) | |||
3112 | * supported, false (0) if it isn't supported. | 3243 | * supported, false (0) if it isn't supported. |
3113 | * | 3244 | * |
3114 | */ | 3245 | */ |
3115 | int security_policycap_supported(unsigned int req_cap) | 3246 | int security_policycap_supported(struct selinux_state *state, |
3247 | unsigned int req_cap) | ||
3116 | { | 3248 | { |
3249 | struct policydb *policydb = &state->ss->policydb; | ||
3117 | int rc; | 3250 | int rc; |
3118 | 3251 | ||
3119 | read_lock(&policy_rwlock); | 3252 | read_lock(&state->ss->policy_rwlock); |
3120 | rc = ebitmap_get_bit(&policydb.policycaps, req_cap); | 3253 | rc = ebitmap_get_bit(&policydb->policycaps, req_cap); |
3121 | read_unlock(&policy_rwlock); | 3254 | read_unlock(&state->ss->policy_rwlock); |
3122 | 3255 | ||
3123 | return rc; | 3256 | return rc; |
3124 | } | 3257 | } |
@@ -3140,6 +3273,8 @@ void selinux_audit_rule_free(void *vrule) | |||
3140 | 3273 | ||
3141 | int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) | 3274 | int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) |
3142 | { | 3275 | { |
3276 | struct selinux_state *state = &selinux_state; | ||
3277 | struct policydb *policydb = &state->ss->policydb; | ||
3143 | struct selinux_audit_rule *tmprule; | 3278 | struct selinux_audit_rule *tmprule; |
3144 | struct role_datum *roledatum; | 3279 | struct role_datum *roledatum; |
3145 | struct type_datum *typedatum; | 3280 | struct type_datum *typedatum; |
@@ -3149,7 +3284,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) | |||
3149 | 3284 | ||
3150 | *rule = NULL; | 3285 | *rule = NULL; |
3151 | 3286 | ||
3152 | if (!ss_initialized) | 3287 | if (!state->initialized) |
3153 | return -EOPNOTSUPP; | 3288 | return -EOPNOTSUPP; |
3154 | 3289 | ||
3155 | switch (field) { | 3290 | switch (field) { |
@@ -3182,15 +3317,15 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) | |||
3182 | 3317 | ||
3183 | context_init(&tmprule->au_ctxt); | 3318 | context_init(&tmprule->au_ctxt); |
3184 | 3319 | ||
3185 | read_lock(&policy_rwlock); | 3320 | read_lock(&state->ss->policy_rwlock); |
3186 | 3321 | ||
3187 | tmprule->au_seqno = latest_granting; | 3322 | tmprule->au_seqno = state->ss->latest_granting; |
3188 | 3323 | ||
3189 | switch (field) { | 3324 | switch (field) { |
3190 | case AUDIT_SUBJ_USER: | 3325 | case AUDIT_SUBJ_USER: |
3191 | case AUDIT_OBJ_USER: | 3326 | case AUDIT_OBJ_USER: |
3192 | rc = -EINVAL; | 3327 | rc = -EINVAL; |
3193 | userdatum = hashtab_search(policydb.p_users.table, rulestr); | 3328 | userdatum = hashtab_search(policydb->p_users.table, rulestr); |
3194 | if (!userdatum) | 3329 | if (!userdatum) |
3195 | goto out; | 3330 | goto out; |
3196 | tmprule->au_ctxt.user = userdatum->value; | 3331 | tmprule->au_ctxt.user = userdatum->value; |
@@ -3198,7 +3333,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) | |||
3198 | case AUDIT_SUBJ_ROLE: | 3333 | case AUDIT_SUBJ_ROLE: |
3199 | case AUDIT_OBJ_ROLE: | 3334 | case AUDIT_OBJ_ROLE: |
3200 | rc = -EINVAL; | 3335 | rc = -EINVAL; |
3201 | roledatum = hashtab_search(policydb.p_roles.table, rulestr); | 3336 | roledatum = hashtab_search(policydb->p_roles.table, rulestr); |
3202 | if (!roledatum) | 3337 | if (!roledatum) |
3203 | goto out; | 3338 | goto out; |
3204 | tmprule->au_ctxt.role = roledatum->value; | 3339 | tmprule->au_ctxt.role = roledatum->value; |
@@ -3206,7 +3341,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) | |||
3206 | case AUDIT_SUBJ_TYPE: | 3341 | case AUDIT_SUBJ_TYPE: |
3207 | case AUDIT_OBJ_TYPE: | 3342 | case AUDIT_OBJ_TYPE: |
3208 | rc = -EINVAL; | 3343 | rc = -EINVAL; |
3209 | typedatum = hashtab_search(policydb.p_types.table, rulestr); | 3344 | typedatum = hashtab_search(policydb->p_types.table, rulestr); |
3210 | if (!typedatum) | 3345 | if (!typedatum) |
3211 | goto out; | 3346 | goto out; |
3212 | tmprule->au_ctxt.type = typedatum->value; | 3347 | tmprule->au_ctxt.type = typedatum->value; |
@@ -3215,14 +3350,15 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) | |||
3215 | case AUDIT_SUBJ_CLR: | 3350 | case AUDIT_SUBJ_CLR: |
3216 | case AUDIT_OBJ_LEV_LOW: | 3351 | case AUDIT_OBJ_LEV_LOW: |
3217 | case AUDIT_OBJ_LEV_HIGH: | 3352 | case AUDIT_OBJ_LEV_HIGH: |
3218 | rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC); | 3353 | rc = mls_from_string(policydb, rulestr, &tmprule->au_ctxt, |
3354 | GFP_ATOMIC); | ||
3219 | if (rc) | 3355 | if (rc) |
3220 | goto out; | 3356 | goto out; |
3221 | break; | 3357 | break; |
3222 | } | 3358 | } |
3223 | rc = 0; | 3359 | rc = 0; |
3224 | out: | 3360 | out: |
3225 | read_unlock(&policy_rwlock); | 3361 | read_unlock(&state->ss->policy_rwlock); |
3226 | 3362 | ||
3227 | if (rc) { | 3363 | if (rc) { |
3228 | selinux_audit_rule_free(tmprule); | 3364 | selinux_audit_rule_free(tmprule); |
@@ -3262,6 +3398,7 @@ int selinux_audit_rule_known(struct audit_krule *rule) | |||
3262 | int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, | 3398 | int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, |
3263 | struct audit_context *actx) | 3399 | struct audit_context *actx) |
3264 | { | 3400 | { |
3401 | struct selinux_state *state = &selinux_state; | ||
3265 | struct context *ctxt; | 3402 | struct context *ctxt; |
3266 | struct mls_level *level; | 3403 | struct mls_level *level; |
3267 | struct selinux_audit_rule *rule = vrule; | 3404 | struct selinux_audit_rule *rule = vrule; |
@@ -3272,14 +3409,14 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, | |||
3272 | return -ENOENT; | 3409 | return -ENOENT; |
3273 | } | 3410 | } |
3274 | 3411 | ||
3275 | read_lock(&policy_rwlock); | 3412 | read_lock(&state->ss->policy_rwlock); |
3276 | 3413 | ||
3277 | if (rule->au_seqno < latest_granting) { | 3414 | if (rule->au_seqno < state->ss->latest_granting) { |
3278 | match = -ESTALE; | 3415 | match = -ESTALE; |
3279 | goto out; | 3416 | goto out; |
3280 | } | 3417 | } |
3281 | 3418 | ||
3282 | ctxt = sidtab_search(&sidtab, sid); | 3419 | ctxt = sidtab_search(&state->ss->sidtab, sid); |
3283 | if (unlikely(!ctxt)) { | 3420 | if (unlikely(!ctxt)) { |
3284 | WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n", | 3421 | WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n", |
3285 | sid); | 3422 | sid); |
@@ -3363,7 +3500,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, | |||
3363 | } | 3500 | } |
3364 | 3501 | ||
3365 | out: | 3502 | out: |
3366 | read_unlock(&policy_rwlock); | 3503 | read_unlock(&state->ss->policy_rwlock); |
3367 | return match; | 3504 | return match; |
3368 | } | 3505 | } |
3369 | 3506 | ||
@@ -3437,19 +3574,22 @@ static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr, | |||
3437 | * failure. | 3574 | * failure. |
3438 | * | 3575 | * |
3439 | */ | 3576 | */ |
3440 | int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, | 3577 | int security_netlbl_secattr_to_sid(struct selinux_state *state, |
3578 | struct netlbl_lsm_secattr *secattr, | ||
3441 | u32 *sid) | 3579 | u32 *sid) |
3442 | { | 3580 | { |
3581 | struct policydb *policydb = &state->ss->policydb; | ||
3582 | struct sidtab *sidtab = &state->ss->sidtab; | ||
3443 | int rc; | 3583 | int rc; |
3444 | struct context *ctx; | 3584 | struct context *ctx; |
3445 | struct context ctx_new; | 3585 | struct context ctx_new; |
3446 | 3586 | ||
3447 | if (!ss_initialized) { | 3587 | if (!state->initialized) { |
3448 | *sid = SECSID_NULL; | 3588 | *sid = SECSID_NULL; |
3449 | return 0; | 3589 | return 0; |
3450 | } | 3590 | } |
3451 | 3591 | ||
3452 | read_lock(&policy_rwlock); | 3592 | read_lock(&state->ss->policy_rwlock); |
3453 | 3593 | ||
3454 | if (secattr->flags & NETLBL_SECATTR_CACHE) | 3594 | if (secattr->flags & NETLBL_SECATTR_CACHE) |
3455 | *sid = *(u32 *)secattr->cache->data; | 3595 | *sid = *(u32 *)secattr->cache->data; |
@@ -3457,7 +3597,7 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, | |||
3457 | *sid = secattr->attr.secid; | 3597 | *sid = secattr->attr.secid; |
3458 | else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { | 3598 | else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { |
3459 | rc = -EIDRM; | 3599 | rc = -EIDRM; |
3460 | ctx = sidtab_search(&sidtab, SECINITSID_NETMSG); | 3600 | ctx = sidtab_search(sidtab, SECINITSID_NETMSG); |
3461 | if (ctx == NULL) | 3601 | if (ctx == NULL) |
3462 | goto out; | 3602 | goto out; |
3463 | 3603 | ||
@@ -3465,17 +3605,17 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, | |||
3465 | ctx_new.user = ctx->user; | 3605 | ctx_new.user = ctx->user; |
3466 | ctx_new.role = ctx->role; | 3606 | ctx_new.role = ctx->role; |
3467 | ctx_new.type = ctx->type; | 3607 | ctx_new.type = ctx->type; |
3468 | mls_import_netlbl_lvl(&ctx_new, secattr); | 3608 | mls_import_netlbl_lvl(policydb, &ctx_new, secattr); |
3469 | if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { | 3609 | if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { |
3470 | rc = mls_import_netlbl_cat(&ctx_new, secattr); | 3610 | rc = mls_import_netlbl_cat(policydb, &ctx_new, secattr); |
3471 | if (rc) | 3611 | if (rc) |
3472 | goto out; | 3612 | goto out; |
3473 | } | 3613 | } |
3474 | rc = -EIDRM; | 3614 | rc = -EIDRM; |
3475 | if (!mls_context_isvalid(&policydb, &ctx_new)) | 3615 | if (!mls_context_isvalid(policydb, &ctx_new)) |
3476 | goto out_free; | 3616 | goto out_free; |
3477 | 3617 | ||
3478 | rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid); | 3618 | rc = sidtab_context_to_sid(sidtab, &ctx_new, sid); |
3479 | if (rc) | 3619 | if (rc) |
3480 | goto out_free; | 3620 | goto out_free; |
3481 | 3621 | ||
@@ -3485,12 +3625,12 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, | |||
3485 | } else | 3625 | } else |
3486 | *sid = SECSID_NULL; | 3626 | *sid = SECSID_NULL; |
3487 | 3627 | ||
3488 | read_unlock(&policy_rwlock); | 3628 | read_unlock(&state->ss->policy_rwlock); |
3489 | return 0; | 3629 | return 0; |
3490 | out_free: | 3630 | out_free: |
3491 | ebitmap_destroy(&ctx_new.range.level[0].cat); | 3631 | ebitmap_destroy(&ctx_new.range.level[0].cat); |
3492 | out: | 3632 | out: |
3493 | read_unlock(&policy_rwlock); | 3633 | read_unlock(&state->ss->policy_rwlock); |
3494 | return rc; | 3634 | return rc; |
3495 | } | 3635 | } |
3496 | 3636 | ||
@@ -3504,33 +3644,35 @@ out: | |||
3504 | * Returns zero on success, negative values on failure. | 3644 | * Returns zero on success, negative values on failure. |
3505 | * | 3645 | * |
3506 | */ | 3646 | */ |
3507 | int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr) | 3647 | int security_netlbl_sid_to_secattr(struct selinux_state *state, |
3648 | u32 sid, struct netlbl_lsm_secattr *secattr) | ||
3508 | { | 3649 | { |
3650 | struct policydb *policydb = &state->ss->policydb; | ||
3509 | int rc; | 3651 | int rc; |
3510 | struct context *ctx; | 3652 | struct context *ctx; |
3511 | 3653 | ||
3512 | if (!ss_initialized) | 3654 | if (!state->initialized) |
3513 | return 0; | 3655 | return 0; |
3514 | 3656 | ||
3515 | read_lock(&policy_rwlock); | 3657 | read_lock(&state->ss->policy_rwlock); |
3516 | 3658 | ||
3517 | rc = -ENOENT; | 3659 | rc = -ENOENT; |
3518 | ctx = sidtab_search(&sidtab, sid); | 3660 | ctx = sidtab_search(&state->ss->sidtab, sid); |
3519 | if (ctx == NULL) | 3661 | if (ctx == NULL) |
3520 | goto out; | 3662 | goto out; |
3521 | 3663 | ||
3522 | rc = -ENOMEM; | 3664 | rc = -ENOMEM; |
3523 | secattr->domain = kstrdup(sym_name(&policydb, SYM_TYPES, ctx->type - 1), | 3665 | secattr->domain = kstrdup(sym_name(policydb, SYM_TYPES, ctx->type - 1), |
3524 | GFP_ATOMIC); | 3666 | GFP_ATOMIC); |
3525 | if (secattr->domain == NULL) | 3667 | if (secattr->domain == NULL) |
3526 | goto out; | 3668 | goto out; |
3527 | 3669 | ||
3528 | secattr->attr.secid = sid; | 3670 | secattr->attr.secid = sid; |
3529 | secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID; | 3671 | secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID; |
3530 | mls_export_netlbl_lvl(ctx, secattr); | 3672 | mls_export_netlbl_lvl(policydb, ctx, secattr); |
3531 | rc = mls_export_netlbl_cat(ctx, secattr); | 3673 | rc = mls_export_netlbl_cat(policydb, ctx, secattr); |
3532 | out: | 3674 | out: |
3533 | read_unlock(&policy_rwlock); | 3675 | read_unlock(&state->ss->policy_rwlock); |
3534 | return rc; | 3676 | return rc; |
3535 | } | 3677 | } |
3536 | #endif /* CONFIG_NETLABEL */ | 3678 | #endif /* CONFIG_NETLABEL */ |
@@ -3541,15 +3683,17 @@ out: | |||
3541 | * @len: length of data in bytes | 3683 | * @len: length of data in bytes |
3542 | * | 3684 | * |
3543 | */ | 3685 | */ |
3544 | int security_read_policy(void **data, size_t *len) | 3686 | int security_read_policy(struct selinux_state *state, |
3687 | void **data, size_t *len) | ||
3545 | { | 3688 | { |
3689 | struct policydb *policydb = &state->ss->policydb; | ||
3546 | int rc; | 3690 | int rc; |
3547 | struct policy_file fp; | 3691 | struct policy_file fp; |
3548 | 3692 | ||
3549 | if (!ss_initialized) | 3693 | if (!state->initialized) |
3550 | return -EINVAL; | 3694 | return -EINVAL; |
3551 | 3695 | ||
3552 | *len = security_policydb_len(); | 3696 | *len = security_policydb_len(state); |
3553 | 3697 | ||
3554 | *data = vmalloc_user(*len); | 3698 | *data = vmalloc_user(*len); |
3555 | if (!*data) | 3699 | if (!*data) |
@@ -3558,9 +3702,9 @@ int security_read_policy(void **data, size_t *len) | |||
3558 | fp.data = *data; | 3702 | fp.data = *data; |
3559 | fp.len = *len; | 3703 | fp.len = *len; |
3560 | 3704 | ||
3561 | read_lock(&policy_rwlock); | 3705 | read_lock(&state->ss->policy_rwlock); |
3562 | rc = policydb_write(&policydb, &fp); | 3706 | rc = policydb_write(policydb, &fp); |
3563 | read_unlock(&policy_rwlock); | 3707 | read_unlock(&state->ss->policy_rwlock); |
3564 | 3708 | ||
3565 | if (rc) | 3709 | if (rc) |
3566 | return rc; | 3710 | return rc; |
diff --git a/security/selinux/ss/services.h b/security/selinux/ss/services.h index 356bdd36cf6d..24c7bdcc8075 100644 --- a/security/selinux/ss/services.h +++ b/security/selinux/ss/services.h | |||
@@ -10,7 +10,28 @@ | |||
10 | #include "policydb.h" | 10 | #include "policydb.h" |
11 | #include "sidtab.h" | 11 | #include "sidtab.h" |
12 | 12 | ||
13 | extern struct policydb policydb; | 13 | /* Mapping for a single class */ |
14 | struct selinux_mapping { | ||
15 | u16 value; /* policy value for class */ | ||
16 | unsigned int num_perms; /* number of permissions in class */ | ||
17 | u32 perms[sizeof(u32) * 8]; /* policy values for permissions */ | ||
18 | }; | ||
19 | |||
20 | /* Map for all of the classes, with array size */ | ||
21 | struct selinux_map { | ||
22 | struct selinux_mapping *mapping; /* indexed by class */ | ||
23 | u16 size; /* array size of mapping */ | ||
24 | }; | ||
25 | |||
26 | struct selinux_ss { | ||
27 | struct sidtab sidtab; | ||
28 | struct policydb policydb; | ||
29 | rwlock_t policy_rwlock; | ||
30 | u32 latest_granting; | ||
31 | struct selinux_map map; | ||
32 | struct page *status_page; | ||
33 | struct mutex status_lock; | ||
34 | }; | ||
14 | 35 | ||
15 | void services_compute_xperms_drivers(struct extended_perms *xperms, | 36 | void services_compute_xperms_drivers(struct extended_perms *xperms, |
16 | struct avtab_node *node); | 37 | struct avtab_node *node); |
@@ -19,4 +40,3 @@ void services_compute_xperms_decision(struct extended_perms_decision *xpermd, | |||
19 | struct avtab_node *node); | 40 | struct avtab_node *node); |
20 | 41 | ||
21 | #endif /* _SS_SERVICES_H_ */ | 42 | #endif /* _SS_SERVICES_H_ */ |
22 | |||
diff --git a/security/selinux/ss/status.c b/security/selinux/ss/status.c index d982365f9d1a..043efc59f8e4 100644 --- a/security/selinux/ss/status.c +++ b/security/selinux/ss/status.c | |||
@@ -35,8 +35,6 @@ | |||
35 | * In most cases, application shall confirm the kernel status is not | 35 | * In most cases, application shall confirm the kernel status is not |
36 | * changed without any system call invocations. | 36 | * changed without any system call invocations. |
37 | */ | 37 | */ |
38 | static struct page *selinux_status_page; | ||
39 | static DEFINE_MUTEX(selinux_status_lock); | ||
40 | 38 | ||
41 | /* | 39 | /* |
42 | * selinux_kernel_status_page | 40 | * selinux_kernel_status_page |
@@ -44,21 +42,21 @@ static DEFINE_MUTEX(selinux_status_lock); | |||
44 | * It returns a reference to selinux_status_page. If the status page is | 42 | * It returns a reference to selinux_status_page. If the status page is |
45 | * not allocated yet, it also tries to allocate it at the first time. | 43 | * not allocated yet, it also tries to allocate it at the first time. |
46 | */ | 44 | */ |
47 | struct page *selinux_kernel_status_page(void) | 45 | struct page *selinux_kernel_status_page(struct selinux_state *state) |
48 | { | 46 | { |
49 | struct selinux_kernel_status *status; | 47 | struct selinux_kernel_status *status; |
50 | struct page *result = NULL; | 48 | struct page *result = NULL; |
51 | 49 | ||
52 | mutex_lock(&selinux_status_lock); | 50 | mutex_lock(&state->ss->status_lock); |
53 | if (!selinux_status_page) { | 51 | if (!state->ss->status_page) { |
54 | selinux_status_page = alloc_page(GFP_KERNEL|__GFP_ZERO); | 52 | state->ss->status_page = alloc_page(GFP_KERNEL|__GFP_ZERO); |
55 | 53 | ||
56 | if (selinux_status_page) { | 54 | if (state->ss->status_page) { |
57 | status = page_address(selinux_status_page); | 55 | status = page_address(state->ss->status_page); |
58 | 56 | ||
59 | status->version = SELINUX_KERNEL_STATUS_VERSION; | 57 | status->version = SELINUX_KERNEL_STATUS_VERSION; |
60 | status->sequence = 0; | 58 | status->sequence = 0; |
61 | status->enforcing = selinux_enforcing; | 59 | status->enforcing = is_enforcing(state); |
62 | /* | 60 | /* |
63 | * NOTE: the next policyload event shall set | 61 | * NOTE: the next policyload event shall set |
64 | * a positive value on the status->policyload, | 62 | * a positive value on the status->policyload, |
@@ -66,11 +64,12 @@ struct page *selinux_kernel_status_page(void) | |||
66 | * So, application can know it was updated. | 64 | * So, application can know it was updated. |
67 | */ | 65 | */ |
68 | status->policyload = 0; | 66 | status->policyload = 0; |
69 | status->deny_unknown = !security_get_allow_unknown(); | 67 | status->deny_unknown = |
68 | !security_get_allow_unknown(state); | ||
70 | } | 69 | } |
71 | } | 70 | } |
72 | result = selinux_status_page; | 71 | result = state->ss->status_page; |
73 | mutex_unlock(&selinux_status_lock); | 72 | mutex_unlock(&state->ss->status_lock); |
74 | 73 | ||
75 | return result; | 74 | return result; |
76 | } | 75 | } |
@@ -80,13 +79,14 @@ struct page *selinux_kernel_status_page(void) | |||
80 | * | 79 | * |
81 | * It updates status of the current enforcing/permissive mode. | 80 | * It updates status of the current enforcing/permissive mode. |
82 | */ | 81 | */ |
83 | void selinux_status_update_setenforce(int enforcing) | 82 | void selinux_status_update_setenforce(struct selinux_state *state, |
83 | int enforcing) | ||
84 | { | 84 | { |
85 | struct selinux_kernel_status *status; | 85 | struct selinux_kernel_status *status; |
86 | 86 | ||
87 | mutex_lock(&selinux_status_lock); | 87 | mutex_lock(&state->ss->status_lock); |
88 | if (selinux_status_page) { | 88 | if (state->ss->status_page) { |
89 | status = page_address(selinux_status_page); | 89 | status = page_address(state->ss->status_page); |
90 | 90 | ||
91 | status->sequence++; | 91 | status->sequence++; |
92 | smp_wmb(); | 92 | smp_wmb(); |
@@ -96,7 +96,7 @@ void selinux_status_update_setenforce(int enforcing) | |||
96 | smp_wmb(); | 96 | smp_wmb(); |
97 | status->sequence++; | 97 | status->sequence++; |
98 | } | 98 | } |
99 | mutex_unlock(&selinux_status_lock); | 99 | mutex_unlock(&state->ss->status_lock); |
100 | } | 100 | } |
101 | 101 | ||
102 | /* | 102 | /* |
@@ -105,22 +105,23 @@ void selinux_status_update_setenforce(int enforcing) | |||
105 | * It updates status of the times of policy reloaded, and current | 105 | * It updates status of the times of policy reloaded, and current |
106 | * setting of deny_unknown. | 106 | * setting of deny_unknown. |
107 | */ | 107 | */ |
108 | void selinux_status_update_policyload(int seqno) | 108 | void selinux_status_update_policyload(struct selinux_state *state, |
109 | int seqno) | ||
109 | { | 110 | { |
110 | struct selinux_kernel_status *status; | 111 | struct selinux_kernel_status *status; |
111 | 112 | ||
112 | mutex_lock(&selinux_status_lock); | 113 | mutex_lock(&state->ss->status_lock); |
113 | if (selinux_status_page) { | 114 | if (state->ss->status_page) { |
114 | status = page_address(selinux_status_page); | 115 | status = page_address(state->ss->status_page); |
115 | 116 | ||
116 | status->sequence++; | 117 | status->sequence++; |
117 | smp_wmb(); | 118 | smp_wmb(); |
118 | 119 | ||
119 | status->policyload = seqno; | 120 | status->policyload = seqno; |
120 | status->deny_unknown = !security_get_allow_unknown(); | 121 | status->deny_unknown = !security_get_allow_unknown(state); |
121 | 122 | ||
122 | smp_wmb(); | 123 | smp_wmb(); |
123 | status->sequence++; | 124 | status->sequence++; |
124 | } | 125 | } |
125 | mutex_unlock(&selinux_status_lock); | 126 | mutex_unlock(&state->ss->status_lock); |
126 | } | 127 | } |
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index 928188902901..a5ac27de571f 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
@@ -101,7 +101,8 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, | |||
101 | ctx->ctx_len = str_len; | 101 | ctx->ctx_len = str_len; |
102 | memcpy(ctx->ctx_str, &uctx[1], str_len); | 102 | memcpy(ctx->ctx_str, &uctx[1], str_len); |
103 | ctx->ctx_str[str_len] = '\0'; | 103 | ctx->ctx_str[str_len] = '\0'; |
104 | rc = security_context_to_sid(ctx->ctx_str, str_len, &ctx->ctx_sid, gfp); | 104 | rc = security_context_to_sid(&selinux_state, ctx->ctx_str, str_len, |
105 | &ctx->ctx_sid, gfp); | ||
105 | if (rc) | 106 | if (rc) |
106 | goto err; | 107 | goto err; |
107 | 108 | ||
@@ -352,7 +353,8 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x, | |||
352 | if (secid == 0) | 353 | if (secid == 0) |
353 | return -EINVAL; | 354 | return -EINVAL; |
354 | 355 | ||
355 | rc = security_sid_to_context(secid, &ctx_str, &str_len); | 356 | rc = security_sid_to_context(&selinux_state, secid, &ctx_str, |
357 | &str_len); | ||
356 | if (rc) | 358 | if (rc) |
357 | return rc; | 359 | return rc; |
358 | 360 | ||