aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/avc.c31
-rw-r--r--security/selinux/hooks.c162
-rw-r--r--security/selinux/include/initial_sid_to_string.h2
-rw-r--r--security/selinux/include/netlabel.h8
-rw-r--r--security/selinux/include/objsec.h1
-rw-r--r--security/selinux/include/security.h13
-rw-r--r--security/selinux/netif.c1
-rw-r--r--security/selinux/netlabel.c15
-rw-r--r--security/selinux/netlink.c2
-rw-r--r--security/selinux/netnode.c1
-rw-r--r--security/selinux/netport.c1
-rw-r--r--security/selinux/nlmsgtab.c1
-rw-r--r--security/selinux/selinuxfs.c56
-rw-r--r--security/selinux/ss/avtab.h2
-rw-r--r--security/selinux/ss/context.h12
-rw-r--r--security/selinux/ss/ebitmap.c2
-rw-r--r--security/selinux/ss/mls.c50
-rw-r--r--security/selinux/ss/mls.h2
-rw-r--r--security/selinux/ss/mls_types.h7
-rw-r--r--security/selinux/ss/policydb.c134
-rw-r--r--security/selinux/ss/policydb.h10
-rw-r--r--security/selinux/ss/services.c322
-rw-r--r--security/selinux/ss/symtab.c1
-rw-r--r--security/selinux/xfrm.c1
24 files changed, 422 insertions, 415 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index f2dde268165a..7f1a304712a9 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -337,7 +337,7 @@ static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass)
337 * Look up an AVC entry that is valid for the 337 * Look up an AVC entry that is valid for the
338 * (@ssid, @tsid), interpreting the permissions 338 * (@ssid, @tsid), interpreting the permissions
339 * based on @tclass. If a valid AVC entry exists, 339 * based on @tclass. If a valid AVC entry exists,
340 * then this function return the avc_node. 340 * then this function returns the avc_node.
341 * Otherwise, this function returns NULL. 341 * Otherwise, this function returns NULL.
342 */ 342 */
343static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass) 343static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass)
@@ -489,21 +489,17 @@ void avc_audit(u32 ssid, u32 tsid,
489 struct common_audit_data stack_data; 489 struct common_audit_data stack_data;
490 u32 denied, audited; 490 u32 denied, audited;
491 denied = requested & ~avd->allowed; 491 denied = requested & ~avd->allowed;
492 if (denied) { 492 if (denied)
493 audited = denied; 493 audited = denied & avd->auditdeny;
494 if (!(audited & avd->auditdeny)) 494 else if (result)
495 return;
496 } else if (result) {
497 audited = denied = requested; 495 audited = denied = requested;
498 } else { 496 else
499 audited = requested; 497 audited = requested & avd->auditallow;
500 if (!(audited & avd->auditallow)) 498 if (!audited)
501 return; 499 return;
502 }
503 if (!a) { 500 if (!a) {
504 a = &stack_data; 501 a = &stack_data;
505 memset(a, 0, sizeof(*a)); 502 COMMON_AUDIT_DATA_INIT(a, NONE);
506 a->type = LSM_AUDIT_NO_AUDIT;
507 } 503 }
508 a->selinux_audit_data.tclass = tclass; 504 a->selinux_audit_data.tclass = tclass;
509 a->selinux_audit_data.requested = requested; 505 a->selinux_audit_data.requested = requested;
@@ -526,7 +522,7 @@ void avc_audit(u32 ssid, u32 tsid,
526 * @perms: permissions 522 * @perms: permissions
527 * 523 *
528 * Register a callback function for events in the set @events 524 * Register a callback function for events in the set @events
529 * related to the SID pair (@ssid, @tsid) and 525 * related to the SID pair (@ssid, @tsid)
530 * and the permissions @perms, interpreting 526 * and the permissions @perms, interpreting
531 * @perms based on @tclass. Returns %0 on success or 527 * @perms based on @tclass. Returns %0 on success or
532 * -%ENOMEM if insufficient memory exists to add the callback. 528 * -%ENOMEM if insufficient memory exists to add the callback.
@@ -571,7 +567,7 @@ static inline int avc_sidcmp(u32 x, u32 y)
571 * 567 *
572 * if a valid AVC entry doesn't exist,this function returns -ENOENT. 568 * if a valid AVC entry doesn't exist,this function returns -ENOENT.
573 * if kmalloc() called internal returns NULL, this function returns -ENOMEM. 569 * if kmalloc() called internal returns NULL, this function returns -ENOMEM.
574 * otherwise, this function update the AVC entry. The original AVC-entry object 570 * otherwise, this function updates the AVC entry. The original AVC-entry object
575 * will release later by RCU. 571 * will release later by RCU.
576 */ 572 */
577static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass, 573static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass,
@@ -746,9 +742,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
746 else 742 else
747 avd = &avd_entry; 743 avd = &avd_entry;
748 744
749 rc = security_compute_av(ssid, tsid, tclass, requested, avd); 745 security_compute_av(ssid, tsid, tclass, avd);
750 if (rc)
751 goto out;
752 rcu_read_lock(); 746 rcu_read_lock();
753 node = avc_insert(ssid, tsid, tclass, avd); 747 node = avc_insert(ssid, tsid, tclass, avd);
754 } else { 748 } else {
@@ -770,7 +764,6 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
770 } 764 }
771 765
772 rcu_read_unlock(); 766 rcu_read_unlock();
773out:
774 return rc; 767 return rc;
775} 768}
776 769
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9a2ee845e9d4..5c9f25ba1c95 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -76,6 +76,7 @@
76#include <linux/selinux.h> 76#include <linux/selinux.h>
77#include <linux/mutex.h> 77#include <linux/mutex.h>
78#include <linux/posix-timers.h> 78#include <linux/posix-timers.h>
79#include <linux/syslog.h>
79 80
80#include "avc.h" 81#include "avc.h"
81#include "objsec.h" 82#include "objsec.h"
@@ -125,18 +126,6 @@ __setup("selinux=", selinux_enabled_setup);
125int selinux_enabled = 1; 126int selinux_enabled = 1;
126#endif 127#endif
127 128
128
129/*
130 * Minimal support for a secondary security module,
131 * just to allow the use of the capability module.
132 */
133static struct security_operations *secondary_ops;
134
135/* Lists of inode and superblock security structures initialized
136 before the policy was loaded. */
137static LIST_HEAD(superblock_security_head);
138static DEFINE_SPINLOCK(sb_security_lock);
139
140static struct kmem_cache *sel_inode_cache; 129static struct kmem_cache *sel_inode_cache;
141 130
142/** 131/**
@@ -272,7 +261,6 @@ static int superblock_alloc_security(struct super_block *sb)
272 return -ENOMEM; 261 return -ENOMEM;
273 262
274 mutex_init(&sbsec->lock); 263 mutex_init(&sbsec->lock);
275 INIT_LIST_HEAD(&sbsec->list);
276 INIT_LIST_HEAD(&sbsec->isec_head); 264 INIT_LIST_HEAD(&sbsec->isec_head);
277 spin_lock_init(&sbsec->isec_lock); 265 spin_lock_init(&sbsec->isec_lock);
278 sbsec->sb = sb; 266 sbsec->sb = sb;
@@ -287,40 +275,34 @@ static int superblock_alloc_security(struct super_block *sb)
287static void superblock_free_security(struct super_block *sb) 275static void superblock_free_security(struct super_block *sb)
288{ 276{
289 struct superblock_security_struct *sbsec = sb->s_security; 277 struct superblock_security_struct *sbsec = sb->s_security;
290
291 spin_lock(&sb_security_lock);
292 if (!list_empty(&sbsec->list))
293 list_del_init(&sbsec->list);
294 spin_unlock(&sb_security_lock);
295
296 sb->s_security = NULL; 278 sb->s_security = NULL;
297 kfree(sbsec); 279 kfree(sbsec);
298} 280}
299 281
300static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) 282static int sk_alloc_security(struct sock *sk, int family, gfp_t priority)
301{ 283{
302 struct sk_security_struct *ssec; 284 struct sk_security_struct *sksec;
303 285
304 ssec = kzalloc(sizeof(*ssec), priority); 286 sksec = kzalloc(sizeof(*sksec), priority);
305 if (!ssec) 287 if (!sksec)
306 return -ENOMEM; 288 return -ENOMEM;
307 289
308 ssec->peer_sid = SECINITSID_UNLABELED; 290 sksec->peer_sid = SECINITSID_UNLABELED;
309 ssec->sid = SECINITSID_UNLABELED; 291 sksec->sid = SECINITSID_UNLABELED;
310 sk->sk_security = ssec; 292 sk->sk_security = sksec;
311 293
312 selinux_netlbl_sk_security_reset(ssec); 294 selinux_netlbl_sk_security_reset(sksec);
313 295
314 return 0; 296 return 0;
315} 297}
316 298
317static void sk_free_security(struct sock *sk) 299static void sk_free_security(struct sock *sk)
318{ 300{
319 struct sk_security_struct *ssec = sk->sk_security; 301 struct sk_security_struct *sksec = sk->sk_security;
320 302
321 sk->sk_security = NULL; 303 sk->sk_security = NULL;
322 selinux_netlbl_sk_security_free(ssec); 304 selinux_netlbl_sk_security_free(sksec);
323 kfree(ssec); 305 kfree(sksec);
324} 306}
325 307
326/* The security server must be initialized before 308/* The security server must be initialized before
@@ -329,7 +311,7 @@ extern int ss_initialized;
329 311
330/* The file system's label must be initialized prior to use. */ 312/* The file system's label must be initialized prior to use. */
331 313
332static char *labeling_behaviors[6] = { 314static const char *labeling_behaviors[6] = {
333 "uses xattr", 315 "uses xattr",
334 "uses transition SIDs", 316 "uses transition SIDs",
335 "uses task SIDs", 317 "uses task SIDs",
@@ -618,10 +600,6 @@ static int selinux_set_mnt_opts(struct super_block *sb,
618 /* Defer initialization until selinux_complete_init, 600 /* Defer initialization until selinux_complete_init,
619 after the initial policy is loaded and the security 601 after the initial policy is loaded and the security
620 server is ready to handle calls. */ 602 server is ready to handle calls. */
621 spin_lock(&sb_security_lock);
622 if (list_empty(&sbsec->list))
623 list_add(&sbsec->list, &superblock_security_head);
624 spin_unlock(&sb_security_lock);
625 goto out; 603 goto out;
626 } 604 }
627 rc = -EINVAL; 605 rc = -EINVAL;
@@ -812,16 +790,10 @@ static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
812 790
813 /* 791 /*
814 * if the parent was able to be mounted it clearly had no special lsm 792 * if the parent was able to be mounted it clearly had no special lsm
815 * mount options. thus we can safely put this sb on the list and deal 793 * mount options. thus we can safely deal with this superblock later
816 * with it later
817 */ 794 */
818 if (!ss_initialized) { 795 if (!ss_initialized)
819 spin_lock(&sb_security_lock);
820 if (list_empty(&newsbsec->list))
821 list_add(&newsbsec->list, &superblock_security_head);
822 spin_unlock(&sb_security_lock);
823 return; 796 return;
824 }
825 797
826 /* how can we clone if the old one wasn't set up?? */ 798 /* how can we clone if the old one wasn't set up?? */
827 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED)); 799 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED));
@@ -2049,29 +2021,30 @@ static int selinux_quota_on(struct dentry *dentry)
2049 return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON); 2021 return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON);
2050} 2022}
2051 2023
2052static int selinux_syslog(int type) 2024static int selinux_syslog(int type, bool from_file)
2053{ 2025{
2054 int rc; 2026 int rc;
2055 2027
2056 rc = cap_syslog(type); 2028 rc = cap_syslog(type, from_file);
2057 if (rc) 2029 if (rc)
2058 return rc; 2030 return rc;
2059 2031
2060 switch (type) { 2032 switch (type) {
2061 case 3: /* Read last kernel messages */ 2033 case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */
2062 case 10: /* Return size of the log buffer */ 2034 case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
2063 rc = task_has_system(current, SYSTEM__SYSLOG_READ); 2035 rc = task_has_system(current, SYSTEM__SYSLOG_READ);
2064 break; 2036 break;
2065 case 6: /* Disable logging to console */ 2037 case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
2066 case 7: /* Enable logging to console */ 2038 case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */
2067 case 8: /* Set level of messages printed to console */ 2039 /* Set level of messages printed to console */
2040 case SYSLOG_ACTION_CONSOLE_LEVEL:
2068 rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE); 2041 rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE);
2069 break; 2042 break;
2070 case 0: /* Close log */ 2043 case SYSLOG_ACTION_CLOSE: /* Close log */
2071 case 1: /* Open log */ 2044 case SYSLOG_ACTION_OPEN: /* Open log */
2072 case 2: /* Read from log */ 2045 case SYSLOG_ACTION_READ: /* Read from log */
2073 case 4: /* Read/clear last kernel messages */ 2046 case SYSLOG_ACTION_READ_CLEAR: /* Read/clear last kernel messages */
2074 case 5: /* Clear ring buffer */ 2047 case SYSLOG_ACTION_CLEAR: /* Clear ring buffer */
2075 default: 2048 default:
2076 rc = task_has_system(current, SYSTEM__SYSLOG_MOD); 2049 rc = task_has_system(current, SYSTEM__SYSLOG_MOD);
2077 break; 2050 break;
@@ -3004,13 +2977,15 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
3004 return file_has_perm(cred, file, av); 2977 return file_has_perm(cred, file, av);
3005} 2978}
3006 2979
2980static int default_noexec;
2981
3007static int file_map_prot_check(struct file *file, unsigned long prot, int shared) 2982static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
3008{ 2983{
3009 const struct cred *cred = current_cred(); 2984 const struct cred *cred = current_cred();
3010 int rc = 0; 2985 int rc = 0;
3011 2986
3012#ifndef CONFIG_PPC32 2987 if (default_noexec &&
3013 if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) { 2988 (prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) {
3014 /* 2989 /*
3015 * We are making executable an anonymous mapping or a 2990 * We are making executable an anonymous mapping or a
3016 * private file mapping that will also be writable. 2991 * private file mapping that will also be writable.
@@ -3020,7 +2995,6 @@ static int file_map_prot_check(struct file *file, unsigned long prot, int shared
3020 if (rc) 2995 if (rc)
3021 goto error; 2996 goto error;
3022 } 2997 }
3023#endif
3024 2998
3025 if (file) { 2999 if (file) {
3026 /* read access is always possible with a mapping */ 3000 /* read access is always possible with a mapping */
@@ -3081,8 +3055,8 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
3081 if (selinux_checkreqprot) 3055 if (selinux_checkreqprot)
3082 prot = reqprot; 3056 prot = reqprot;
3083 3057
3084#ifndef CONFIG_PPC32 3058 if (default_noexec &&
3085 if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) { 3059 (prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
3086 int rc = 0; 3060 int rc = 0;
3087 if (vma->vm_start >= vma->vm_mm->start_brk && 3061 if (vma->vm_start >= vma->vm_mm->start_brk &&
3088 vma->vm_end <= vma->vm_mm->brk) { 3062 vma->vm_end <= vma->vm_mm->brk) {
@@ -3104,7 +3078,6 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
3104 if (rc) 3078 if (rc)
3105 return rc; 3079 return rc;
3106 } 3080 }
3107#endif
3108 3081
3109 return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED); 3082 return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
3110} 3083}
@@ -3334,7 +3307,7 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
3334 3307
3335 if (ret == 0) 3308 if (ret == 0)
3336 tsec->create_sid = isec->sid; 3309 tsec->create_sid = isec->sid;
3337 return 0; 3310 return ret;
3338} 3311}
3339 3312
3340static int selinux_kernel_module_request(char *kmod_name) 3313static int selinux_kernel_module_request(char *kmod_name)
@@ -4007,7 +3980,7 @@ static int selinux_socket_unix_stream_connect(struct socket *sock,
4007 struct socket *other, 3980 struct socket *other,
4008 struct sock *newsk) 3981 struct sock *newsk)
4009{ 3982{
4010 struct sk_security_struct *ssec; 3983 struct sk_security_struct *sksec;
4011 struct inode_security_struct *isec; 3984 struct inode_security_struct *isec;
4012 struct inode_security_struct *other_isec; 3985 struct inode_security_struct *other_isec;
4013 struct common_audit_data ad; 3986 struct common_audit_data ad;
@@ -4026,13 +3999,13 @@ static int selinux_socket_unix_stream_connect(struct socket *sock,
4026 return err; 3999 return err;
4027 4000
4028 /* connecting socket */ 4001 /* connecting socket */
4029 ssec = sock->sk->sk_security; 4002 sksec = sock->sk->sk_security;
4030 ssec->peer_sid = other_isec->sid; 4003 sksec->peer_sid = other_isec->sid;
4031 4004
4032 /* server child socket */ 4005 /* server child socket */
4033 ssec = newsk->sk_security; 4006 sksec = newsk->sk_security;
4034 ssec->peer_sid = isec->sid; 4007 sksec->peer_sid = isec->sid;
4035 err = security_sid_mls_copy(other_isec->sid, ssec->peer_sid, &ssec->sid); 4008 err = security_sid_mls_copy(other_isec->sid, sksec->peer_sid, &sksec->sid);
4036 4009
4037 return err; 4010 return err;
4038} 4011}
@@ -4195,7 +4168,7 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
4195 int err = 0; 4168 int err = 0;
4196 char *scontext; 4169 char *scontext;
4197 u32 scontext_len; 4170 u32 scontext_len;
4198 struct sk_security_struct *ssec; 4171 struct sk_security_struct *sksec;
4199 struct inode_security_struct *isec; 4172 struct inode_security_struct *isec;
4200 u32 peer_sid = SECSID_NULL; 4173 u32 peer_sid = SECSID_NULL;
4201 4174
@@ -4203,8 +4176,8 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
4203 4176
4204 if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET || 4177 if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET ||
4205 isec->sclass == SECCLASS_TCP_SOCKET) { 4178 isec->sclass == SECCLASS_TCP_SOCKET) {
4206 ssec = sock->sk->sk_security; 4179 sksec = sock->sk->sk_security;
4207 peer_sid = ssec->peer_sid; 4180 peer_sid = sksec->peer_sid;
4208 } 4181 }
4209 if (peer_sid == SECSID_NULL) { 4182 if (peer_sid == SECSID_NULL) {
4210 err = -ENOPROTOOPT; 4183 err = -ENOPROTOOPT;
@@ -4271,14 +4244,14 @@ static void selinux_sk_free_security(struct sock *sk)
4271 4244
4272static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) 4245static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk)
4273{ 4246{
4274 struct sk_security_struct *ssec = sk->sk_security; 4247 struct sk_security_struct *sksec = sk->sk_security;
4275 struct sk_security_struct *newssec = newsk->sk_security; 4248 struct sk_security_struct *newsksec = newsk->sk_security;
4276 4249
4277 newssec->sid = ssec->sid; 4250 newsksec->sid = sksec->sid;
4278 newssec->peer_sid = ssec->peer_sid; 4251 newsksec->peer_sid = sksec->peer_sid;
4279 newssec->sclass = ssec->sclass; 4252 newsksec->sclass = sksec->sclass;
4280 4253
4281 selinux_netlbl_sk_security_reset(newssec); 4254 selinux_netlbl_sk_security_reset(newsksec);
4282} 4255}
4283 4256
4284static void selinux_sk_getsecid(struct sock *sk, u32 *secid) 4257static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
@@ -5667,14 +5640,13 @@ static __init int selinux_init(void)
5667 /* Set the security state for the initial task. */ 5640 /* Set the security state for the initial task. */
5668 cred_init_security(); 5641 cred_init_security();
5669 5642
5643 default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC);
5644
5670 sel_inode_cache = kmem_cache_create("selinux_inode_security", 5645 sel_inode_cache = kmem_cache_create("selinux_inode_security",
5671 sizeof(struct inode_security_struct), 5646 sizeof(struct inode_security_struct),
5672 0, SLAB_PANIC, NULL); 5647 0, SLAB_PANIC, NULL);
5673 avc_init(); 5648 avc_init();
5674 5649
5675 secondary_ops = security_ops;
5676 if (!secondary_ops)
5677 panic("SELinux: No initial security operations\n");
5678 if (register_security(&selinux_ops)) 5650 if (register_security(&selinux_ops))
5679 panic("SELinux: Unable to register with kernel.\n"); 5651 panic("SELinux: Unable to register with kernel.\n");
5680 5652
@@ -5686,35 +5658,18 @@ static __init int selinux_init(void)
5686 return 0; 5658 return 0;
5687} 5659}
5688 5660
5661static void delayed_superblock_init(struct super_block *sb, void *unused)
5662{
5663 superblock_doinit(sb, NULL);
5664}
5665
5689void selinux_complete_init(void) 5666void selinux_complete_init(void)
5690{ 5667{
5691 printk(KERN_DEBUG "SELinux: Completing initialization.\n"); 5668 printk(KERN_DEBUG "SELinux: Completing initialization.\n");
5692 5669
5693 /* Set up any superblocks initialized prior to the policy load. */ 5670 /* Set up any superblocks initialized prior to the policy load. */
5694 printk(KERN_DEBUG "SELinux: Setting up existing superblocks.\n"); 5671 printk(KERN_DEBUG "SELinux: Setting up existing superblocks.\n");
5695 spin_lock(&sb_lock); 5672 iterate_supers(delayed_superblock_init, NULL);
5696 spin_lock(&sb_security_lock);
5697next_sb:
5698 if (!list_empty(&superblock_security_head)) {
5699 struct superblock_security_struct *sbsec =
5700 list_entry(superblock_security_head.next,
5701 struct superblock_security_struct,
5702 list);
5703 struct super_block *sb = sbsec->sb;
5704 sb->s_count++;
5705 spin_unlock(&sb_security_lock);
5706 spin_unlock(&sb_lock);
5707 down_read(&sb->s_umount);
5708 if (sb->s_root)
5709 superblock_doinit(sb, NULL);
5710 drop_super(sb);
5711 spin_lock(&sb_lock);
5712 spin_lock(&sb_security_lock);
5713 list_del_init(&sbsec->list);
5714 goto next_sb;
5715 }
5716 spin_unlock(&sb_security_lock);
5717 spin_unlock(&sb_lock);
5718} 5673}
5719 5674
5720/* SELinux requires early initialization in order to label 5675/* SELinux requires early initialization in order to label
@@ -5835,8 +5790,7 @@ int selinux_disable(void)
5835 selinux_disabled = 1; 5790 selinux_disabled = 1;
5836 selinux_enabled = 0; 5791 selinux_enabled = 0;
5837 5792
5838 /* Reset security_ops to the secondary module, dummy or capability. */ 5793 reset_security_ops();
5839 security_ops = secondary_ops;
5840 5794
5841 /* Try to destroy the avc node cache */ 5795 /* Try to destroy the avc node cache */
5842 avc_disable(); 5796 avc_disable();
diff --git a/security/selinux/include/initial_sid_to_string.h b/security/selinux/include/initial_sid_to_string.h
index d4fac82793ae..a59b64e3fd02 100644
--- a/security/selinux/include/initial_sid_to_string.h
+++ b/security/selinux/include/initial_sid_to_string.h
@@ -1,5 +1,5 @@
1/* This file is automatically generated. Do not edit. */ 1/* This file is automatically generated. Do not edit. */
2static char *initial_sid_to_string[] = 2static const char *initial_sid_to_string[] =
3{ 3{
4 "null", 4 "null",
5 "kernel", 5 "kernel",
diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h
index 8d7384280a7a..cf2f628e6e28 100644
--- a/security/selinux/include/netlabel.h
+++ b/security/selinux/include/netlabel.h
@@ -42,8 +42,8 @@ void selinux_netlbl_cache_invalidate(void);
42 42
43void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway); 43void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway);
44 44
45void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec); 45void selinux_netlbl_sk_security_free(struct sk_security_struct *sksec);
46void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec); 46void selinux_netlbl_sk_security_reset(struct sk_security_struct *sksec);
47 47
48int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, 48int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
49 u16 family, 49 u16 family,
@@ -79,13 +79,13 @@ static inline void selinux_netlbl_err(struct sk_buff *skb,
79} 79}
80 80
81static inline void selinux_netlbl_sk_security_free( 81static inline void selinux_netlbl_sk_security_free(
82 struct sk_security_struct *ssec) 82 struct sk_security_struct *sksec)
83{ 83{
84 return; 84 return;
85} 85}
86 86
87static inline void selinux_netlbl_sk_security_reset( 87static inline void selinux_netlbl_sk_security_reset(
88 struct sk_security_struct *ssec) 88 struct sk_security_struct *sksec)
89{ 89{
90 return; 90 return;
91} 91}
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index c4e062336ef3..26c7eee1c309 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -55,7 +55,6 @@ struct file_security_struct {
55 55
56struct superblock_security_struct { 56struct superblock_security_struct {
57 struct super_block *sb; /* back pointer to sb object */ 57 struct super_block *sb; /* back pointer to sb object */
58 struct list_head list; /* list of superblock_security_struct */
59 u32 sid; /* SID of file system superblock */ 58 u32 sid; /* SID of file system superblock */
60 u32 def_sid; /* default SID for labeling */ 59 u32 def_sid; /* default SID for labeling */
61 u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ 60 u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 2553266ad793..1f7c2491d3dc 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -57,7 +57,6 @@
57struct netlbl_lsm_secattr; 57struct netlbl_lsm_secattr;
58 58
59extern int selinux_enabled; 59extern int selinux_enabled;
60extern int selinux_mls_enabled;
61 60
62/* Policy capabilities */ 61/* Policy capabilities */
63enum { 62enum {
@@ -80,6 +79,8 @@ extern int selinux_policycap_openperm;
80/* limitation of boundary depth */ 79/* limitation of boundary depth */
81#define POLICYDB_BOUNDS_MAXDEPTH 4 80#define POLICYDB_BOUNDS_MAXDEPTH 4
82 81
82int security_mls_enabled(void);
83
83int security_load_policy(void *data, size_t len); 84int security_load_policy(void *data, size_t len);
84 85
85int security_policycap_supported(unsigned int req_cap); 86int security_policycap_supported(unsigned int req_cap);
@@ -96,13 +97,11 @@ struct av_decision {
96/* definitions of av_decision.flags */ 97/* definitions of av_decision.flags */
97#define AVD_FLAGS_PERMISSIVE 0x0001 98#define AVD_FLAGS_PERMISSIVE 0x0001
98 99
99int security_compute_av(u32 ssid, u32 tsid, 100void security_compute_av(u32 ssid, u32 tsid,
100 u16 tclass, u32 requested, 101 u16 tclass, struct av_decision *avd);
101 struct av_decision *avd);
102 102
103int security_compute_av_user(u32 ssid, u32 tsid, 103void security_compute_av_user(u32 ssid, u32 tsid,
104 u16 tclass, u32 requested, 104 u16 tclass, struct av_decision *avd);
105 struct av_decision *avd);
106 105
107int security_transition_sid(u32 ssid, u32 tsid, 106int security_transition_sid(u32 ssid, u32 tsid,
108 u16 tclass, u32 *out_sid); 107 u16 tclass, u32 *out_sid);
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index b4e14bc0bf32..d6095d63d831 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -16,6 +16,7 @@
16 */ 16 */
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/slab.h>
19#include <linux/stddef.h> 20#include <linux/stddef.h>
20#include <linux/kernel.h> 21#include <linux/kernel.h>
21#include <linux/list.h> 22#include <linux/list.h>
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index 2534400317c5..1c2fc46544bf 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -29,6 +29,7 @@
29 29
30#include <linux/spinlock.h> 30#include <linux/spinlock.h>
31#include <linux/rcupdate.h> 31#include <linux/rcupdate.h>
32#include <linux/gfp.h>
32#include <linux/ip.h> 33#include <linux/ip.h>
33#include <linux/ipv6.h> 34#include <linux/ipv6.h>
34#include <net/sock.h> 35#include <net/sock.h>
@@ -131,21 +132,21 @@ void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway)
131 132
132/** 133/**
133 * selinux_netlbl_sk_security_free - Free the NetLabel fields 134 * selinux_netlbl_sk_security_free - Free the NetLabel fields
134 * @sssec: the sk_security_struct 135 * @sksec: the sk_security_struct
135 * 136 *
136 * Description: 137 * Description:
137 * Free all of the memory in the NetLabel fields of a sk_security_struct. 138 * Free all of the memory in the NetLabel fields of a sk_security_struct.
138 * 139 *
139 */ 140 */
140void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec) 141void selinux_netlbl_sk_security_free(struct sk_security_struct *sksec)
141{ 142{
142 if (ssec->nlbl_secattr != NULL) 143 if (sksec->nlbl_secattr != NULL)
143 netlbl_secattr_free(ssec->nlbl_secattr); 144 netlbl_secattr_free(sksec->nlbl_secattr);
144} 145}
145 146
146/** 147/**
147 * selinux_netlbl_sk_security_reset - Reset the NetLabel fields 148 * selinux_netlbl_sk_security_reset - Reset the NetLabel fields
148 * @ssec: the sk_security_struct 149 * @sksec: the sk_security_struct
149 * @family: the socket family 150 * @family: the socket family
150 * 151 *
151 * Description: 152 * Description:
@@ -153,9 +154,9 @@ void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec)
153 * The caller is responsibile for all the NetLabel sk_security_struct locking. 154 * The caller is responsibile for all the NetLabel sk_security_struct locking.
154 * 155 *
155 */ 156 */
156void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec) 157void selinux_netlbl_sk_security_reset(struct sk_security_struct *sksec)
157{ 158{
158 ssec->nlbl_state = NLBL_UNSET; 159 sksec->nlbl_state = NLBL_UNSET;
159} 160}
160 161
161/** 162/**
diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c
index 1ae556446e65..36ac257cec9a 100644
--- a/security/selinux/netlink.c
+++ b/security/selinux/netlink.c
@@ -11,9 +11,9 @@
11 */ 11 */
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/slab.h>
14#include <linux/stddef.h> 15#include <linux/stddef.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/list.h>
17#include <linux/skbuff.h> 17#include <linux/skbuff.h>
18#include <linux/netlink.h> 18#include <linux/netlink.h>
19#include <linux/selinux_netlink.h> 19#include <linux/selinux_netlink.h>
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index 7100072bb1b0..dc92792271f1 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -31,6 +31,7 @@
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/rcupdate.h> 32#include <linux/rcupdate.h>
33#include <linux/list.h> 33#include <linux/list.h>
34#include <linux/slab.h>
34#include <linux/spinlock.h> 35#include <linux/spinlock.h>
35#include <linux/in.h> 36#include <linux/in.h>
36#include <linux/in6.h> 37#include <linux/in6.h>
diff --git a/security/selinux/netport.c b/security/selinux/netport.c
index fe7fba67f19f..cfe2d72d3fb7 100644
--- a/security/selinux/netport.c
+++ b/security/selinux/netport.c
@@ -30,6 +30,7 @@
30#include <linux/types.h> 30#include <linux/types.h>
31#include <linux/rcupdate.h> 31#include <linux/rcupdate.h>
32#include <linux/list.h> 32#include <linux/list.h>
33#include <linux/slab.h>
33#include <linux/spinlock.h> 34#include <linux/spinlock.h>
34#include <linux/in.h> 35#include <linux/in.h>
35#include <linux/in6.h> 36#include <linux/in6.h>
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index dd7cc6de77f9..75ec0c6ebacd 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -11,7 +11,6 @@
11 */ 11 */
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/skbuff.h>
15#include <linux/netlink.h> 14#include <linux/netlink.h>
16#include <linux/rtnetlink.h> 15#include <linux/rtnetlink.h>
17#include <linux/if.h> 16#include <linux/if.h>
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index fab36fdf2769..0293843f7eda 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -282,7 +282,8 @@ static ssize_t sel_read_mls(struct file *filp, char __user *buf,
282 char tmpbuf[TMPBUFLEN]; 282 char tmpbuf[TMPBUFLEN];
283 ssize_t length; 283 ssize_t length;
284 284
285 length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled); 285 length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
286 security_mls_enabled());
286 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); 287 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
287} 288}
288 289
@@ -494,7 +495,6 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
494 char *scon, *tcon; 495 char *scon, *tcon;
495 u32 ssid, tsid; 496 u32 ssid, tsid;
496 u16 tclass; 497 u16 tclass;
497 u32 req;
498 struct av_decision avd; 498 struct av_decision avd;
499 ssize_t length; 499 ssize_t length;
500 500
@@ -503,28 +503,26 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
503 return length; 503 return length;
504 504
505 length = -ENOMEM; 505 length = -ENOMEM;
506 scon = kzalloc(size+1, GFP_KERNEL); 506 scon = kzalloc(size + 1, GFP_KERNEL);
507 if (!scon) 507 if (!scon)
508 return length; 508 return length;
509 509
510 tcon = kzalloc(size+1, GFP_KERNEL); 510 tcon = kzalloc(size + 1, GFP_KERNEL);
511 if (!tcon) 511 if (!tcon)
512 goto out; 512 goto out;
513 513
514 length = -EINVAL; 514 length = -EINVAL;
515 if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4) 515 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
516 goto out2; 516 goto out2;
517 517
518 length = security_context_to_sid(scon, strlen(scon)+1, &ssid); 518 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
519 if (length < 0) 519 if (length < 0)
520 goto out2; 520 goto out2;
521 length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid); 521 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
522 if (length < 0) 522 if (length < 0)
523 goto out2; 523 goto out2;
524 524
525 length = security_compute_av_user(ssid, tsid, tclass, req, &avd); 525 security_compute_av_user(ssid, tsid, tclass, &avd);
526 if (length < 0)
527 goto out2;
528 526
529 length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, 527 length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
530 "%x %x %x %x %u %x", 528 "%x %x %x %x %u %x",
@@ -552,11 +550,11 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
552 return length; 550 return length;
553 551
554 length = -ENOMEM; 552 length = -ENOMEM;
555 scon = kzalloc(size+1, GFP_KERNEL); 553 scon = kzalloc(size + 1, GFP_KERNEL);
556 if (!scon) 554 if (!scon)
557 return length; 555 return length;
558 556
559 tcon = kzalloc(size+1, GFP_KERNEL); 557 tcon = kzalloc(size + 1, GFP_KERNEL);
560 if (!tcon) 558 if (!tcon)
561 goto out; 559 goto out;
562 560
@@ -564,10 +562,10 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
564 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 562 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
565 goto out2; 563 goto out2;
566 564
567 length = security_context_to_sid(scon, strlen(scon)+1, &ssid); 565 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
568 if (length < 0) 566 if (length < 0)
569 goto out2; 567 goto out2;
570 length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid); 568 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
571 if (length < 0) 569 if (length < 0)
572 goto out2; 570 goto out2;
573 571
@@ -611,11 +609,11 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
611 return length; 609 return length;
612 610
613 length = -ENOMEM; 611 length = -ENOMEM;
614 scon = kzalloc(size+1, GFP_KERNEL); 612 scon = kzalloc(size + 1, GFP_KERNEL);
615 if (!scon) 613 if (!scon)
616 return length; 614 return length;
617 615
618 tcon = kzalloc(size+1, GFP_KERNEL); 616 tcon = kzalloc(size + 1, GFP_KERNEL);
619 if (!tcon) 617 if (!tcon)
620 goto out; 618 goto out;
621 619
@@ -623,10 +621,10 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
623 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 621 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
624 goto out2; 622 goto out2;
625 623
626 length = security_context_to_sid(scon, strlen(scon)+1, &ssid); 624 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
627 if (length < 0) 625 if (length < 0)
628 goto out2; 626 goto out2;
629 length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid); 627 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
630 if (length < 0) 628 if (length < 0)
631 goto out2; 629 goto out2;
632 630
@@ -668,11 +666,11 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
668 return length; 666 return length;
669 667
670 length = -ENOMEM; 668 length = -ENOMEM;
671 con = kzalloc(size+1, GFP_KERNEL); 669 con = kzalloc(size + 1, GFP_KERNEL);
672 if (!con) 670 if (!con)
673 return length; 671 return length;
674 672
675 user = kzalloc(size+1, GFP_KERNEL); 673 user = kzalloc(size + 1, GFP_KERNEL);
676 if (!user) 674 if (!user)
677 goto out; 675 goto out;
678 676
@@ -680,7 +678,7 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
680 if (sscanf(buf, "%s %s", con, user) != 2) 678 if (sscanf(buf, "%s %s", con, user) != 2)
681 goto out2; 679 goto out2;
682 680
683 length = security_context_to_sid(con, strlen(con)+1, &sid); 681 length = security_context_to_sid(con, strlen(con) + 1, &sid);
684 if (length < 0) 682 if (length < 0)
685 goto out2; 683 goto out2;
686 684
@@ -729,11 +727,11 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
729 return length; 727 return length;
730 728
731 length = -ENOMEM; 729 length = -ENOMEM;
732 scon = kzalloc(size+1, GFP_KERNEL); 730 scon = kzalloc(size + 1, GFP_KERNEL);
733 if (!scon) 731 if (!scon)
734 return length; 732 return length;
735 733
736 tcon = kzalloc(size+1, GFP_KERNEL); 734 tcon = kzalloc(size + 1, GFP_KERNEL);
737 if (!tcon) 735 if (!tcon)
738 goto out; 736 goto out;
739 737
@@ -741,10 +739,10 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
741 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 739 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
742 goto out2; 740 goto out2;
743 741
744 length = security_context_to_sid(scon, strlen(scon)+1, &ssid); 742 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
745 if (length < 0) 743 if (length < 0)
746 goto out2; 744 goto out2;
747 length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid); 745 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
748 if (length < 0) 746 if (length < 0)
749 goto out2; 747 goto out2;
750 748
@@ -979,6 +977,8 @@ static int sel_make_bools(void)
979 u32 sid; 977 u32 sid;
980 978
981 /* remove any existing files */ 979 /* remove any existing files */
980 for (i = 0; i < bool_num; i++)
981 kfree(bool_pending_names[i]);
982 kfree(bool_pending_names); 982 kfree(bool_pending_names);
983 kfree(bool_pending_values); 983 kfree(bool_pending_values);
984 bool_pending_names = NULL; 984 bool_pending_names = NULL;
@@ -1401,7 +1401,7 @@ static int sel_make_perm_files(char *objclass, int classvalue,
1401 } 1401 }
1402 inode->i_fop = &sel_perm_ops; 1402 inode->i_fop = &sel_perm_ops;
1403 /* i+1 since perm values are 1-indexed */ 1403 /* i+1 since perm values are 1-indexed */
1404 inode->i_ino = sel_perm_to_ino(classvalue, i+1); 1404 inode->i_ino = sel_perm_to_ino(classvalue, i + 1);
1405 d_add(dentry, inode); 1405 d_add(dentry, inode);
1406 } 1406 }
1407 1407
@@ -1489,7 +1489,7 @@ static int sel_make_classes(void)
1489 goto out; 1489 goto out;
1490 1490
1491 /* +2 since classes are 1-indexed */ 1491 /* +2 since classes are 1-indexed */
1492 last_class_ino = sel_class_to_ino(nclasses+2); 1492 last_class_ino = sel_class_to_ino(nclasses + 2);
1493 1493
1494 for (i = 0; i < nclasses; i++) { 1494 for (i = 0; i < nclasses; i++) {
1495 struct dentry *class_name_dir; 1495 struct dentry *class_name_dir;
@@ -1506,7 +1506,7 @@ static int sel_make_classes(void)
1506 goto out1; 1506 goto out1;
1507 1507
1508 /* i+1 since class values are 1-indexed */ 1508 /* i+1 since class values are 1-indexed */
1509 rc = sel_make_class_dir_entries(classes[i], i+1, 1509 rc = sel_make_class_dir_entries(classes[i], i + 1,
1510 class_name_dir); 1510 class_name_dir);
1511 if (rc) 1511 if (rc)
1512 goto out1; 1512 goto out1;
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index 8da6a8428086..cd4f734e2749 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -82,7 +82,7 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified
82void avtab_cache_init(void); 82void avtab_cache_init(void);
83void avtab_cache_destroy(void); 83void avtab_cache_destroy(void);
84 84
85#define MAX_AVTAB_HASH_BITS 13 85#define MAX_AVTAB_HASH_BITS 11
86#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) 86#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
87#define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1) 87#define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1)
88#define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS 88#define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS
diff --git a/security/selinux/ss/context.h b/security/selinux/ss/context.h
index d9dd7a2f6a8a..45e8fb0515f8 100644
--- a/security/selinux/ss/context.h
+++ b/security/selinux/ss/context.h
@@ -41,9 +41,6 @@ static inline int mls_context_cpy(struct context *dst, struct context *src)
41{ 41{
42 int rc; 42 int rc;
43 43
44 if (!selinux_mls_enabled)
45 return 0;
46
47 dst->range.level[0].sens = src->range.level[0].sens; 44 dst->range.level[0].sens = src->range.level[0].sens;
48 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat); 45 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
49 if (rc) 46 if (rc)
@@ -64,9 +61,6 @@ static inline int mls_context_cpy_low(struct context *dst, struct context *src)
64{ 61{
65 int rc; 62 int rc;
66 63
67 if (!selinux_mls_enabled)
68 return 0;
69
70 dst->range.level[0].sens = src->range.level[0].sens; 64 dst->range.level[0].sens = src->range.level[0].sens;
71 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat); 65 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
72 if (rc) 66 if (rc)
@@ -82,9 +76,6 @@ out:
82 76
83static inline int mls_context_cmp(struct context *c1, struct context *c2) 77static inline int mls_context_cmp(struct context *c1, struct context *c2)
84{ 78{
85 if (!selinux_mls_enabled)
86 return 1;
87
88 return ((c1->range.level[0].sens == c2->range.level[0].sens) && 79 return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
89 ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) && 80 ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
90 (c1->range.level[1].sens == c2->range.level[1].sens) && 81 (c1->range.level[1].sens == c2->range.level[1].sens) &&
@@ -93,9 +84,6 @@ static inline int mls_context_cmp(struct context *c1, struct context *c2)
93 84
94static inline void mls_context_destroy(struct context *c) 85static inline void mls_context_destroy(struct context *c)
95{ 86{
96 if (!selinux_mls_enabled)
97 return;
98
99 ebitmap_destroy(&c->range.level[0].cat); 87 ebitmap_destroy(&c->range.level[0].cat);
100 ebitmap_destroy(&c->range.level[1].cat); 88 ebitmap_destroy(&c->range.level[1].cat);
101 mls_context_init(c); 89 mls_context_init(c);
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 68c7348d1acc..04b6145d767f 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -128,7 +128,7 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
128 cmap_idx = delta / NETLBL_CATMAP_MAPSIZE; 128 cmap_idx = delta / NETLBL_CATMAP_MAPSIZE;
129 cmap_sft = delta % NETLBL_CATMAP_MAPSIZE; 129 cmap_sft = delta % NETLBL_CATMAP_MAPSIZE;
130 c_iter->bitmap[cmap_idx] 130 c_iter->bitmap[cmap_idx]
131 |= e_iter->maps[cmap_idx] << cmap_sft; 131 |= e_iter->maps[i] << cmap_sft;
132 } 132 }
133 e_iter = e_iter->next; 133 e_iter = e_iter->next;
134 } 134 }
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 3f2b2706b5bb..b4eff7a60c50 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -39,7 +39,7 @@ int mls_compute_context_len(struct context *context)
39 struct ebitmap *e; 39 struct ebitmap *e;
40 struct ebitmap_node *node; 40 struct ebitmap_node *node;
41 41
42 if (!selinux_mls_enabled) 42 if (!policydb.mls_enabled)
43 return 0; 43 return 0;
44 44
45 len = 1; /* for the beginning ":" */ 45 len = 1; /* for the beginning ":" */
@@ -93,7 +93,7 @@ void mls_sid_to_context(struct context *context,
93 struct ebitmap *e; 93 struct ebitmap *e;
94 struct ebitmap_node *node; 94 struct ebitmap_node *node;
95 95
96 if (!selinux_mls_enabled) 96 if (!policydb.mls_enabled)
97 return; 97 return;
98 98
99 scontextp = *scontext; 99 scontextp = *scontext;
@@ -200,7 +200,7 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
200{ 200{
201 struct user_datum *usrdatum; 201 struct user_datum *usrdatum;
202 202
203 if (!selinux_mls_enabled) 203 if (!p->mls_enabled)
204 return 1; 204 return 1;
205 205
206 if (!mls_range_isvalid(p, &c->range)) 206 if (!mls_range_isvalid(p, &c->range))
@@ -253,9 +253,9 @@ int mls_context_to_sid(struct policydb *pol,
253 struct cat_datum *catdatum, *rngdatum; 253 struct cat_datum *catdatum, *rngdatum;
254 int l, rc = -EINVAL; 254 int l, rc = -EINVAL;
255 255
256 if (!selinux_mls_enabled) { 256 if (!pol->mls_enabled) {
257 if (def_sid != SECSID_NULL && oldc) 257 if (def_sid != SECSID_NULL && oldc)
258 *scontext += strlen(*scontext)+1; 258 *scontext += strlen(*scontext) + 1;
259 return 0; 259 return 0;
260 } 260 }
261 261
@@ -387,7 +387,7 @@ int mls_from_string(char *str, struct context *context, gfp_t gfp_mask)
387 char *tmpstr, *freestr; 387 char *tmpstr, *freestr;
388 int rc; 388 int rc;
389 389
390 if (!selinux_mls_enabled) 390 if (!policydb.mls_enabled)
391 return -EINVAL; 391 return -EINVAL;
392 392
393 /* we need freestr because mls_context_to_sid will change 393 /* we need freestr because mls_context_to_sid will change
@@ -407,7 +407,7 @@ int mls_from_string(char *str, struct context *context, gfp_t gfp_mask)
407/* 407/*
408 * Copies the MLS range `range' into `context'. 408 * Copies the MLS range `range' into `context'.
409 */ 409 */
410static inline int mls_range_set(struct context *context, 410int mls_range_set(struct context *context,
411 struct mls_range *range) 411 struct mls_range *range)
412{ 412{
413 int l, rc = 0; 413 int l, rc = 0;
@@ -427,7 +427,7 @@ static inline int mls_range_set(struct context *context,
427int mls_setup_user_range(struct context *fromcon, struct user_datum *user, 427int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
428 struct context *usercon) 428 struct context *usercon)
429{ 429{
430 if (selinux_mls_enabled) { 430 if (policydb.mls_enabled) {
431 struct mls_level *fromcon_sen = &(fromcon->range.level[0]); 431 struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
432 struct mls_level *fromcon_clr = &(fromcon->range.level[1]); 432 struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
433 struct mls_level *user_low = &(user->range.level[0]); 433 struct mls_level *user_low = &(user->range.level[0]);
@@ -477,7 +477,7 @@ int mls_convert_context(struct policydb *oldp,
477 struct ebitmap_node *node; 477 struct ebitmap_node *node;
478 int l, i; 478 int l, i;
479 479
480 if (!selinux_mls_enabled) 480 if (!policydb.mls_enabled)
481 return 0; 481 return 0;
482 482
483 for (l = 0; l < 2; l++) { 483 for (l = 0; l < 2; l++) {
@@ -513,23 +513,21 @@ int mls_compute_sid(struct context *scontext,
513 u32 specified, 513 u32 specified,
514 struct context *newcontext) 514 struct context *newcontext)
515{ 515{
516 struct range_trans *rtr; 516 struct range_trans rtr;
517 struct mls_range *r;
517 518
518 if (!selinux_mls_enabled) 519 if (!policydb.mls_enabled)
519 return 0; 520 return 0;
520 521
521 switch (specified) { 522 switch (specified) {
522 case AVTAB_TRANSITION: 523 case AVTAB_TRANSITION:
523 /* Look for a range transition rule. */ 524 /* Look for a range transition rule. */
524 for (rtr = policydb.range_tr; rtr; rtr = rtr->next) { 525 rtr.source_type = scontext->type;
525 if (rtr->source_type == scontext->type && 526 rtr.target_type = tcontext->type;
526 rtr->target_type == tcontext->type && 527 rtr.target_class = tclass;
527 rtr->target_class == tclass) { 528 r = hashtab_search(policydb.range_tr, &rtr);
528 /* Set the range from the rule */ 529 if (r)
529 return mls_range_set(newcontext, 530 return mls_range_set(newcontext, r);
530 &rtr->target_range);
531 }
532 }
533 /* Fallthrough */ 531 /* Fallthrough */
534 case AVTAB_CHANGE: 532 case AVTAB_CHANGE:
535 if (tclass == policydb.process_class) 533 if (tclass == policydb.process_class)
@@ -541,8 +539,8 @@ int mls_compute_sid(struct context *scontext,
541 case AVTAB_MEMBER: 539 case AVTAB_MEMBER:
542 /* Use the process effective MLS attributes. */ 540 /* Use the process effective MLS attributes. */
543 return mls_context_cpy_low(newcontext, scontext); 541 return mls_context_cpy_low(newcontext, scontext);
544 default: 542
545 return -EINVAL; 543 /* fall through */
546 } 544 }
547 return -EINVAL; 545 return -EINVAL;
548} 546}
@@ -561,7 +559,7 @@ int mls_compute_sid(struct context *scontext,
561void mls_export_netlbl_lvl(struct context *context, 559void mls_export_netlbl_lvl(struct context *context,
562 struct netlbl_lsm_secattr *secattr) 560 struct netlbl_lsm_secattr *secattr)
563{ 561{
564 if (!selinux_mls_enabled) 562 if (!policydb.mls_enabled)
565 return; 563 return;
566 564
567 secattr->attr.mls.lvl = context->range.level[0].sens - 1; 565 secattr->attr.mls.lvl = context->range.level[0].sens - 1;
@@ -581,7 +579,7 @@ void mls_export_netlbl_lvl(struct context *context,
581void mls_import_netlbl_lvl(struct context *context, 579void mls_import_netlbl_lvl(struct context *context,
582 struct netlbl_lsm_secattr *secattr) 580 struct netlbl_lsm_secattr *secattr)
583{ 581{
584 if (!selinux_mls_enabled) 582 if (!policydb.mls_enabled)
585 return; 583 return;
586 584
587 context->range.level[0].sens = secattr->attr.mls.lvl + 1; 585 context->range.level[0].sens = secattr->attr.mls.lvl + 1;
@@ -603,7 +601,7 @@ int mls_export_netlbl_cat(struct context *context,
603{ 601{
604 int rc; 602 int rc;
605 603
606 if (!selinux_mls_enabled) 604 if (!policydb.mls_enabled)
607 return 0; 605 return 0;
608 606
609 rc = ebitmap_netlbl_export(&context->range.level[0].cat, 607 rc = ebitmap_netlbl_export(&context->range.level[0].cat,
@@ -631,7 +629,7 @@ int mls_import_netlbl_cat(struct context *context,
631{ 629{
632 int rc; 630 int rc;
633 631
634 if (!selinux_mls_enabled) 632 if (!policydb.mls_enabled)
635 return 0; 633 return 0;
636 634
637 rc = ebitmap_netlbl_import(&context->range.level[0].cat, 635 rc = ebitmap_netlbl_import(&context->range.level[0].cat,
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
index 1276715aaa8b..cd9152632e54 100644
--- a/security/selinux/ss/mls.h
+++ b/security/selinux/ss/mls.h
@@ -39,6 +39,8 @@ int mls_context_to_sid(struct policydb *p,
39 39
40int mls_from_string(char *str, struct context *context, gfp_t gfp_mask); 40int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);
41 41
42int mls_range_set(struct context *context, struct mls_range *range);
43
42int mls_convert_context(struct policydb *oldp, 44int mls_convert_context(struct policydb *oldp,
43 struct policydb *newp, 45 struct policydb *newp,
44 struct context *context); 46 struct context *context);
diff --git a/security/selinux/ss/mls_types.h b/security/selinux/ss/mls_types.h
index b6e943a21061..03bed52a8052 100644
--- a/security/selinux/ss/mls_types.h
+++ b/security/selinux/ss/mls_types.h
@@ -15,6 +15,7 @@
15#define _SS_MLS_TYPES_H_ 15#define _SS_MLS_TYPES_H_
16 16
17#include "security.h" 17#include "security.h"
18#include "ebitmap.h"
18 19
19struct mls_level { 20struct mls_level {
20 u32 sens; /* sensitivity */ 21 u32 sens; /* sensitivity */
@@ -27,18 +28,12 @@ struct mls_range {
27 28
28static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2) 29static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
29{ 30{
30 if (!selinux_mls_enabled)
31 return 1;
32
33 return ((l1->sens == l2->sens) && 31 return ((l1->sens == l2->sens) &&
34 ebitmap_cmp(&l1->cat, &l2->cat)); 32 ebitmap_cmp(&l1->cat, &l2->cat));
35} 33}
36 34
37static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) 35static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
38{ 36{
39 if (!selinux_mls_enabled)
40 return 1;
41
42 return ((l1->sens >= l2->sens) && 37 return ((l1->sens >= l2->sens) &&
43 ebitmap_contains(&l1->cat, &l2->cat)); 38 ebitmap_contains(&l1->cat, &l2->cat));
44} 39}
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index f03667213ea8..c57802a164d5 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -40,7 +40,7 @@
40#define _DEBUG_HASHES 40#define _DEBUG_HASHES
41 41
42#ifdef DEBUG_HASHES 42#ifdef DEBUG_HASHES
43static char *symtab_name[SYM_NUM] = { 43static const char *symtab_name[SYM_NUM] = {
44 "common prefixes", 44 "common prefixes",
45 "classes", 45 "classes",
46 "roles", 46 "roles",
@@ -52,8 +52,6 @@ static char *symtab_name[SYM_NUM] = {
52}; 52};
53#endif 53#endif
54 54
55int selinux_mls_enabled;
56
57static unsigned int symtab_sizes[SYM_NUM] = { 55static unsigned int symtab_sizes[SYM_NUM] = {
58 2, 56 2,
59 32, 57 32,
@@ -158,12 +156,11 @@ static int roles_init(struct policydb *p)
158 rc = -EINVAL; 156 rc = -EINVAL;
159 goto out_free_role; 157 goto out_free_role;
160 } 158 }
161 key = kmalloc(strlen(OBJECT_R)+1, GFP_KERNEL); 159 key = kstrdup(OBJECT_R, GFP_KERNEL);
162 if (!key) { 160 if (!key) {
163 rc = -ENOMEM; 161 rc = -ENOMEM;
164 goto out_free_role; 162 goto out_free_role;
165 } 163 }
166 strcpy(key, OBJECT_R);
167 rc = hashtab_insert(p->p_roles.table, key, role); 164 rc = hashtab_insert(p->p_roles.table, key, role);
168 if (rc) 165 if (rc)
169 goto out_free_key; 166 goto out_free_key;
@@ -177,6 +174,21 @@ out_free_role:
177 goto out; 174 goto out;
178} 175}
179 176
177static u32 rangetr_hash(struct hashtab *h, const void *k)
178{
179 const struct range_trans *key = k;
180 return (key->source_type + (key->target_type << 3) +
181 (key->target_class << 5)) & (h->size - 1);
182}
183
184static int rangetr_cmp(struct hashtab *h, const void *k1, const void *k2)
185{
186 const struct range_trans *key1 = k1, *key2 = k2;
187 return (key1->source_type != key2->source_type ||
188 key1->target_type != key2->target_type ||
189 key1->target_class != key2->target_class);
190}
191
180/* 192/*
181 * Initialize a policy database structure. 193 * Initialize a policy database structure.
182 */ 194 */
@@ -204,6 +216,10 @@ static int policydb_init(struct policydb *p)
204 if (rc) 216 if (rc)
205 goto out_free_symtab; 217 goto out_free_symtab;
206 218
219 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
220 if (!p->range_tr)
221 goto out_free_symtab;
222
207 ebitmap_init(&p->policycaps); 223 ebitmap_init(&p->policycaps);
208 ebitmap_init(&p->permissive_map); 224 ebitmap_init(&p->permissive_map);
209 225
@@ -408,6 +424,20 @@ static void symtab_hash_eval(struct symtab *s)
408 info.slots_used, h->size, info.max_chain_len); 424 info.slots_used, h->size, info.max_chain_len);
409 } 425 }
410} 426}
427
428static void rangetr_hash_eval(struct hashtab *h)
429{
430 struct hashtab_info info;
431
432 hashtab_stat(h, &info);
433 printk(KERN_DEBUG "SELinux: rangetr: %d entries and %d/%d buckets used, "
434 "longest chain length %d\n", h->nel,
435 info.slots_used, h->size, info.max_chain_len);
436}
437#else
438static inline void rangetr_hash_eval(struct hashtab *h)
439{
440}
411#endif 441#endif
412 442
413/* 443/*
@@ -422,7 +452,7 @@ static int policydb_index_others(struct policydb *p)
422 452
423 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools", 453 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools",
424 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); 454 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
425 if (selinux_mls_enabled) 455 if (p->mls_enabled)
426 printk(", %d sens, %d cats", p->p_levels.nprim, 456 printk(", %d sens, %d cats", p->p_levels.nprim,
427 p->p_cats.nprim); 457 p->p_cats.nprim);
428 printk("\n"); 458 printk("\n");
@@ -612,6 +642,17 @@ static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) =
612 cat_destroy, 642 cat_destroy,
613}; 643};
614 644
645static int range_tr_destroy(void *key, void *datum, void *p)
646{
647 struct mls_range *rt = datum;
648 kfree(key);
649 ebitmap_destroy(&rt->level[0].cat);
650 ebitmap_destroy(&rt->level[1].cat);
651 kfree(datum);
652 cond_resched();
653 return 0;
654}
655
615static void ocontext_destroy(struct ocontext *c, int i) 656static void ocontext_destroy(struct ocontext *c, int i)
616{ 657{
617 context_destroy(&c->context[0]); 658 context_destroy(&c->context[0]);
@@ -632,7 +673,6 @@ void policydb_destroy(struct policydb *p)
632 int i; 673 int i;
633 struct role_allow *ra, *lra = NULL; 674 struct role_allow *ra, *lra = NULL;
634 struct role_trans *tr, *ltr = NULL; 675 struct role_trans *tr, *ltr = NULL;
635 struct range_trans *rt, *lrt = NULL;
636 676
637 for (i = 0; i < SYM_NUM; i++) { 677 for (i = 0; i < SYM_NUM; i++) {
638 cond_resched(); 678 cond_resched();
@@ -693,20 +733,8 @@ void policydb_destroy(struct policydb *p)
693 } 733 }
694 kfree(lra); 734 kfree(lra);
695 735
696 for (rt = p->range_tr; rt; rt = rt->next) { 736 hashtab_map(p->range_tr, range_tr_destroy, NULL);
697 cond_resched(); 737 hashtab_destroy(p->range_tr);
698 if (lrt) {
699 ebitmap_destroy(&lrt->target_range.level[0].cat);
700 ebitmap_destroy(&lrt->target_range.level[1].cat);
701 kfree(lrt);
702 }
703 lrt = rt;
704 }
705 if (lrt) {
706 ebitmap_destroy(&lrt->target_range.level[0].cat);
707 ebitmap_destroy(&lrt->target_range.level[1].cat);
708 kfree(lrt);
709 }
710 738
711 if (p->type_attr_map) { 739 if (p->type_attr_map) {
712 for (i = 0; i < p->p_types.nprim; i++) 740 for (i = 0; i < p->p_types.nprim; i++)
@@ -1686,12 +1714,11 @@ int policydb_read(struct policydb *p, void *fp)
1686 int i, j, rc; 1714 int i, j, rc;
1687 __le32 buf[4]; 1715 __le32 buf[4];
1688 u32 nodebuf[8]; 1716 u32 nodebuf[8];
1689 u32 len, len2, config, nprim, nel, nel2; 1717 u32 len, len2, nprim, nel, nel2;
1690 char *policydb_str; 1718 char *policydb_str;
1691 struct policydb_compat_info *info; 1719 struct policydb_compat_info *info;
1692 struct range_trans *rt, *lrt; 1720 struct range_trans *rt;
1693 1721 struct mls_range *r;
1694 config = 0;
1695 1722
1696 rc = policydb_init(p); 1723 rc = policydb_init(p);
1697 if (rc) 1724 if (rc)
@@ -1740,7 +1767,7 @@ int policydb_read(struct policydb *p, void *fp)
1740 kfree(policydb_str); 1767 kfree(policydb_str);
1741 policydb_str = NULL; 1768 policydb_str = NULL;
1742 1769
1743 /* Read the version, config, and table sizes. */ 1770 /* Read the version and table sizes. */
1744 rc = next_entry(buf, fp, sizeof(u32)*4); 1771 rc = next_entry(buf, fp, sizeof(u32)*4);
1745 if (rc < 0) 1772 if (rc < 0)
1746 goto bad; 1773 goto bad;
@@ -1755,13 +1782,7 @@ int policydb_read(struct policydb *p, void *fp)
1755 } 1782 }
1756 1783
1757 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { 1784 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
1758 if (ss_initialized && !selinux_mls_enabled) { 1785 p->mls_enabled = 1;
1759 printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
1760 " and MLS policies\n");
1761 goto bad;
1762 }
1763 selinux_mls_enabled = 1;
1764 config |= POLICYDB_CONFIG_MLS;
1765 1786
1766 if (p->policyvers < POLICYDB_VERSION_MLS) { 1787 if (p->policyvers < POLICYDB_VERSION_MLS) {
1767 printk(KERN_ERR "SELinux: security policydb version %d " 1788 printk(KERN_ERR "SELinux: security policydb version %d "
@@ -1769,12 +1790,6 @@ int policydb_read(struct policydb *p, void *fp)
1769 p->policyvers); 1790 p->policyvers);
1770 goto bad; 1791 goto bad;
1771 } 1792 }
1772 } else {
1773 if (ss_initialized && selinux_mls_enabled) {
1774 printk(KERN_ERR "SELinux: Cannot switch between MLS and"
1775 " non-MLS policies\n");
1776 goto bad;
1777 }
1778 } 1793 }
1779 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); 1794 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
1780 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); 1795 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
@@ -2122,47 +2137,64 @@ int policydb_read(struct policydb *p, void *fp)
2122 if (rc < 0) 2137 if (rc < 0)
2123 goto bad; 2138 goto bad;
2124 nel = le32_to_cpu(buf[0]); 2139 nel = le32_to_cpu(buf[0]);
2125 lrt = NULL;
2126 for (i = 0; i < nel; i++) { 2140 for (i = 0; i < nel; i++) {
2127 rt = kzalloc(sizeof(*rt), GFP_KERNEL); 2141 rt = kzalloc(sizeof(*rt), GFP_KERNEL);
2128 if (!rt) { 2142 if (!rt) {
2129 rc = -ENOMEM; 2143 rc = -ENOMEM;
2130 goto bad; 2144 goto bad;
2131 } 2145 }
2132 if (lrt)
2133 lrt->next = rt;
2134 else
2135 p->range_tr = rt;
2136 rc = next_entry(buf, fp, (sizeof(u32) * 2)); 2146 rc = next_entry(buf, fp, (sizeof(u32) * 2));
2137 if (rc < 0) 2147 if (rc < 0) {
2148 kfree(rt);
2138 goto bad; 2149 goto bad;
2150 }
2139 rt->source_type = le32_to_cpu(buf[0]); 2151 rt->source_type = le32_to_cpu(buf[0]);
2140 rt->target_type = le32_to_cpu(buf[1]); 2152 rt->target_type = le32_to_cpu(buf[1]);
2141 if (new_rangetr) { 2153 if (new_rangetr) {
2142 rc = next_entry(buf, fp, sizeof(u32)); 2154 rc = next_entry(buf, fp, sizeof(u32));
2143 if (rc < 0) 2155 if (rc < 0) {
2156 kfree(rt);
2144 goto bad; 2157 goto bad;
2158 }
2145 rt->target_class = le32_to_cpu(buf[0]); 2159 rt->target_class = le32_to_cpu(buf[0]);
2146 } else 2160 } else
2147 rt->target_class = p->process_class; 2161 rt->target_class = p->process_class;
2148 if (!policydb_type_isvalid(p, rt->source_type) || 2162 if (!policydb_type_isvalid(p, rt->source_type) ||
2149 !policydb_type_isvalid(p, rt->target_type) || 2163 !policydb_type_isvalid(p, rt->target_type) ||
2150 !policydb_class_isvalid(p, rt->target_class)) { 2164 !policydb_class_isvalid(p, rt->target_class)) {
2165 kfree(rt);
2151 rc = -EINVAL; 2166 rc = -EINVAL;
2152 goto bad; 2167 goto bad;
2153 } 2168 }
2154 rc = mls_read_range_helper(&rt->target_range, fp); 2169 r = kzalloc(sizeof(*r), GFP_KERNEL);
2155 if (rc) 2170 if (!r) {
2171 kfree(rt);
2172 rc = -ENOMEM;
2156 goto bad; 2173 goto bad;
2157 if (!mls_range_isvalid(p, &rt->target_range)) { 2174 }
2175 rc = mls_read_range_helper(r, fp);
2176 if (rc) {
2177 kfree(rt);
2178 kfree(r);
2179 goto bad;
2180 }
2181 if (!mls_range_isvalid(p, r)) {
2158 printk(KERN_WARNING "SELinux: rangetrans: invalid range\n"); 2182 printk(KERN_WARNING "SELinux: rangetrans: invalid range\n");
2183 kfree(rt);
2184 kfree(r);
2185 goto bad;
2186 }
2187 rc = hashtab_insert(p->range_tr, rt, r);
2188 if (rc) {
2189 kfree(rt);
2190 kfree(r);
2159 goto bad; 2191 goto bad;
2160 } 2192 }
2161 lrt = rt;
2162 } 2193 }
2194 rangetr_hash_eval(p->range_tr);
2163 } 2195 }
2164 2196
2165 p->type_attr_map = kmalloc(p->p_types.nprim*sizeof(struct ebitmap), GFP_KERNEL); 2197 p->type_attr_map = kmalloc(p->p_types.nprim * sizeof(struct ebitmap), GFP_KERNEL);
2166 if (!p->type_attr_map) 2198 if (!p->type_attr_map)
2167 goto bad; 2199 goto bad;
2168 2200
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index cdcc5700946f..26d9adf8542b 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -27,6 +27,8 @@
27#include "symtab.h" 27#include "symtab.h"
28#include "avtab.h" 28#include "avtab.h"
29#include "sidtab.h" 29#include "sidtab.h"
30#include "ebitmap.h"
31#include "mls_types.h"
30#include "context.h" 32#include "context.h"
31#include "constraint.h" 33#include "constraint.h"
32 34
@@ -113,8 +115,6 @@ struct range_trans {
113 u32 source_type; 115 u32 source_type;
114 u32 target_type; 116 u32 target_type;
115 u32 target_class; 117 u32 target_class;
116 struct mls_range target_range;
117 struct range_trans *next;
118}; 118};
119 119
120/* Boolean data type */ 120/* Boolean data type */
@@ -187,6 +187,8 @@ struct genfs {
187 187
188/* The policy database */ 188/* The policy database */
189struct policydb { 189struct policydb {
190 int mls_enabled;
191
190 /* symbol tables */ 192 /* symbol tables */
191 struct symtab symtab[SYM_NUM]; 193 struct symtab symtab[SYM_NUM];
192#define p_commons symtab[SYM_COMMONS] 194#define p_commons symtab[SYM_COMMONS]
@@ -240,8 +242,8 @@ struct policydb {
240 fixed labeling behavior. */ 242 fixed labeling behavior. */
241 struct genfs *genfs; 243 struct genfs *genfs;
242 244
243 /* range transitions */ 245 /* range transitions table (range_trans_key -> mls_range) */
244 struct range_trans *range_tr; 246 struct hashtab *range_tr;
245 247
246 /* type -> attribute reverse mapping */ 248 /* type -> attribute reverse mapping */
247 struct ebitmap *type_attr_map; 249 struct ebitmap *type_attr_map;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index b3efae204ac7..1de60ce90d9a 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -26,6 +26,10 @@
26 * 26 *
27 * Added support for bounds domain and audit messaged on masked permissions 27 * Added support for bounds domain and audit messaged on masked permissions
28 * 28 *
29 * Updated: Guido Trentalancia <guido@trentalancia.com>
30 *
31 * Added support for runtime switching of the policy type
32 *
29 * Copyright (C) 2008, 2009 NEC Corporation 33 * Copyright (C) 2008, 2009 NEC Corporation
30 * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. 34 * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
31 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. 35 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
@@ -87,11 +91,10 @@ static u32 latest_granting;
87static int context_struct_to_string(struct context *context, char **scontext, 91static int context_struct_to_string(struct context *context, char **scontext,
88 u32 *scontext_len); 92 u32 *scontext_len);
89 93
90static int context_struct_compute_av(struct context *scontext, 94static void context_struct_compute_av(struct context *scontext,
91 struct context *tcontext, 95 struct context *tcontext,
92 u16 tclass, 96 u16 tclass,
93 u32 requested, 97 struct av_decision *avd);
94 struct av_decision *avd);
95 98
96struct selinux_mapping { 99struct selinux_mapping {
97 u16 value; /* policy value */ 100 u16 value; /* policy value */
@@ -196,23 +199,6 @@ static u16 unmap_class(u16 tclass)
196 return tclass; 199 return tclass;
197} 200}
198 201
199static u32 unmap_perm(u16 tclass, u32 tperm)
200{
201 if (tclass < current_mapping_size) {
202 unsigned i;
203 u32 kperm = 0;
204
205 for (i = 0; i < current_mapping[tclass].num_perms; i++)
206 if (tperm & (1<<i)) {
207 kperm |= current_mapping[tclass].perms[i];
208 tperm &= ~(1<<i);
209 }
210 return kperm;
211 }
212
213 return tperm;
214}
215
216static void map_decision(u16 tclass, struct av_decision *avd, 202static void map_decision(u16 tclass, struct av_decision *avd,
217 int allow_unknown) 203 int allow_unknown)
218{ 204{
@@ -250,6 +236,10 @@ static void map_decision(u16 tclass, struct av_decision *avd,
250 } 236 }
251} 237}
252 238
239int security_mls_enabled(void)
240{
241 return policydb.mls_enabled;
242}
253 243
254/* 244/*
255 * Return the boolean value of a constraint expression 245 * Return the boolean value of a constraint expression
@@ -284,15 +274,15 @@ static int constraint_expr_eval(struct context *scontext,
284 case CEXPR_AND: 274 case CEXPR_AND:
285 BUG_ON(sp < 1); 275 BUG_ON(sp < 1);
286 sp--; 276 sp--;
287 s[sp] &= s[sp+1]; 277 s[sp] &= s[sp + 1];
288 break; 278 break;
289 case CEXPR_OR: 279 case CEXPR_OR:
290 BUG_ON(sp < 1); 280 BUG_ON(sp < 1);
291 sp--; 281 sp--;
292 s[sp] |= s[sp+1]; 282 s[sp] |= s[sp + 1];
293 break; 283 break;
294 case CEXPR_ATTR: 284 case CEXPR_ATTR:
295 if (sp == (CEXPR_MAXDEPTH-1)) 285 if (sp == (CEXPR_MAXDEPTH - 1))
296 return 0; 286 return 0;
297 switch (e->attr) { 287 switch (e->attr) {
298 case CEXPR_USER: 288 case CEXPR_USER:
@@ -465,7 +455,8 @@ static void security_dump_masked_av(struct context *scontext,
465 char *scontext_name = NULL; 455 char *scontext_name = NULL;
466 char *tcontext_name = NULL; 456 char *tcontext_name = NULL;
467 char *permission_names[32]; 457 char *permission_names[32];
468 int index, length; 458 int index;
459 u32 length;
469 bool need_comma = false; 460 bool need_comma = false;
470 461
471 if (!permissions) 462 if (!permissions)
@@ -532,7 +523,6 @@ out:
532static void type_attribute_bounds_av(struct context *scontext, 523static void type_attribute_bounds_av(struct context *scontext,
533 struct context *tcontext, 524 struct context *tcontext,
534 u16 tclass, 525 u16 tclass,
535 u32 requested,
536 struct av_decision *avd) 526 struct av_decision *avd)
537{ 527{
538 struct context lo_scontext; 528 struct context lo_scontext;
@@ -553,7 +543,6 @@ static void type_attribute_bounds_av(struct context *scontext,
553 context_struct_compute_av(&lo_scontext, 543 context_struct_compute_av(&lo_scontext,
554 tcontext, 544 tcontext,
555 tclass, 545 tclass,
556 requested,
557 &lo_avd); 546 &lo_avd);
558 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 547 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
559 return; /* no masked permission */ 548 return; /* no masked permission */
@@ -569,7 +558,6 @@ static void type_attribute_bounds_av(struct context *scontext,
569 context_struct_compute_av(scontext, 558 context_struct_compute_av(scontext,
570 &lo_tcontext, 559 &lo_tcontext,
571 tclass, 560 tclass,
572 requested,
573 &lo_avd); 561 &lo_avd);
574 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 562 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
575 return; /* no masked permission */ 563 return; /* no masked permission */
@@ -586,7 +574,6 @@ static void type_attribute_bounds_av(struct context *scontext,
586 context_struct_compute_av(&lo_scontext, 574 context_struct_compute_av(&lo_scontext,
587 &lo_tcontext, 575 &lo_tcontext,
588 tclass, 576 tclass,
589 requested,
590 &lo_avd); 577 &lo_avd);
591 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 578 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
592 return; /* no masked permission */ 579 return; /* no masked permission */
@@ -607,11 +594,10 @@ static void type_attribute_bounds_av(struct context *scontext,
607 * Compute access vectors based on a context structure pair for 594 * Compute access vectors based on a context structure pair for
608 * the permissions in a particular class. 595 * the permissions in a particular class.
609 */ 596 */
610static int context_struct_compute_av(struct context *scontext, 597static void context_struct_compute_av(struct context *scontext,
611 struct context *tcontext, 598 struct context *tcontext,
612 u16 tclass, 599 u16 tclass,
613 u32 requested, 600 struct av_decision *avd)
614 struct av_decision *avd)
615{ 601{
616 struct constraint_node *constraint; 602 struct constraint_node *constraint;
617 struct role_allow *ra; 603 struct role_allow *ra;
@@ -622,19 +608,14 @@ static int context_struct_compute_av(struct context *scontext,
622 struct ebitmap_node *snode, *tnode; 608 struct ebitmap_node *snode, *tnode;
623 unsigned int i, j; 609 unsigned int i, j;
624 610
625 /*
626 * Initialize the access vectors to the default values.
627 */
628 avd->allowed = 0; 611 avd->allowed = 0;
629 avd->auditallow = 0; 612 avd->auditallow = 0;
630 avd->auditdeny = 0xffffffff; 613 avd->auditdeny = 0xffffffff;
631 avd->seqno = latest_granting;
632 avd->flags = 0;
633 614
634 if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) { 615 if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) {
635 if (printk_ratelimit()) 616 if (printk_ratelimit())
636 printk(KERN_WARNING "SELinux: Invalid class %hu\n", tclass); 617 printk(KERN_WARNING "SELinux: Invalid class %hu\n", tclass);
637 return -EINVAL; 618 return;
638 } 619 }
639 620
640 tclass_datum = policydb.class_val_to_struct[tclass - 1]; 621 tclass_datum = policydb.class_val_to_struct[tclass - 1];
@@ -705,9 +686,7 @@ static int context_struct_compute_av(struct context *scontext,
705 * permission and notice it to userspace via audit. 686 * permission and notice it to userspace via audit.
706 */ 687 */
707 type_attribute_bounds_av(scontext, tcontext, 688 type_attribute_bounds_av(scontext, tcontext,
708 tclass, requested, avd); 689 tclass, avd);
709
710 return 0;
711} 690}
712 691
713static int security_validtrans_handle_fail(struct context *ocontext, 692static int security_validtrans_handle_fail(struct context *ocontext,
@@ -864,7 +843,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
864 if (rc) { 843 if (rc) {
865 char *old_name = NULL; 844 char *old_name = NULL;
866 char *new_name = NULL; 845 char *new_name = NULL;
867 int length; 846 u32 length;
868 847
869 if (!context_struct_to_string(old_context, 848 if (!context_struct_to_string(old_context,
870 &old_name, &length) && 849 &old_name, &length) &&
@@ -886,110 +865,116 @@ out:
886 return rc; 865 return rc;
887} 866}
888 867
889 868static void avd_init(struct av_decision *avd)
890static int security_compute_av_core(u32 ssid,
891 u32 tsid,
892 u16 tclass,
893 u32 requested,
894 struct av_decision *avd)
895{ 869{
896 struct context *scontext = NULL, *tcontext = NULL; 870 avd->allowed = 0;
897 int rc = 0; 871 avd->auditallow = 0;
898 872 avd->auditdeny = 0xffffffff;
899 scontext = sidtab_search(&sidtab, ssid); 873 avd->seqno = latest_granting;
900 if (!scontext) { 874 avd->flags = 0;
901 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
902 __func__, ssid);
903 return -EINVAL;
904 }
905 tcontext = sidtab_search(&sidtab, tsid);
906 if (!tcontext) {
907 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
908 __func__, tsid);
909 return -EINVAL;
910 }
911
912 rc = context_struct_compute_av(scontext, tcontext, tclass,
913 requested, avd);
914
915 /* permissive domain? */
916 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
917 avd->flags |= AVD_FLAGS_PERMISSIVE;
918
919 return rc;
920} 875}
921 876
877
922/** 878/**
923 * security_compute_av - Compute access vector decisions. 879 * security_compute_av - Compute access vector decisions.
924 * @ssid: source security identifier 880 * @ssid: source security identifier
925 * @tsid: target security identifier 881 * @tsid: target security identifier
926 * @tclass: target security class 882 * @tclass: target security class
927 * @requested: requested permissions
928 * @avd: access vector decisions 883 * @avd: access vector decisions
929 * 884 *
930 * Compute a set of access vector decisions based on the 885 * Compute a set of access vector decisions based on the
931 * SID pair (@ssid, @tsid) for the permissions in @tclass. 886 * SID pair (@ssid, @tsid) for the permissions in @tclass.
932 * Return -%EINVAL if any of the parameters are invalid or %0
933 * if the access vector decisions were computed successfully.
934 */ 887 */
935int security_compute_av(u32 ssid, 888void security_compute_av(u32 ssid,
936 u32 tsid, 889 u32 tsid,
937 u16 orig_tclass, 890 u16 orig_tclass,
938 u32 orig_requested, 891 struct av_decision *avd)
939 struct av_decision *avd)
940{ 892{
941 u16 tclass; 893 u16 tclass;
942 u32 requested; 894 struct context *scontext = NULL, *tcontext = NULL;
943 int rc;
944 895
945 read_lock(&policy_rwlock); 896 read_lock(&policy_rwlock);
946 897 avd_init(avd);
947 if (!ss_initialized) 898 if (!ss_initialized)
948 goto allow; 899 goto allow;
949 900
950 requested = unmap_perm(orig_tclass, orig_requested); 901 scontext = sidtab_search(&sidtab, ssid);
902 if (!scontext) {
903 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
904 __func__, ssid);
905 goto out;
906 }
907
908 /* permissive domain? */
909 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
910 avd->flags |= AVD_FLAGS_PERMISSIVE;
911
912 tcontext = sidtab_search(&sidtab, tsid);
913 if (!tcontext) {
914 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
915 __func__, tsid);
916 goto out;
917 }
918
951 tclass = unmap_class(orig_tclass); 919 tclass = unmap_class(orig_tclass);
952 if (unlikely(orig_tclass && !tclass)) { 920 if (unlikely(orig_tclass && !tclass)) {
953 if (policydb.allow_unknown) 921 if (policydb.allow_unknown)
954 goto allow; 922 goto allow;
955 rc = -EINVAL;
956 goto out; 923 goto out;
957 } 924 }
958 rc = security_compute_av_core(ssid, tsid, tclass, requested, avd); 925 context_struct_compute_av(scontext, tcontext, tclass, avd);
959 map_decision(orig_tclass, avd, policydb.allow_unknown); 926 map_decision(orig_tclass, avd, policydb.allow_unknown);
960out: 927out:
961 read_unlock(&policy_rwlock); 928 read_unlock(&policy_rwlock);
962 return rc; 929 return;
963allow: 930allow:
964 avd->allowed = 0xffffffff; 931 avd->allowed = 0xffffffff;
965 avd->auditallow = 0;
966 avd->auditdeny = 0xffffffff;
967 avd->seqno = latest_granting;
968 avd->flags = 0;
969 rc = 0;
970 goto out; 932 goto out;
971} 933}
972 934
973int security_compute_av_user(u32 ssid, 935void security_compute_av_user(u32 ssid,
974 u32 tsid, 936 u32 tsid,
975 u16 tclass, 937 u16 tclass,
976 u32 requested, 938 struct av_decision *avd)
977 struct av_decision *avd)
978{ 939{
979 int rc; 940 struct context *scontext = NULL, *tcontext = NULL;
980 941
981 if (!ss_initialized) { 942 read_lock(&policy_rwlock);
982 avd->allowed = 0xffffffff; 943 avd_init(avd);
983 avd->auditallow = 0; 944 if (!ss_initialized)
984 avd->auditdeny = 0xffffffff; 945 goto allow;
985 avd->seqno = latest_granting; 946
986 return 0; 947 scontext = sidtab_search(&sidtab, ssid);
948 if (!scontext) {
949 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
950 __func__, ssid);
951 goto out;
987 } 952 }
988 953
989 read_lock(&policy_rwlock); 954 /* permissive domain? */
990 rc = security_compute_av_core(ssid, tsid, tclass, requested, avd); 955 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
956 avd->flags |= AVD_FLAGS_PERMISSIVE;
957
958 tcontext = sidtab_search(&sidtab, tsid);
959 if (!tcontext) {
960 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
961 __func__, tsid);
962 goto out;
963 }
964
965 if (unlikely(!tclass)) {
966 if (policydb.allow_unknown)
967 goto allow;
968 goto out;
969 }
970
971 context_struct_compute_av(scontext, tcontext, tclass, avd);
972 out:
991 read_unlock(&policy_rwlock); 973 read_unlock(&policy_rwlock);
992 return rc; 974 return;
975allow:
976 avd->allowed = 0xffffffff;
977 goto out;
993} 978}
994 979
995/* 980/*
@@ -1231,7 +1216,7 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
1231 *sid = SECSID_NULL; 1216 *sid = SECSID_NULL;
1232 1217
1233 /* Copy the string so that we can modify the copy as we parse it. */ 1218 /* Copy the string so that we can modify the copy as we parse it. */
1234 scontext2 = kmalloc(scontext_len+1, gfp_flags); 1219 scontext2 = kmalloc(scontext_len + 1, gfp_flags);
1235 if (!scontext2) 1220 if (!scontext2)
1236 return -ENOMEM; 1221 return -ENOMEM;
1237 memcpy(scontext2, scontext, scontext_len); 1222 memcpy(scontext2, scontext, scontext_len);
@@ -1565,7 +1550,10 @@ static int clone_sid(u32 sid,
1565{ 1550{
1566 struct sidtab *s = arg; 1551 struct sidtab *s = arg;
1567 1552
1568 return sidtab_insert(s, sid, context); 1553 if (sid > SECINITSID_NUM)
1554 return sidtab_insert(s, sid, context);
1555 else
1556 return 0;
1569} 1557}
1570 1558
1571static inline int convert_context_handle_invalid_context(struct context *context) 1559static inline int convert_context_handle_invalid_context(struct context *context)
@@ -1606,12 +1594,17 @@ static int convert_context(u32 key,
1606{ 1594{
1607 struct convert_context_args *args; 1595 struct convert_context_args *args;
1608 struct context oldc; 1596 struct context oldc;
1597 struct ocontext *oc;
1598 struct mls_range *range;
1609 struct role_datum *role; 1599 struct role_datum *role;
1610 struct type_datum *typdatum; 1600 struct type_datum *typdatum;
1611 struct user_datum *usrdatum; 1601 struct user_datum *usrdatum;
1612 char *s; 1602 char *s;
1613 u32 len; 1603 u32 len;
1614 int rc; 1604 int rc = 0;
1605
1606 if (key <= SECINITSID_NUM)
1607 goto out;
1615 1608
1616 args = p; 1609 args = p;
1617 1610
@@ -1673,9 +1666,39 @@ static int convert_context(u32 key,
1673 goto bad; 1666 goto bad;
1674 c->type = typdatum->value; 1667 c->type = typdatum->value;
1675 1668
1676 rc = mls_convert_context(args->oldp, args->newp, c); 1669 /* Convert the MLS fields if dealing with MLS policies */
1677 if (rc) 1670 if (args->oldp->mls_enabled && args->newp->mls_enabled) {
1678 goto bad; 1671 rc = mls_convert_context(args->oldp, args->newp, c);
1672 if (rc)
1673 goto bad;
1674 } else if (args->oldp->mls_enabled && !args->newp->mls_enabled) {
1675 /*
1676 * Switching between MLS and non-MLS policy:
1677 * free any storage used by the MLS fields in the
1678 * context for all existing entries in the sidtab.
1679 */
1680 mls_context_destroy(c);
1681 } else if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
1682 /*
1683 * Switching between non-MLS and MLS policy:
1684 * ensure that the MLS fields of the context for all
1685 * existing entries in the sidtab are filled in with a
1686 * suitable default value, likely taken from one of the
1687 * initial SIDs.
1688 */
1689 oc = args->newp->ocontexts[OCON_ISID];
1690 while (oc && oc->sid[0] != SECINITSID_UNLABELED)
1691 oc = oc->next;
1692 if (!oc) {
1693 printk(KERN_ERR "SELinux: unable to look up"
1694 " the initial SIDs list\n");
1695 goto bad;
1696 }
1697 range = &oc->context[0].range;
1698 rc = mls_range_set(c, range);
1699 if (rc)
1700 goto bad;
1701 }
1679 1702
1680 /* Check the validity of the new context. */ 1703 /* Check the validity of the new context. */
1681 if (!policydb_context_isvalid(args->newp, c)) { 1704 if (!policydb_context_isvalid(args->newp, c)) {
@@ -1737,22 +1760,28 @@ int security_load_policy(void *data, size_t len)
1737 1760
1738 if (!ss_initialized) { 1761 if (!ss_initialized) {
1739 avtab_cache_init(); 1762 avtab_cache_init();
1740 if (policydb_read(&policydb, fp)) { 1763 rc = policydb_read(&policydb, fp);
1764 if (rc) {
1741 avtab_cache_destroy(); 1765 avtab_cache_destroy();
1742 return -EINVAL; 1766 return rc;
1743 } 1767 }
1744 if (selinux_set_mapping(&policydb, secclass_map, 1768
1745 &current_mapping, 1769 rc = selinux_set_mapping(&policydb, secclass_map,
1746 &current_mapping_size)) { 1770 &current_mapping,
1771 &current_mapping_size);
1772 if (rc) {
1747 policydb_destroy(&policydb); 1773 policydb_destroy(&policydb);
1748 avtab_cache_destroy(); 1774 avtab_cache_destroy();
1749 return -EINVAL; 1775 return rc;
1750 } 1776 }
1751 if (policydb_load_isids(&policydb, &sidtab)) { 1777
1778 rc = policydb_load_isids(&policydb, &sidtab);
1779 if (rc) {
1752 policydb_destroy(&policydb); 1780 policydb_destroy(&policydb);
1753 avtab_cache_destroy(); 1781 avtab_cache_destroy();
1754 return -EINVAL; 1782 return rc;
1755 } 1783 }
1784
1756 security_load_policycaps(); 1785 security_load_policycaps();
1757 ss_initialized = 1; 1786 ss_initialized = 1;
1758 seqno = ++latest_granting; 1787 seqno = ++latest_granting;
@@ -1768,16 +1797,25 @@ int security_load_policy(void *data, size_t len)
1768 sidtab_hash_eval(&sidtab, "sids"); 1797 sidtab_hash_eval(&sidtab, "sids");
1769#endif 1798#endif
1770 1799
1771 if (policydb_read(&newpolicydb, fp)) 1800 rc = policydb_read(&newpolicydb, fp);
1772 return -EINVAL; 1801 if (rc)
1802 return rc;
1803
1804 /* If switching between different policy types, log MLS status */
1805 if (policydb.mls_enabled && !newpolicydb.mls_enabled)
1806 printk(KERN_INFO "SELinux: Disabling MLS support...\n");
1807 else if (!policydb.mls_enabled && newpolicydb.mls_enabled)
1808 printk(KERN_INFO "SELinux: Enabling MLS support...\n");
1773 1809
1774 if (sidtab_init(&newsidtab)) { 1810 rc = policydb_load_isids(&newpolicydb, &newsidtab);
1811 if (rc) {
1812 printk(KERN_ERR "SELinux: unable to load the initial SIDs\n");
1775 policydb_destroy(&newpolicydb); 1813 policydb_destroy(&newpolicydb);
1776 return -ENOMEM; 1814 return rc;
1777 } 1815 }
1778 1816
1779 if (selinux_set_mapping(&newpolicydb, secclass_map, 1817 rc = selinux_set_mapping(&newpolicydb, secclass_map, &map, &map_size);
1780 &map, &map_size)) 1818 if (rc)
1781 goto err; 1819 goto err;
1782 1820
1783 rc = security_preserve_bools(&newpolicydb); 1821 rc = security_preserve_bools(&newpolicydb);
@@ -1788,10 +1826,10 @@ int security_load_policy(void *data, size_t len)
1788 1826
1789 /* Clone the SID table. */ 1827 /* Clone the SID table. */
1790 sidtab_shutdown(&sidtab); 1828 sidtab_shutdown(&sidtab);
1791 if (sidtab_map(&sidtab, clone_sid, &newsidtab)) { 1829
1792 rc = -ENOMEM; 1830 rc = sidtab_map(&sidtab, clone_sid, &newsidtab);
1831 if (rc)
1793 goto err; 1832 goto err;
1794 }
1795 1833
1796 /* 1834 /*
1797 * Convert the internal representations of contexts 1835 * Convert the internal representations of contexts
@@ -1800,8 +1838,12 @@ int security_load_policy(void *data, size_t len)
1800 args.oldp = &policydb; 1838 args.oldp = &policydb;
1801 args.newp = &newpolicydb; 1839 args.newp = &newpolicydb;
1802 rc = sidtab_map(&newsidtab, convert_context, &args); 1840 rc = sidtab_map(&newsidtab, convert_context, &args);
1803 if (rc) 1841 if (rc) {
1842 printk(KERN_ERR "SELinux: unable to convert the internal"
1843 " representation of contexts in the new SID"
1844 " table\n");
1804 goto err; 1845 goto err;
1846 }
1805 1847
1806 /* Save the old policydb and SID table to free later. */ 1848 /* Save the old policydb and SID table to free later. */
1807 memcpy(&oldpolicydb, &policydb, sizeof policydb); 1849 memcpy(&oldpolicydb, &policydb, sizeof policydb);
@@ -2066,9 +2108,9 @@ int security_get_user_sids(u32 fromsid,
2066 2108
2067 ebitmap_for_each_positive_bit(&user->roles, rnode, i) { 2109 ebitmap_for_each_positive_bit(&user->roles, rnode, i) {
2068 role = policydb.role_val_to_struct[i]; 2110 role = policydb.role_val_to_struct[i];
2069 usercon.role = i+1; 2111 usercon.role = i + 1;
2070 ebitmap_for_each_positive_bit(&role->types, tnode, j) { 2112 ebitmap_for_each_positive_bit(&role->types, tnode, j) {
2071 usercon.type = j+1; 2113 usercon.type = j + 1;
2072 2114
2073 if (mls_setup_user_range(fromcon, user, &usercon)) 2115 if (mls_setup_user_range(fromcon, user, &usercon))
2074 continue; 2116 continue;
@@ -2397,7 +2439,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2397 u32 len; 2439 u32 len;
2398 int rc = 0; 2440 int rc = 0;
2399 2441
2400 if (!ss_initialized || !selinux_mls_enabled) { 2442 if (!ss_initialized || !policydb.mls_enabled) {
2401 *new_sid = sid; 2443 *new_sid = sid;
2402 goto out; 2444 goto out;
2403 } 2445 }
@@ -2498,7 +2540,7 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2498 /* we don't need to check ss_initialized here since the only way both 2540 /* we don't need to check ss_initialized here since the only way both
2499 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the 2541 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
2500 * security server was initialized and ss_initialized was true */ 2542 * security server was initialized and ss_initialized was true */
2501 if (!selinux_mls_enabled) { 2543 if (!policydb.mls_enabled) {
2502 *peer_sid = SECSID_NULL; 2544 *peer_sid = SECSID_NULL;
2503 return 0; 2545 return 0;
2504 } 2546 }
@@ -2555,7 +2597,7 @@ int security_get_classes(char ***classes, int *nclasses)
2555 read_lock(&policy_rwlock); 2597 read_lock(&policy_rwlock);
2556 2598
2557 *nclasses = policydb.p_classes.nprim; 2599 *nclasses = policydb.p_classes.nprim;
2558 *classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC); 2600 *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC);
2559 if (!*classes) 2601 if (!*classes)
2560 goto out; 2602 goto out;
2561 2603
@@ -2602,7 +2644,7 @@ int security_get_permissions(char *class, char ***perms, int *nperms)
2602 } 2644 }
2603 2645
2604 *nperms = match->permissions.nprim; 2646 *nperms = match->permissions.nprim;
2605 *perms = kcalloc(*nperms, sizeof(*perms), GFP_ATOMIC); 2647 *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC);
2606 if (!*perms) 2648 if (!*perms)
2607 goto out; 2649 goto out;
2608 2650
diff --git a/security/selinux/ss/symtab.c b/security/selinux/ss/symtab.c
index 837658a98a54..bcf9f620426e 100644
--- a/security/selinux/ss/symtab.c
+++ b/security/selinux/ss/symtab.c
@@ -4,7 +4,6 @@
4 * Author : Stephen Smalley, <sds@epoch.ncsc.mil> 4 * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
5 */ 5 */
6#include <linux/kernel.h> 6#include <linux/kernel.h>
7#include <linux/slab.h>
8#include <linux/string.h> 7#include <linux/string.h>
9#include <linux/errno.h> 8#include <linux/errno.h>
10#include "symtab.h" 9#include "symtab.h"
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index f3cb9ed731a9..fff78d3b51a2 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -38,6 +38,7 @@
38#include <linux/netfilter.h> 38#include <linux/netfilter.h>
39#include <linux/netfilter_ipv4.h> 39#include <linux/netfilter_ipv4.h>
40#include <linux/netfilter_ipv6.h> 40#include <linux/netfilter_ipv6.h>
41#include <linux/slab.h>
41#include <linux/ip.h> 42#include <linux/ip.h>
42#include <linux/tcp.h> 43#include <linux/tcp.h>
43#include <linux/skbuff.h> 44#include <linux/skbuff.h>