aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /security/selinux
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/Makefile21
-rw-r--r--security/selinux/avc.c63
-rw-r--r--security/selinux/exports.c49
-rw-r--r--security/selinux/hooks.c566
-rw-r--r--security/selinux/include/avc.h20
-rw-r--r--security/selinux/include/classmap.h11
-rw-r--r--security/selinux/include/security.h36
-rw-r--r--security/selinux/include/xfrm.h2
-rw-r--r--security/selinux/netif.c18
-rw-r--r--security/selinux/netlabel.c2
-rw-r--r--security/selinux/netnode.c1
-rw-r--r--security/selinux/nlmsgtab.c2
-rw-r--r--security/selinux/selinuxfs.c939
-rw-r--r--security/selinux/ss/Makefile9
-rw-r--r--security/selinux/ss/avtab.c46
-rw-r--r--security/selinux/ss/avtab.h26
-rw-r--r--security/selinux/ss/conditional.c131
-rw-r--r--security/selinux/ss/conditional.h2
-rw-r--r--security/selinux/ss/ebitmap.c81
-rw-r--r--security/selinux/ss/ebitmap.h2
-rw-r--r--security/selinux/ss/mls.c30
-rw-r--r--security/selinux/ss/mls.h3
-rw-r--r--security/selinux/ss/policydb.c1817
-rw-r--r--security/selinux/ss/policydb.h59
-rw-r--r--security/selinux/ss/services.c596
-rw-r--r--security/selinux/ss/sidtab.c39
-rw-r--r--security/selinux/ss/sidtab.h2
-rw-r--r--security/selinux/ss/status.c126
-rw-r--r--security/selinux/xfrm.c8
29 files changed, 3308 insertions, 1399 deletions
diff --git a/security/selinux/Makefile b/security/selinux/Makefile
index 58d80f3bd6f6..ad5cd76ec231 100644
--- a/security/selinux/Makefile
+++ b/security/selinux/Makefile
@@ -2,25 +2,20 @@
2# Makefile for building the SELinux module as part of the kernel tree. 2# Makefile for building the SELinux module as part of the kernel tree.
3# 3#
4 4
5obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/ 5obj-$(CONFIG_SECURITY_SELINUX) := selinux.o
6 6
7selinux-y := avc.o \ 7selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \
8 hooks.o \ 8 netnode.o netport.o exports.o \
9 selinuxfs.o \ 9 ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \
10 netlink.o \ 10 ss/policydb.o ss/services.o ss/conditional.o ss/mls.o ss/status.o
11 nlmsgtab.o \
12 netif.o \
13 netnode.o \
14 netport.o \
15 exports.o
16 11
17selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o 12selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o
18 13
19selinux-$(CONFIG_NETLABEL) += netlabel.o 14selinux-$(CONFIG_NETLABEL) += netlabel.o
20 15
21EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include 16ccflags-y := -Isecurity/selinux -Isecurity/selinux/include
22 17
23$(obj)/avc.o: $(obj)/flask.h 18$(addprefix $(obj)/,$(selinux-y)): $(obj)/flask.h
24 19
25quiet_cmd_flask = GEN $(obj)/flask.h $(obj)/av_permissions.h 20quiet_cmd_flask = GEN $(obj)/flask.h $(obj)/av_permissions.h
26 cmd_flask = scripts/selinux/genheaders/genheaders $(obj)/flask.h $(obj)/av_permissions.h 21 cmd_flask = scripts/selinux/genheaders/genheaders $(obj)/flask.h $(obj)/av_permissions.h
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 9da6420e2056..d515b2128a4e 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -38,11 +38,7 @@
38#define AVC_CACHE_RECLAIM 16 38#define AVC_CACHE_RECLAIM 16
39 39
40#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS 40#ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
41#define avc_cache_stats_incr(field) \ 41#define avc_cache_stats_incr(field) this_cpu_inc(avc_cache_stats.field)
42do { \
43 per_cpu(avc_cache_stats, get_cpu()).field++; \
44 put_cpu(); \
45} while (0)
46#else 42#else
47#define avc_cache_stats_incr(field) do {} while (0) 43#define avc_cache_stats_incr(field) do {} while (0)
48#endif 44#endif
@@ -347,11 +343,10 @@ static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass)
347 node = avc_search_node(ssid, tsid, tclass); 343 node = avc_search_node(ssid, tsid, tclass);
348 344
349 if (node) 345 if (node)
350 avc_cache_stats_incr(hits); 346 return node;
351 else
352 avc_cache_stats_incr(misses);
353 347
354 return node; 348 avc_cache_stats_incr(misses);
349 return NULL;
355} 350}
356 351
357static int avc_latest_notif_update(int seqno, int is_insert) 352static int avc_latest_notif_update(int seqno, int is_insert)
@@ -471,6 +466,7 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
471 * @avd: access vector decisions 466 * @avd: access vector decisions
472 * @result: result from avc_has_perm_noaudit 467 * @result: result from avc_has_perm_noaudit
473 * @a: auxiliary audit data 468 * @a: auxiliary audit data
469 * @flags: VFS walk flags
474 * 470 *
475 * Audit the granting or denial of permissions in accordance 471 * Audit the granting or denial of permissions in accordance
476 * with the policy. This function is typically called by 472 * with the policy. This function is typically called by
@@ -481,9 +477,10 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
481 * be performed under a lock, to allow the lock to be released 477 * be performed under a lock, to allow the lock to be released
482 * before calling the auditing code. 478 * before calling the auditing code.
483 */ 479 */
484void avc_audit(u32 ssid, u32 tsid, 480int avc_audit(u32 ssid, u32 tsid,
485 u16 tclass, u32 requested, 481 u16 tclass, u32 requested,
486 struct av_decision *avd, int result, struct common_audit_data *a) 482 struct av_decision *avd, int result, struct common_audit_data *a,
483 unsigned flags)
487{ 484{
488 struct common_audit_data stack_data; 485 struct common_audit_data stack_data;
489 u32 denied, audited; 486 u32 denied, audited;
@@ -515,11 +512,24 @@ void avc_audit(u32 ssid, u32 tsid,
515 else 512 else
516 audited = requested & avd->auditallow; 513 audited = requested & avd->auditallow;
517 if (!audited) 514 if (!audited)
518 return; 515 return 0;
516
519 if (!a) { 517 if (!a) {
520 a = &stack_data; 518 a = &stack_data;
521 COMMON_AUDIT_DATA_INIT(a, NONE); 519 COMMON_AUDIT_DATA_INIT(a, NONE);
522 } 520 }
521
522 /*
523 * When in a RCU walk do the audit on the RCU retry. This is because
524 * the collection of the dname in an inode audit message is not RCU
525 * safe. Note this may drop some audits when the situation changes
526 * during retry. However this is logically just as if the operation
527 * happened a little later.
528 */
529 if ((a->type == LSM_AUDIT_DATA_INODE) &&
530 (flags & IPERM_FLAG_RCU))
531 return -ECHILD;
532
523 a->selinux_audit_data.tclass = tclass; 533 a->selinux_audit_data.tclass = tclass;
524 a->selinux_audit_data.requested = requested; 534 a->selinux_audit_data.requested = requested;
525 a->selinux_audit_data.ssid = ssid; 535 a->selinux_audit_data.ssid = ssid;
@@ -529,6 +539,7 @@ void avc_audit(u32 ssid, u32 tsid,
529 a->lsm_pre_audit = avc_audit_pre_callback; 539 a->lsm_pre_audit = avc_audit_pre_callback;
530 a->lsm_post_audit = avc_audit_post_callback; 540 a->lsm_post_audit = avc_audit_post_callback;
531 common_lsm_audit(a); 541 common_lsm_audit(a);
542 return 0;
532} 543}
533 544
534/** 545/**
@@ -741,10 +752,9 @@ int avc_ss_reset(u32 seqno)
741int avc_has_perm_noaudit(u32 ssid, u32 tsid, 752int avc_has_perm_noaudit(u32 ssid, u32 tsid,
742 u16 tclass, u32 requested, 753 u16 tclass, u32 requested,
743 unsigned flags, 754 unsigned flags,
744 struct av_decision *in_avd) 755 struct av_decision *avd)
745{ 756{
746 struct avc_node *node; 757 struct avc_node *node;
747 struct av_decision avd_entry, *avd;
748 int rc = 0; 758 int rc = 0;
749 u32 denied; 759 u32 denied;
750 760
@@ -753,20 +763,13 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
753 rcu_read_lock(); 763 rcu_read_lock();
754 764
755 node = avc_lookup(ssid, tsid, tclass); 765 node = avc_lookup(ssid, tsid, tclass);
756 if (!node) { 766 if (unlikely(!node)) {
757 rcu_read_unlock(); 767 rcu_read_unlock();
758
759 if (in_avd)
760 avd = in_avd;
761 else
762 avd = &avd_entry;
763
764 security_compute_av(ssid, tsid, tclass, avd); 768 security_compute_av(ssid, tsid, tclass, avd);
765 rcu_read_lock(); 769 rcu_read_lock();
766 node = avc_insert(ssid, tsid, tclass, avd); 770 node = avc_insert(ssid, tsid, tclass, avd);
767 } else { 771 } else {
768 if (in_avd) 772 memcpy(avd, &node->ae.avd, sizeof(*avd));
769 memcpy(in_avd, &node->ae.avd, sizeof(*in_avd));
770 avd = &node->ae.avd; 773 avd = &node->ae.avd;
771 } 774 }
772 775
@@ -793,6 +796,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
793 * @tclass: target security class 796 * @tclass: target security class
794 * @requested: requested permissions, interpreted based on @tclass 797 * @requested: requested permissions, interpreted based on @tclass
795 * @auditdata: auxiliary audit data 798 * @auditdata: auxiliary audit data
799 * @flags: VFS walk flags
796 * 800 *
797 * Check the AVC to determine whether the @requested permissions are granted 801 * Check the AVC to determine whether the @requested permissions are granted
798 * for the SID pair (@ssid, @tsid), interpreting the permissions 802 * for the SID pair (@ssid, @tsid), interpreting the permissions
@@ -802,14 +806,19 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
802 * permissions are granted, -%EACCES if any permissions are denied, or 806 * permissions are granted, -%EACCES if any permissions are denied, or
803 * another -errno upon other errors. 807 * another -errno upon other errors.
804 */ 808 */
805int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, 809int avc_has_perm_flags(u32 ssid, u32 tsid, u16 tclass,
806 u32 requested, struct common_audit_data *auditdata) 810 u32 requested, struct common_audit_data *auditdata,
811 unsigned flags)
807{ 812{
808 struct av_decision avd; 813 struct av_decision avd;
809 int rc; 814 int rc, rc2;
810 815
811 rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd); 816 rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd);
812 avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata); 817
818 rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata,
819 flags);
820 if (rc2)
821 return rc2;
813 return rc; 822 return rc;
814} 823}
815 824
diff --git a/security/selinux/exports.c b/security/selinux/exports.c
index c0a454aee1e0..90664385dead 100644
--- a/security/selinux/exports.c
+++ b/security/selinux/exports.c
@@ -11,58 +11,9 @@
11 * it under the terms of the GNU General Public License version 2, 11 * it under the terms of the GNU General Public License version 2,
12 * as published by the Free Software Foundation. 12 * as published by the Free Software Foundation.
13 */ 13 */
14#include <linux/types.h>
15#include <linux/kernel.h>
16#include <linux/module.h> 14#include <linux/module.h>
17#include <linux/selinux.h>
18#include <linux/fs.h>
19#include <linux/ipc.h>
20#include <asm/atomic.h>
21 15
22#include "security.h" 16#include "security.h"
23#include "objsec.h"
24
25/* SECMARK reference count */
26extern atomic_t selinux_secmark_refcount;
27
28int selinux_string_to_sid(char *str, u32 *sid)
29{
30 if (selinux_enabled)
31 return security_context_to_sid(str, strlen(str), sid);
32 else {
33 *sid = 0;
34 return 0;
35 }
36}
37EXPORT_SYMBOL_GPL(selinux_string_to_sid);
38
39int selinux_secmark_relabel_packet_permission(u32 sid)
40{
41 if (selinux_enabled) {
42 const struct task_security_struct *__tsec;
43 u32 tsid;
44
45 __tsec = current_security();
46 tsid = __tsec->sid;
47
48 return avc_has_perm(tsid, sid, SECCLASS_PACKET,
49 PACKET__RELABELTO, NULL);
50 }
51 return 0;
52}
53EXPORT_SYMBOL_GPL(selinux_secmark_relabel_packet_permission);
54
55void selinux_secmark_refcount_inc(void)
56{
57 atomic_inc(&selinux_secmark_refcount);
58}
59EXPORT_SYMBOL_GPL(selinux_secmark_refcount_inc);
60
61void selinux_secmark_refcount_dec(void)
62{
63 atomic_dec(&selinux_secmark_refcount);
64}
65EXPORT_SYMBOL_GPL(selinux_secmark_refcount_dec);
66 17
67bool selinux_is_enabled(void) 18bool selinux_is_enabled(void)
68{ 19{
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 4796ddd4e721..20219ef5439a 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -24,9 +24,11 @@
24 */ 24 */
25 25
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/kd.h>
27#include <linux/kernel.h> 28#include <linux/kernel.h>
28#include <linux/tracehook.h> 29#include <linux/tracehook.h>
29#include <linux/errno.h> 30#include <linux/errno.h>
31#include <linux/ext2_fs.h>
30#include <linux/sched.h> 32#include <linux/sched.h>
31#include <linux/security.h> 33#include <linux/security.h>
32#include <linux/xattr.h> 34#include <linux/xattr.h>
@@ -36,14 +38,15 @@
36#include <linux/mman.h> 38#include <linux/mman.h>
37#include <linux/slab.h> 39#include <linux/slab.h>
38#include <linux/pagemap.h> 40#include <linux/pagemap.h>
41#include <linux/proc_fs.h>
39#include <linux/swap.h> 42#include <linux/swap.h>
40#include <linux/spinlock.h> 43#include <linux/spinlock.h>
41#include <linux/syscalls.h> 44#include <linux/syscalls.h>
45#include <linux/dcache.h>
42#include <linux/file.h> 46#include <linux/file.h>
43#include <linux/fdtable.h> 47#include <linux/fdtable.h>
44#include <linux/namei.h> 48#include <linux/namei.h>
45#include <linux/mount.h> 49#include <linux/mount.h>
46#include <linux/proc_fs.h>
47#include <linux/netfilter_ipv4.h> 50#include <linux/netfilter_ipv4.h>
48#include <linux/netfilter_ipv6.h> 51#include <linux/netfilter_ipv6.h>
49#include <linux/tty.h> 52#include <linux/tty.h>
@@ -70,13 +73,13 @@
70#include <net/ipv6.h> 73#include <net/ipv6.h>
71#include <linux/hugetlb.h> 74#include <linux/hugetlb.h>
72#include <linux/personality.h> 75#include <linux/personality.h>
73#include <linux/sysctl.h>
74#include <linux/audit.h> 76#include <linux/audit.h>
75#include <linux/string.h> 77#include <linux/string.h>
76#include <linux/selinux.h> 78#include <linux/selinux.h>
77#include <linux/mutex.h> 79#include <linux/mutex.h>
78#include <linux/posix-timers.h> 80#include <linux/posix-timers.h>
79#include <linux/syslog.h> 81#include <linux/syslog.h>
82#include <linux/user_namespace.h>
80 83
81#include "avc.h" 84#include "avc.h"
82#include "objsec.h" 85#include "objsec.h"
@@ -987,6 +990,7 @@ static void selinux_write_opts(struct seq_file *m,
987 continue; 990 continue;
988 default: 991 default:
989 BUG(); 992 BUG();
993 return;
990 }; 994 };
991 /* we need a comma before each option */ 995 /* we need a comma before each option */
992 seq_putc(m, ','); 996 seq_putc(m, ',');
@@ -1120,39 +1124,35 @@ static inline u16 socket_type_to_security_class(int family, int type, int protoc
1120} 1124}
1121 1125
1122#ifdef CONFIG_PROC_FS 1126#ifdef CONFIG_PROC_FS
1123static int selinux_proc_get_sid(struct proc_dir_entry *de, 1127static int selinux_proc_get_sid(struct dentry *dentry,
1124 u16 tclass, 1128 u16 tclass,
1125 u32 *sid) 1129 u32 *sid)
1126{ 1130{
1127 int buflen, rc; 1131 int rc;
1128 char *buffer, *path, *end; 1132 char *buffer, *path;
1129 1133
1130 buffer = (char *)__get_free_page(GFP_KERNEL); 1134 buffer = (char *)__get_free_page(GFP_KERNEL);
1131 if (!buffer) 1135 if (!buffer)
1132 return -ENOMEM; 1136 return -ENOMEM;
1133 1137
1134 buflen = PAGE_SIZE; 1138 path = dentry_path_raw(dentry, buffer, PAGE_SIZE);
1135 end = buffer+buflen; 1139 if (IS_ERR(path))
1136 *--end = '\0'; 1140 rc = PTR_ERR(path);
1137 buflen--; 1141 else {
1138 path = end-1; 1142 /* each process gets a /proc/PID/ entry. Strip off the
1139 *path = '/'; 1143 * PID part to get a valid selinux labeling.
1140 while (de && de != de->parent) { 1144 * e.g. /proc/1/net/rpc/nfs -> /net/rpc/nfs */
1141 buflen -= de->namelen + 1; 1145 while (path[1] >= '0' && path[1] <= '9') {
1142 if (buflen < 0) 1146 path[1] = '/';
1143 break; 1147 path++;
1144 end -= de->namelen; 1148 }
1145 memcpy(end, de->name, de->namelen); 1149 rc = security_genfs_sid("proc", path, tclass, sid);
1146 *--end = '/';
1147 path = end;
1148 de = de->parent;
1149 } 1150 }
1150 rc = security_genfs_sid("proc", path, tclass, sid);
1151 free_page((unsigned long)buffer); 1151 free_page((unsigned long)buffer);
1152 return rc; 1152 return rc;
1153} 1153}
1154#else 1154#else
1155static int selinux_proc_get_sid(struct proc_dir_entry *de, 1155static int selinux_proc_get_sid(struct dentry *dentry,
1156 u16 tclass, 1156 u16 tclass,
1157 u32 *sid) 1157 u32 *sid)
1158{ 1158{
@@ -1300,10 +1300,8 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1300 1300
1301 /* Try to obtain a transition SID. */ 1301 /* Try to obtain a transition SID. */
1302 isec->sclass = inode_mode_to_security_class(inode->i_mode); 1302 isec->sclass = inode_mode_to_security_class(inode->i_mode);
1303 rc = security_transition_sid(isec->task_sid, 1303 rc = security_transition_sid(isec->task_sid, sbsec->sid,
1304 sbsec->sid, 1304 isec->sclass, NULL, &sid);
1305 isec->sclass,
1306 &sid);
1307 if (rc) 1305 if (rc)
1308 goto out_unlock; 1306 goto out_unlock;
1309 isec->sid = sid; 1307 isec->sid = sid;
@@ -1316,10 +1314,9 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
1316 isec->sid = sbsec->sid; 1314 isec->sid = sbsec->sid;
1317 1315
1318 if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) { 1316 if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) {
1319 struct proc_inode *proci = PROC_I(inode); 1317 if (opt_dentry) {
1320 if (proci->pde) {
1321 isec->sclass = inode_mode_to_security_class(inode->i_mode); 1318 isec->sclass = inode_mode_to_security_class(inode->i_mode);
1322 rc = selinux_proc_get_sid(proci->pde, 1319 rc = selinux_proc_get_sid(opt_dentry,
1323 isec->sclass, 1320 isec->sclass,
1324 &sid); 1321 &sid);
1325 if (rc) 1322 if (rc)
@@ -1447,11 +1444,15 @@ static int task_has_capability(struct task_struct *tsk,
1447 printk(KERN_ERR 1444 printk(KERN_ERR
1448 "SELinux: out of range capability %d\n", cap); 1445 "SELinux: out of range capability %d\n", cap);
1449 BUG(); 1446 BUG();
1447 return -EINVAL;
1450 } 1448 }
1451 1449
1452 rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd); 1450 rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd);
1453 if (audit == SECURITY_CAP_AUDIT) 1451 if (audit == SECURITY_CAP_AUDIT) {
1454 avc_audit(sid, sid, sclass, av, &avd, rc, &ad); 1452 int rc2 = avc_audit(sid, sid, sclass, av, &avd, rc, &ad, 0);
1453 if (rc2)
1454 return rc2;
1455 }
1455 return rc; 1456 return rc;
1456} 1457}
1457 1458
@@ -1471,10 +1472,10 @@ static int task_has_system(struct task_struct *tsk,
1471static int inode_has_perm(const struct cred *cred, 1472static int inode_has_perm(const struct cred *cred,
1472 struct inode *inode, 1473 struct inode *inode,
1473 u32 perms, 1474 u32 perms,
1474 struct common_audit_data *adp) 1475 struct common_audit_data *adp,
1476 unsigned flags)
1475{ 1477{
1476 struct inode_security_struct *isec; 1478 struct inode_security_struct *isec;
1477 struct common_audit_data ad;
1478 u32 sid; 1479 u32 sid;
1479 1480
1480 validate_creds(cred); 1481 validate_creds(cred);
@@ -1485,30 +1486,49 @@ static int inode_has_perm(const struct cred *cred,
1485 sid = cred_sid(cred); 1486 sid = cred_sid(cred);
1486 isec = inode->i_security; 1487 isec = inode->i_security;
1487 1488
1488 if (!adp) { 1489 return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
1489 adp = &ad; 1490}
1490 COMMON_AUDIT_DATA_INIT(&ad, FS);
1491 ad.u.fs.inode = inode;
1492 }
1493 1491
1494 return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp); 1492static int inode_has_perm_noadp(const struct cred *cred,
1493 struct inode *inode,
1494 u32 perms,
1495 unsigned flags)
1496{
1497 struct common_audit_data ad;
1498
1499 COMMON_AUDIT_DATA_INIT(&ad, INODE);
1500 ad.u.inode = inode;
1501 return inode_has_perm(cred, inode, perms, &ad, flags);
1495} 1502}
1496 1503
1497/* Same as inode_has_perm, but pass explicit audit data containing 1504/* Same as inode_has_perm, but pass explicit audit data containing
1498 the dentry to help the auditing code to more easily generate the 1505 the dentry to help the auditing code to more easily generate the
1499 pathname if needed. */ 1506 pathname if needed. */
1500static inline int dentry_has_perm(const struct cred *cred, 1507static inline int dentry_has_perm(const struct cred *cred,
1501 struct vfsmount *mnt,
1502 struct dentry *dentry, 1508 struct dentry *dentry,
1503 u32 av) 1509 u32 av)
1504{ 1510{
1505 struct inode *inode = dentry->d_inode; 1511 struct inode *inode = dentry->d_inode;
1506 struct common_audit_data ad; 1512 struct common_audit_data ad;
1507 1513
1508 COMMON_AUDIT_DATA_INIT(&ad, FS); 1514 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1509 ad.u.fs.path.mnt = mnt; 1515 ad.u.dentry = dentry;
1510 ad.u.fs.path.dentry = dentry; 1516 return inode_has_perm(cred, inode, av, &ad, 0);
1511 return inode_has_perm(cred, inode, av, &ad); 1517}
1518
1519/* Same as inode_has_perm, but pass explicit audit data containing
1520 the path to help the auditing code to more easily generate the
1521 pathname if needed. */
1522static inline int path_has_perm(const struct cred *cred,
1523 struct path *path,
1524 u32 av)
1525{
1526 struct inode *inode = path->dentry->d_inode;
1527 struct common_audit_data ad;
1528
1529 COMMON_AUDIT_DATA_INIT(&ad, PATH);
1530 ad.u.path = *path;
1531 return inode_has_perm(cred, inode, av, &ad, 0);
1512} 1532}
1513 1533
1514/* Check whether a task can use an open file descriptor to 1534/* Check whether a task can use an open file descriptor to
@@ -1529,8 +1549,8 @@ static int file_has_perm(const struct cred *cred,
1529 u32 sid = cred_sid(cred); 1549 u32 sid = cred_sid(cred);
1530 int rc; 1550 int rc;
1531 1551
1532 COMMON_AUDIT_DATA_INIT(&ad, FS); 1552 COMMON_AUDIT_DATA_INIT(&ad, PATH);
1533 ad.u.fs.path = file->f_path; 1553 ad.u.path = file->f_path;
1534 1554
1535 if (sid != fsec->sid) { 1555 if (sid != fsec->sid) {
1536 rc = avc_has_perm(sid, fsec->sid, 1556 rc = avc_has_perm(sid, fsec->sid,
@@ -1544,7 +1564,7 @@ static int file_has_perm(const struct cred *cred,
1544 /* av is zero if only checking access to the descriptor. */ 1564 /* av is zero if only checking access to the descriptor. */
1545 rc = 0; 1565 rc = 0;
1546 if (av) 1566 if (av)
1547 rc = inode_has_perm(cred, inode, av, &ad); 1567 rc = inode_has_perm(cred, inode, av, &ad, 0);
1548 1568
1549out: 1569out:
1550 return rc; 1570 return rc;
@@ -1568,8 +1588,8 @@ static int may_create(struct inode *dir,
1568 sid = tsec->sid; 1588 sid = tsec->sid;
1569 newsid = tsec->create_sid; 1589 newsid = tsec->create_sid;
1570 1590
1571 COMMON_AUDIT_DATA_INIT(&ad, FS); 1591 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1572 ad.u.fs.path.dentry = dentry; 1592 ad.u.dentry = dentry;
1573 1593
1574 rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, 1594 rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
1575 DIR__ADD_NAME | DIR__SEARCH, 1595 DIR__ADD_NAME | DIR__SEARCH,
@@ -1578,7 +1598,8 @@ static int may_create(struct inode *dir,
1578 return rc; 1598 return rc;
1579 1599
1580 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { 1600 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
1581 rc = security_transition_sid(sid, dsec->sid, tclass, &newsid); 1601 rc = security_transition_sid(sid, dsec->sid, tclass,
1602 &dentry->d_name, &newsid);
1582 if (rc) 1603 if (rc)
1583 return rc; 1604 return rc;
1584 } 1605 }
@@ -1620,8 +1641,8 @@ static int may_link(struct inode *dir,
1620 dsec = dir->i_security; 1641 dsec = dir->i_security;
1621 isec = dentry->d_inode->i_security; 1642 isec = dentry->d_inode->i_security;
1622 1643
1623 COMMON_AUDIT_DATA_INIT(&ad, FS); 1644 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1624 ad.u.fs.path.dentry = dentry; 1645 ad.u.dentry = dentry;
1625 1646
1626 av = DIR__SEARCH; 1647 av = DIR__SEARCH;
1627 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); 1648 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
@@ -1666,9 +1687,9 @@ static inline int may_rename(struct inode *old_dir,
1666 old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); 1687 old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
1667 new_dsec = new_dir->i_security; 1688 new_dsec = new_dir->i_security;
1668 1689
1669 COMMON_AUDIT_DATA_INIT(&ad, FS); 1690 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1670 1691
1671 ad.u.fs.path.dentry = old_dentry; 1692 ad.u.dentry = old_dentry;
1672 rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, 1693 rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
1673 DIR__REMOVE_NAME | DIR__SEARCH, &ad); 1694 DIR__REMOVE_NAME | DIR__SEARCH, &ad);
1674 if (rc) 1695 if (rc)
@@ -1684,7 +1705,7 @@ static inline int may_rename(struct inode *old_dir,
1684 return rc; 1705 return rc;
1685 } 1706 }
1686 1707
1687 ad.u.fs.path.dentry = new_dentry; 1708 ad.u.dentry = new_dentry;
1688 av = DIR__ADD_NAME | DIR__SEARCH; 1709 av = DIR__ADD_NAME | DIR__SEARCH;
1689 if (new_dentry->d_inode) 1710 if (new_dentry->d_inode)
1690 av |= DIR__REMOVE_NAME; 1711 av |= DIR__REMOVE_NAME;
@@ -1851,93 +1872,17 @@ static int selinux_capset(struct cred *new, const struct cred *old,
1851 */ 1872 */
1852 1873
1853static int selinux_capable(struct task_struct *tsk, const struct cred *cred, 1874static int selinux_capable(struct task_struct *tsk, const struct cred *cred,
1854 int cap, int audit) 1875 struct user_namespace *ns, int cap, int audit)
1855{ 1876{
1856 int rc; 1877 int rc;
1857 1878
1858 rc = cap_capable(tsk, cred, cap, audit); 1879 rc = cap_capable(tsk, cred, ns, cap, audit);
1859 if (rc) 1880 if (rc)
1860 return rc; 1881 return rc;
1861 1882
1862 return task_has_capability(tsk, cred, cap, audit); 1883 return task_has_capability(tsk, cred, cap, audit);
1863} 1884}
1864 1885
1865static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid)
1866{
1867 int buflen, rc;
1868 char *buffer, *path, *end;
1869
1870 rc = -ENOMEM;
1871 buffer = (char *)__get_free_page(GFP_KERNEL);
1872 if (!buffer)
1873 goto out;
1874
1875 buflen = PAGE_SIZE;
1876 end = buffer+buflen;
1877 *--end = '\0';
1878 buflen--;
1879 path = end-1;
1880 *path = '/';
1881 while (table) {
1882 const char *name = table->procname;
1883 size_t namelen = strlen(name);
1884 buflen -= namelen + 1;
1885 if (buflen < 0)
1886 goto out_free;
1887 end -= namelen;
1888 memcpy(end, name, namelen);
1889 *--end = '/';
1890 path = end;
1891 table = table->parent;
1892 }
1893 buflen -= 4;
1894 if (buflen < 0)
1895 goto out_free;
1896 end -= 4;
1897 memcpy(end, "/sys", 4);
1898 path = end;
1899 rc = security_genfs_sid("proc", path, tclass, sid);
1900out_free:
1901 free_page((unsigned long)buffer);
1902out:
1903 return rc;
1904}
1905
1906static int selinux_sysctl(ctl_table *table, int op)
1907{
1908 int error = 0;
1909 u32 av;
1910 u32 tsid, sid;
1911 int rc;
1912
1913 sid = current_sid();
1914
1915 rc = selinux_sysctl_get_sid(table, (op == 0001) ?
1916 SECCLASS_DIR : SECCLASS_FILE, &tsid);
1917 if (rc) {
1918 /* Default to the well-defined sysctl SID. */
1919 tsid = SECINITSID_SYSCTL;
1920 }
1921
1922 /* The op values are "defined" in sysctl.c, thereby creating
1923 * a bad coupling between this module and sysctl.c */
1924 if (op == 001) {
1925 error = avc_has_perm(sid, tsid,
1926 SECCLASS_DIR, DIR__SEARCH, NULL);
1927 } else {
1928 av = 0;
1929 if (op & 004)
1930 av |= FILE__READ;
1931 if (op & 002)
1932 av |= FILE__WRITE;
1933 if (av)
1934 error = avc_has_perm(sid, tsid,
1935 SECCLASS_FILE, av, NULL);
1936 }
1937
1938 return error;
1939}
1940
1941static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) 1886static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
1942{ 1887{
1943 const struct cred *cred = current_cred(); 1888 const struct cred *cred = current_cred();
@@ -1970,17 +1915,13 @@ static int selinux_quota_on(struct dentry *dentry)
1970{ 1915{
1971 const struct cred *cred = current_cred(); 1916 const struct cred *cred = current_cred();
1972 1917
1973 return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON); 1918 return dentry_has_perm(cred, dentry, FILE__QUOTAON);
1974} 1919}
1975 1920
1976static int selinux_syslog(int type, bool from_file) 1921static int selinux_syslog(int type)
1977{ 1922{
1978 int rc; 1923 int rc;
1979 1924
1980 rc = cap_syslog(type, from_file);
1981 if (rc)
1982 return rc;
1983
1984 switch (type) { 1925 switch (type) {
1985 case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */ 1926 case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */
1986 case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */ 1927 case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
@@ -2016,7 +1957,8 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
2016{ 1957{
2017 int rc, cap_sys_admin = 0; 1958 int rc, cap_sys_admin = 0;
2018 1959
2019 rc = selinux_capable(current, current_cred(), CAP_SYS_ADMIN, 1960 rc = selinux_capable(current, current_cred(),
1961 &init_user_ns, CAP_SYS_ADMIN,
2020 SECURITY_CAP_NOAUDIT); 1962 SECURITY_CAP_NOAUDIT);
2021 if (rc == 0) 1963 if (rc == 0)
2022 cap_sys_admin = 1; 1964 cap_sys_admin = 1;
@@ -2064,13 +2006,14 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
2064 } else { 2006 } else {
2065 /* Check for a default transition on this program. */ 2007 /* Check for a default transition on this program. */
2066 rc = security_transition_sid(old_tsec->sid, isec->sid, 2008 rc = security_transition_sid(old_tsec->sid, isec->sid,
2067 SECCLASS_PROCESS, &new_tsec->sid); 2009 SECCLASS_PROCESS, NULL,
2010 &new_tsec->sid);
2068 if (rc) 2011 if (rc)
2069 return rc; 2012 return rc;
2070 } 2013 }
2071 2014
2072 COMMON_AUDIT_DATA_INIT(&ad, FS); 2015 COMMON_AUDIT_DATA_INIT(&ad, PATH);
2073 ad.u.fs.path = bprm->file->f_path; 2016 ad.u.path = bprm->file->f_path;
2074 2017
2075 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) 2018 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
2076 new_tsec->sid = old_tsec->sid; 2019 new_tsec->sid = old_tsec->sid;
@@ -2184,8 +2127,8 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2184 struct tty_file_private, list); 2127 struct tty_file_private, list);
2185 file = file_priv->file; 2128 file = file_priv->file;
2186 inode = file->f_path.dentry->d_inode; 2129 inode = file->f_path.dentry->d_inode;
2187 if (inode_has_perm(cred, inode, 2130 if (inode_has_perm_noadp(cred, inode,
2188 FILE__READ | FILE__WRITE, NULL)) { 2131 FILE__READ | FILE__WRITE, 0)) {
2189 drop_tty = 1; 2132 drop_tty = 1;
2190 } 2133 }
2191 } 2134 }
@@ -2198,7 +2141,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2198 2141
2199 /* Revalidate access to inherited open files. */ 2142 /* Revalidate access to inherited open files. */
2200 2143
2201 COMMON_AUDIT_DATA_INIT(&ad, FS); 2144 COMMON_AUDIT_DATA_INIT(&ad, INODE);
2202 2145
2203 spin_lock(&files->file_lock); 2146 spin_lock(&files->file_lock);
2204 for (;;) { 2147 for (;;) {
@@ -2447,6 +2390,91 @@ out:
2447 return rc; 2390 return rc;
2448} 2391}
2449 2392
2393static int selinux_sb_remount(struct super_block *sb, void *data)
2394{
2395 int rc, i, *flags;
2396 struct security_mnt_opts opts;
2397 char *secdata, **mount_options;
2398 struct superblock_security_struct *sbsec = sb->s_security;
2399
2400 if (!(sbsec->flags & SE_SBINITIALIZED))
2401 return 0;
2402
2403 if (!data)
2404 return 0;
2405
2406 if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
2407 return 0;
2408
2409 security_init_mnt_opts(&opts);
2410 secdata = alloc_secdata();
2411 if (!secdata)
2412 return -ENOMEM;
2413 rc = selinux_sb_copy_data(data, secdata);
2414 if (rc)
2415 goto out_free_secdata;
2416
2417 rc = selinux_parse_opts_str(secdata, &opts);
2418 if (rc)
2419 goto out_free_secdata;
2420
2421 mount_options = opts.mnt_opts;
2422 flags = opts.mnt_opts_flags;
2423
2424 for (i = 0; i < opts.num_mnt_opts; i++) {
2425 u32 sid;
2426 size_t len;
2427
2428 if (flags[i] == SE_SBLABELSUPP)
2429 continue;
2430 len = strlen(mount_options[i]);
2431 rc = security_context_to_sid(mount_options[i], len, &sid);
2432 if (rc) {
2433 printk(KERN_WARNING "SELinux: security_context_to_sid"
2434 "(%s) failed for (dev %s, type %s) errno=%d\n",
2435 mount_options[i], sb->s_id, sb->s_type->name, rc);
2436 goto out_free_opts;
2437 }
2438 rc = -EINVAL;
2439 switch (flags[i]) {
2440 case FSCONTEXT_MNT:
2441 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
2442 goto out_bad_option;
2443 break;
2444 case CONTEXT_MNT:
2445 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
2446 goto out_bad_option;
2447 break;
2448 case ROOTCONTEXT_MNT: {
2449 struct inode_security_struct *root_isec;
2450 root_isec = sb->s_root->d_inode->i_security;
2451
2452 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
2453 goto out_bad_option;
2454 break;
2455 }
2456 case DEFCONTEXT_MNT:
2457 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
2458 goto out_bad_option;
2459 break;
2460 default:
2461 goto out_free_opts;
2462 }
2463 }
2464
2465 rc = 0;
2466out_free_opts:
2467 security_free_mnt_opts(&opts);
2468out_free_secdata:
2469 free_secdata(secdata);
2470 return rc;
2471out_bad_option:
2472 printk(KERN_WARNING "SELinux: unable to change security options "
2473 "during remount (dev %s, type=%s)\n", sb->s_id,
2474 sb->s_type->name);
2475 goto out_free_opts;
2476}
2477
2450static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) 2478static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
2451{ 2479{
2452 const struct cred *cred = current_cred(); 2480 const struct cred *cred = current_cred();
@@ -2461,8 +2489,8 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
2461 if (flags & MS_KERNMOUNT) 2489 if (flags & MS_KERNMOUNT)
2462 return 0; 2490 return 0;
2463 2491
2464 COMMON_AUDIT_DATA_INIT(&ad, FS); 2492 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2465 ad.u.fs.path.dentry = sb->s_root; 2493 ad.u.dentry = sb->s_root;
2466 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); 2494 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
2467} 2495}
2468 2496
@@ -2471,8 +2499,8 @@ static int selinux_sb_statfs(struct dentry *dentry)
2471 const struct cred *cred = current_cred(); 2499 const struct cred *cred = current_cred();
2472 struct common_audit_data ad; 2500 struct common_audit_data ad;
2473 2501
2474 COMMON_AUDIT_DATA_INIT(&ad, FS); 2502 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2475 ad.u.fs.path.dentry = dentry->d_sb->s_root; 2503 ad.u.dentry = dentry->d_sb->s_root;
2476 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); 2504 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
2477} 2505}
2478 2506
@@ -2488,8 +2516,7 @@ static int selinux_mount(char *dev_name,
2488 return superblock_has_perm(cred, path->mnt->mnt_sb, 2516 return superblock_has_perm(cred, path->mnt->mnt_sb,
2489 FILESYSTEM__REMOUNT, NULL); 2517 FILESYSTEM__REMOUNT, NULL);
2490 else 2518 else
2491 return dentry_has_perm(cred, path->mnt, path->dentry, 2519 return path_has_perm(cred, path, FILE__MOUNTON);
2492 FILE__MOUNTON);
2493} 2520}
2494 2521
2495static int selinux_umount(struct vfsmount *mnt, int flags) 2522static int selinux_umount(struct vfsmount *mnt, int flags)
@@ -2513,8 +2540,8 @@ static void selinux_inode_free_security(struct inode *inode)
2513} 2540}
2514 2541
2515static int selinux_inode_init_security(struct inode *inode, struct inode *dir, 2542static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2516 char **name, void **value, 2543 const struct qstr *qstr, char **name,
2517 size_t *len) 2544 void **value, size_t *len)
2518{ 2545{
2519 const struct task_security_struct *tsec = current_security(); 2546 const struct task_security_struct *tsec = current_security();
2520 struct inode_security_struct *dsec; 2547 struct inode_security_struct *dsec;
@@ -2529,10 +2556,13 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2529 sid = tsec->sid; 2556 sid = tsec->sid;
2530 newsid = tsec->create_sid; 2557 newsid = tsec->create_sid;
2531 2558
2532 if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) { 2559 if ((sbsec->flags & SE_SBINITIALIZED) &&
2560 (sbsec->behavior == SECURITY_FS_USE_MNTPOINT))
2561 newsid = sbsec->mntpoint_sid;
2562 else if (!newsid || !(sbsec->flags & SE_SBLABELSUPP)) {
2533 rc = security_transition_sid(sid, dsec->sid, 2563 rc = security_transition_sid(sid, dsec->sid,
2534 inode_mode_to_security_class(inode->i_mode), 2564 inode_mode_to_security_class(inode->i_mode),
2535 &newsid); 2565 qstr, &newsid);
2536 if (rc) { 2566 if (rc) {
2537 printk(KERN_WARNING "%s: " 2567 printk(KERN_WARNING "%s: "
2538 "security_transition_sid failed, rc=%d (dev=%s " 2568 "security_transition_sid failed, rc=%d (dev=%s "
@@ -2619,17 +2649,17 @@ static int selinux_inode_readlink(struct dentry *dentry)
2619{ 2649{
2620 const struct cred *cred = current_cred(); 2650 const struct cred *cred = current_cred();
2621 2651
2622 return dentry_has_perm(cred, NULL, dentry, FILE__READ); 2652 return dentry_has_perm(cred, dentry, FILE__READ);
2623} 2653}
2624 2654
2625static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata) 2655static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
2626{ 2656{
2627 const struct cred *cred = current_cred(); 2657 const struct cred *cred = current_cred();
2628 2658
2629 return dentry_has_perm(cred, NULL, dentry, FILE__READ); 2659 return dentry_has_perm(cred, dentry, FILE__READ);
2630} 2660}
2631 2661
2632static int selinux_inode_permission(struct inode *inode, int mask) 2662static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags)
2633{ 2663{
2634 const struct cred *cred = current_cred(); 2664 const struct cred *cred = current_cred();
2635 struct common_audit_data ad; 2665 struct common_audit_data ad;
@@ -2643,15 +2673,15 @@ static int selinux_inode_permission(struct inode *inode, int mask)
2643 if (!mask) 2673 if (!mask)
2644 return 0; 2674 return 0;
2645 2675
2646 COMMON_AUDIT_DATA_INIT(&ad, FS); 2676 COMMON_AUDIT_DATA_INIT(&ad, INODE);
2647 ad.u.fs.inode = inode; 2677 ad.u.inode = inode;
2648 2678
2649 if (from_access) 2679 if (from_access)
2650 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS; 2680 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS;
2651 2681
2652 perms = file_mask_to_av(inode->i_mode, mask); 2682 perms = file_mask_to_av(inode->i_mode, mask);
2653 2683
2654 return inode_has_perm(cred, inode, perms, &ad); 2684 return inode_has_perm(cred, inode, perms, &ad, flags);
2655} 2685}
2656 2686
2657static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) 2687static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
@@ -2669,16 +2699,20 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
2669 2699
2670 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | 2700 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
2671 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) 2701 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
2672 return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); 2702 return dentry_has_perm(cred, dentry, FILE__SETATTR);
2673 2703
2674 return dentry_has_perm(cred, NULL, dentry, FILE__WRITE); 2704 return dentry_has_perm(cred, dentry, FILE__WRITE);
2675} 2705}
2676 2706
2677static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) 2707static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
2678{ 2708{
2679 const struct cred *cred = current_cred(); 2709 const struct cred *cred = current_cred();
2710 struct path path;
2711
2712 path.dentry = dentry;
2713 path.mnt = mnt;
2680 2714
2681 return dentry_has_perm(cred, mnt, dentry, FILE__GETATTR); 2715 return path_has_perm(cred, &path, FILE__GETATTR);
2682} 2716}
2683 2717
2684static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) 2718static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
@@ -2699,7 +2733,7 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
2699 2733
2700 /* Not an attribute we recognize, so just check the 2734 /* Not an attribute we recognize, so just check the
2701 ordinary setattr permission. */ 2735 ordinary setattr permission. */
2702 return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); 2736 return dentry_has_perm(cred, dentry, FILE__SETATTR);
2703} 2737}
2704 2738
2705static int selinux_inode_setxattr(struct dentry *dentry, const char *name, 2739static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
@@ -2719,11 +2753,11 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2719 if (!(sbsec->flags & SE_SBLABELSUPP)) 2753 if (!(sbsec->flags & SE_SBLABELSUPP))
2720 return -EOPNOTSUPP; 2754 return -EOPNOTSUPP;
2721 2755
2722 if (!is_owner_or_cap(inode)) 2756 if (!inode_owner_or_capable(inode))
2723 return -EPERM; 2757 return -EPERM;
2724 2758
2725 COMMON_AUDIT_DATA_INIT(&ad, FS); 2759 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2726 ad.u.fs.path.dentry = dentry; 2760 ad.u.dentry = dentry;
2727 2761
2728 rc = avc_has_perm(sid, isec->sid, isec->sclass, 2762 rc = avc_has_perm(sid, isec->sid, isec->sclass,
2729 FILE__RELABELFROM, &ad); 2763 FILE__RELABELFROM, &ad);
@@ -2786,14 +2820,14 @@ static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
2786{ 2820{
2787 const struct cred *cred = current_cred(); 2821 const struct cred *cred = current_cred();
2788 2822
2789 return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); 2823 return dentry_has_perm(cred, dentry, FILE__GETATTR);
2790} 2824}
2791 2825
2792static int selinux_inode_listxattr(struct dentry *dentry) 2826static int selinux_inode_listxattr(struct dentry *dentry)
2793{ 2827{
2794 const struct cred *cred = current_cred(); 2828 const struct cred *cred = current_cred();
2795 2829
2796 return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); 2830 return dentry_has_perm(cred, dentry, FILE__GETATTR);
2797} 2831}
2798 2832
2799static int selinux_inode_removexattr(struct dentry *dentry, const char *name) 2833static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
@@ -2830,7 +2864,8 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name
2830 * and lack of permission just means that we fall back to the 2864 * and lack of permission just means that we fall back to the
2831 * in-core context value, not a denial. 2865 * in-core context value, not a denial.
2832 */ 2866 */
2833 error = selinux_capable(current, current_cred(), CAP_MAC_ADMIN, 2867 error = selinux_capable(current, current_cred(),
2868 &init_user_ns, CAP_MAC_ADMIN,
2834 SECURITY_CAP_NOAUDIT); 2869 SECURITY_CAP_NOAUDIT);
2835 if (!error) 2870 if (!error)
2836 error = security_sid_to_context_force(isec->sid, &context, 2871 error = security_sid_to_context_force(isec->sid, &context,
@@ -2933,16 +2968,47 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
2933 unsigned long arg) 2968 unsigned long arg)
2934{ 2969{
2935 const struct cred *cred = current_cred(); 2970 const struct cred *cred = current_cred();
2936 u32 av = 0; 2971 int error = 0;
2937 2972
2938 if (_IOC_DIR(cmd) & _IOC_WRITE) 2973 switch (cmd) {
2939 av |= FILE__WRITE; 2974 case FIONREAD:
2940 if (_IOC_DIR(cmd) & _IOC_READ) 2975 /* fall through */
2941 av |= FILE__READ; 2976 case FIBMAP:
2942 if (!av) 2977 /* fall through */
2943 av = FILE__IOCTL; 2978 case FIGETBSZ:
2979 /* fall through */
2980 case EXT2_IOC_GETFLAGS:
2981 /* fall through */
2982 case EXT2_IOC_GETVERSION:
2983 error = file_has_perm(cred, file, FILE__GETATTR);
2984 break;
2944 2985
2945 return file_has_perm(cred, file, av); 2986 case EXT2_IOC_SETFLAGS:
2987 /* fall through */
2988 case EXT2_IOC_SETVERSION:
2989 error = file_has_perm(cred, file, FILE__SETATTR);
2990 break;
2991
2992 /* sys_ioctl() checks */
2993 case FIONBIO:
2994 /* fall through */
2995 case FIOASYNC:
2996 error = file_has_perm(cred, file, 0);
2997 break;
2998
2999 case KDSKBENT:
3000 case KDSKBSENT:
3001 error = task_has_capability(current, cred, CAP_SYS_TTY_CONFIG,
3002 SECURITY_CAP_AUDIT);
3003 break;
3004
3005 /* default case assumes that the command will go
3006 * to the file's ioctl() function.
3007 */
3008 default:
3009 error = file_has_perm(cred, file, FILE__IOCTL);
3010 }
3011 return error;
2946} 3012}
2947 3013
2948static int default_noexec; 3014static int default_noexec;
@@ -3167,7 +3233,7 @@ static int selinux_dentry_open(struct file *file, const struct cred *cred)
3167 * new inode label or new policy. 3233 * new inode label or new policy.
3168 * This check is not redundant - do not remove. 3234 * This check is not redundant - do not remove.
3169 */ 3235 */
3170 return inode_has_perm(cred, inode, open_file_to_av(file), NULL); 3236 return inode_has_perm_noadp(cred, inode, open_file_to_av(file), 0);
3171} 3237}
3172 3238
3173/* task security operations */ 3239/* task security operations */
@@ -3199,7 +3265,11 @@ static void selinux_cred_free(struct cred *cred)
3199{ 3265{
3200 struct task_security_struct *tsec = cred->security; 3266 struct task_security_struct *tsec = cred->security;
3201 3267
3202 BUG_ON((unsigned long) cred->security < PAGE_SIZE); 3268 /*
3269 * cred->security == NULL if security_cred_alloc_blank() or
3270 * security_prepare_creds() returned an error.
3271 */
3272 BUG_ON(cred->security && (unsigned long) cred->security < PAGE_SIZE);
3203 cred->security = (void *) 0x7UL; 3273 cred->security = (void *) 0x7UL;
3204 kfree(tsec); 3274 kfree(tsec);
3205} 3275}
@@ -3354,11 +3424,11 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
3354 return 0; 3424 return 0;
3355} 3425}
3356 3426
3357static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp) 3427static int selinux_task_setscheduler(struct task_struct *p)
3358{ 3428{
3359 int rc; 3429 int rc;
3360 3430
3361 rc = cap_task_setscheduler(p, policy, lp); 3431 rc = cap_task_setscheduler(p);
3362 if (rc) 3432 if (rc)
3363 return rc; 3433 return rc;
3364 3434
@@ -3641,9 +3711,16 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
3641 3711
3642/* socket security operations */ 3712/* socket security operations */
3643 3713
3644static u32 socket_sockcreate_sid(const struct task_security_struct *tsec) 3714static int socket_sockcreate_sid(const struct task_security_struct *tsec,
3715 u16 secclass, u32 *socksid)
3645{ 3716{
3646 return tsec->sockcreate_sid ? : tsec->sid; 3717 if (tsec->sockcreate_sid > SECSID_NULL) {
3718 *socksid = tsec->sockcreate_sid;
3719 return 0;
3720 }
3721
3722 return security_transition_sid(tsec->sid, tsec->sid, secclass, NULL,
3723 socksid);
3647} 3724}
3648 3725
3649static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms) 3726static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms)
@@ -3667,12 +3744,16 @@ static int selinux_socket_create(int family, int type,
3667 const struct task_security_struct *tsec = current_security(); 3744 const struct task_security_struct *tsec = current_security();
3668 u32 newsid; 3745 u32 newsid;
3669 u16 secclass; 3746 u16 secclass;
3747 int rc;
3670 3748
3671 if (kern) 3749 if (kern)
3672 return 0; 3750 return 0;
3673 3751
3674 newsid = socket_sockcreate_sid(tsec);
3675 secclass = socket_type_to_security_class(family, type, protocol); 3752 secclass = socket_type_to_security_class(family, type, protocol);
3753 rc = socket_sockcreate_sid(tsec, secclass, &newsid);
3754 if (rc)
3755 return rc;
3756
3676 return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL); 3757 return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
3677} 3758}
3678 3759
@@ -3684,12 +3765,16 @@ static int selinux_socket_post_create(struct socket *sock, int family,
3684 struct sk_security_struct *sksec; 3765 struct sk_security_struct *sksec;
3685 int err = 0; 3766 int err = 0;
3686 3767
3768 isec->sclass = socket_type_to_security_class(family, type, protocol);
3769
3687 if (kern) 3770 if (kern)
3688 isec->sid = SECINITSID_KERNEL; 3771 isec->sid = SECINITSID_KERNEL;
3689 else 3772 else {
3690 isec->sid = socket_sockcreate_sid(tsec); 3773 err = socket_sockcreate_sid(tsec, isec->sclass, &(isec->sid));
3774 if (err)
3775 return err;
3776 }
3691 3777
3692 isec->sclass = socket_type_to_security_class(family, type, protocol);
3693 isec->initialized = 1; 3778 isec->initialized = 1;
3694 3779
3695 if (sock->sk) { 3780 if (sock->sk) {
@@ -3925,18 +4010,18 @@ static int selinux_socket_shutdown(struct socket *sock, int how)
3925 return sock_has_perm(current, sock->sk, SOCKET__SHUTDOWN); 4010 return sock_has_perm(current, sock->sk, SOCKET__SHUTDOWN);
3926} 4011}
3927 4012
3928static int selinux_socket_unix_stream_connect(struct socket *sock, 4013static int selinux_socket_unix_stream_connect(struct sock *sock,
3929 struct socket *other, 4014 struct sock *other,
3930 struct sock *newsk) 4015 struct sock *newsk)
3931{ 4016{
3932 struct sk_security_struct *sksec_sock = sock->sk->sk_security; 4017 struct sk_security_struct *sksec_sock = sock->sk_security;
3933 struct sk_security_struct *sksec_other = other->sk->sk_security; 4018 struct sk_security_struct *sksec_other = other->sk_security;
3934 struct sk_security_struct *sksec_new = newsk->sk_security; 4019 struct sk_security_struct *sksec_new = newsk->sk_security;
3935 struct common_audit_data ad; 4020 struct common_audit_data ad;
3936 int err; 4021 int err;
3937 4022
3938 COMMON_AUDIT_DATA_INIT(&ad, NET); 4023 COMMON_AUDIT_DATA_INIT(&ad, NET);
3939 ad.u.net.sk = other->sk; 4024 ad.u.net.sk = other;
3940 4025
3941 err = avc_has_perm(sksec_sock->sid, sksec_other->sid, 4026 err = avc_has_perm(sksec_sock->sid, sksec_other->sid,
3942 sksec_other->sclass, 4027 sksec_other->sclass,
@@ -3999,7 +4084,6 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
3999{ 4084{
4000 int err = 0; 4085 int err = 0;
4001 struct sk_security_struct *sksec = sk->sk_security; 4086 struct sk_security_struct *sksec = sk->sk_security;
4002 u32 peer_sid;
4003 u32 sk_sid = sksec->sid; 4087 u32 sk_sid = sksec->sid;
4004 struct common_audit_data ad; 4088 struct common_audit_data ad;
4005 char *addrp; 4089 char *addrp;
@@ -4018,20 +4102,10 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
4018 return err; 4102 return err;
4019 } 4103 }
4020 4104
4021 if (selinux_policycap_netpeer) { 4105 err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
4022 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid); 4106 if (err)
4023 if (err) 4107 return err;
4024 return err; 4108 err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
4025 err = avc_has_perm(sk_sid, peer_sid,
4026 SECCLASS_PEER, PEER__RECV, &ad);
4027 if (err)
4028 selinux_netlbl_err(skb, err, 0);
4029 } else {
4030 err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
4031 if (err)
4032 return err;
4033 err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
4034 }
4035 4109
4036 return err; 4110 return err;
4037} 4111}
@@ -4279,10 +4353,31 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
4279 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid); 4353 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
4280} 4354}
4281 4355
4356static int selinux_secmark_relabel_packet(u32 sid)
4357{
4358 const struct task_security_struct *__tsec;
4359 u32 tsid;
4360
4361 __tsec = current_security();
4362 tsid = __tsec->sid;
4363
4364 return avc_has_perm(tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO, NULL);
4365}
4366
4367static void selinux_secmark_refcount_inc(void)
4368{
4369 atomic_inc(&selinux_secmark_refcount);
4370}
4371
4372static void selinux_secmark_refcount_dec(void)
4373{
4374 atomic_dec(&selinux_secmark_refcount);
4375}
4376
4282static void selinux_req_classify_flow(const struct request_sock *req, 4377static void selinux_req_classify_flow(const struct request_sock *req,
4283 struct flowi *fl) 4378 struct flowi *fl)
4284{ 4379{
4285 fl->secid = req->secid; 4380 fl->flowi_secid = req->secid;
4286} 4381}
4287 4382
4288static int selinux_tun_dev_create(void) 4383static int selinux_tun_dev_create(void)
@@ -4503,11 +4598,10 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb,
4503 if (selinux_secmark_enabled()) 4598 if (selinux_secmark_enabled())
4504 if (avc_has_perm(sksec->sid, skb->secmark, 4599 if (avc_has_perm(sksec->sid, skb->secmark,
4505 SECCLASS_PACKET, PACKET__SEND, &ad)) 4600 SECCLASS_PACKET, PACKET__SEND, &ad))
4506 return NF_DROP; 4601 return NF_DROP_ERR(-ECONNREFUSED);
4507 4602
4508 if (selinux_policycap_netpeer) 4603 if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto))
4509 if (selinux_xfrm_postroute_last(sksec->sid, skb, &ad, proto)) 4604 return NF_DROP_ERR(-ECONNREFUSED);
4510 return NF_DROP;
4511 4605
4512 return NF_ACCEPT; 4606 return NF_ACCEPT;
4513} 4607}
@@ -4550,27 +4644,14 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4550 * from the sending socket, otherwise use the kernel's sid */ 4644 * from the sending socket, otherwise use the kernel's sid */
4551 sk = skb->sk; 4645 sk = skb->sk;
4552 if (sk == NULL) { 4646 if (sk == NULL) {
4553 switch (family) { 4647 if (skb->skb_iif) {
4554 case PF_INET: 4648 secmark_perm = PACKET__FORWARD_OUT;
4555 if (IPCB(skb)->flags & IPSKB_FORWARDED)
4556 secmark_perm = PACKET__FORWARD_OUT;
4557 else
4558 secmark_perm = PACKET__SEND;
4559 break;
4560 case PF_INET6:
4561 if (IP6CB(skb)->flags & IP6SKB_FORWARDED)
4562 secmark_perm = PACKET__FORWARD_OUT;
4563 else
4564 secmark_perm = PACKET__SEND;
4565 break;
4566 default:
4567 return NF_DROP;
4568 }
4569 if (secmark_perm == PACKET__FORWARD_OUT) {
4570 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid)) 4649 if (selinux_skb_peerlbl_sid(skb, family, &peer_sid))
4571 return NF_DROP; 4650 return NF_DROP;
4572 } else 4651 } else {
4652 secmark_perm = PACKET__SEND;
4573 peer_sid = SECINITSID_KERNEL; 4653 peer_sid = SECINITSID_KERNEL;
4654 }
4574 } else { 4655 } else {
4575 struct sk_security_struct *sksec = sk->sk_security; 4656 struct sk_security_struct *sksec = sk->sk_security;
4576 peer_sid = sksec->sid; 4657 peer_sid = sksec->sid;
@@ -4586,7 +4667,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4586 if (secmark_active) 4667 if (secmark_active)
4587 if (avc_has_perm(peer_sid, skb->secmark, 4668 if (avc_has_perm(peer_sid, skb->secmark,
4588 SECCLASS_PACKET, secmark_perm, &ad)) 4669 SECCLASS_PACKET, secmark_perm, &ad))
4589 return NF_DROP; 4670 return NF_DROP_ERR(-ECONNREFUSED);
4590 4671
4591 if (peerlbl_active) { 4672 if (peerlbl_active) {
4592 u32 if_sid; 4673 u32 if_sid;
@@ -4596,13 +4677,13 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4596 return NF_DROP; 4677 return NF_DROP;
4597 if (avc_has_perm(peer_sid, if_sid, 4678 if (avc_has_perm(peer_sid, if_sid,
4598 SECCLASS_NETIF, NETIF__EGRESS, &ad)) 4679 SECCLASS_NETIF, NETIF__EGRESS, &ad))
4599 return NF_DROP; 4680 return NF_DROP_ERR(-ECONNREFUSED);
4600 4681
4601 if (sel_netnode_sid(addrp, family, &node_sid)) 4682 if (sel_netnode_sid(addrp, family, &node_sid))
4602 return NF_DROP; 4683 return NF_DROP;
4603 if (avc_has_perm(peer_sid, node_sid, 4684 if (avc_has_perm(peer_sid, node_sid,
4604 SECCLASS_NODE, NODE__SENDTO, &ad)) 4685 SECCLASS_NODE, NODE__SENDTO, &ad))
4605 return NF_DROP; 4686 return NF_DROP_ERR(-ECONNREFUSED);
4606 } 4687 }
4607 4688
4608 return NF_ACCEPT; 4689 return NF_ACCEPT;
@@ -4645,6 +4726,7 @@ static int selinux_netlink_recv(struct sk_buff *skb, int capability)
4645{ 4726{
4646 int err; 4727 int err;
4647 struct common_audit_data ad; 4728 struct common_audit_data ad;
4729 u32 sid;
4648 4730
4649 err = cap_netlink_recv(skb, capability); 4731 err = cap_netlink_recv(skb, capability);
4650 if (err) 4732 if (err)
@@ -4653,8 +4735,9 @@ static int selinux_netlink_recv(struct sk_buff *skb, int capability)
4653 COMMON_AUDIT_DATA_INIT(&ad, CAP); 4735 COMMON_AUDIT_DATA_INIT(&ad, CAP);
4654 ad.u.cap = capability; 4736 ad.u.cap = capability;
4655 4737
4656 return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid, 4738 security_task_getsecid(current, &sid);
4657 SECCLASS_CAPABILITY, CAP_TO_MASK(capability), &ad); 4739 return avc_has_perm(sid, sid, SECCLASS_CAPABILITY,
4740 CAP_TO_MASK(capability), &ad);
4658} 4741}
4659 4742
4660static int ipc_alloc_security(struct task_struct *task, 4743static int ipc_alloc_security(struct task_struct *task,
@@ -4824,7 +4907,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
4824 * message queue this message will be stored in 4907 * message queue this message will be stored in
4825 */ 4908 */
4826 rc = security_transition_sid(sid, isec->sid, SECCLASS_MSG, 4909 rc = security_transition_sid(sid, isec->sid, SECCLASS_MSG,
4827 &msec->sid); 4910 NULL, &msec->sid);
4828 if (rc) 4911 if (rc)
4829 return rc; 4912 return rc;
4830 } 4913 }
@@ -5378,7 +5461,6 @@ static struct security_operations selinux_ops = {
5378 .ptrace_traceme = selinux_ptrace_traceme, 5461 .ptrace_traceme = selinux_ptrace_traceme,
5379 .capget = selinux_capget, 5462 .capget = selinux_capget,
5380 .capset = selinux_capset, 5463 .capset = selinux_capset,
5381 .sysctl = selinux_sysctl,
5382 .capable = selinux_capable, 5464 .capable = selinux_capable,
5383 .quotactl = selinux_quotactl, 5465 .quotactl = selinux_quotactl,
5384 .quota_on = selinux_quota_on, 5466 .quota_on = selinux_quota_on,
@@ -5396,6 +5478,7 @@ static struct security_operations selinux_ops = {
5396 .sb_alloc_security = selinux_sb_alloc_security, 5478 .sb_alloc_security = selinux_sb_alloc_security,
5397 .sb_free_security = selinux_sb_free_security, 5479 .sb_free_security = selinux_sb_free_security,
5398 .sb_copy_data = selinux_sb_copy_data, 5480 .sb_copy_data = selinux_sb_copy_data,
5481 .sb_remount = selinux_sb_remount,
5399 .sb_kern_mount = selinux_sb_kern_mount, 5482 .sb_kern_mount = selinux_sb_kern_mount,
5400 .sb_show_options = selinux_sb_show_options, 5483 .sb_show_options = selinux_sb_show_options,
5401 .sb_statfs = selinux_sb_statfs, 5484 .sb_statfs = selinux_sb_statfs,
@@ -5533,6 +5616,9 @@ static struct security_operations selinux_ops = {
5533 .inet_conn_request = selinux_inet_conn_request, 5616 .inet_conn_request = selinux_inet_conn_request,
5534 .inet_csk_clone = selinux_inet_csk_clone, 5617 .inet_csk_clone = selinux_inet_csk_clone,
5535 .inet_conn_established = selinux_inet_conn_established, 5618 .inet_conn_established = selinux_inet_conn_established,
5619 .secmark_relabel_packet = selinux_secmark_relabel_packet,
5620 .secmark_refcount_inc = selinux_secmark_refcount_inc,
5621 .secmark_refcount_dec = selinux_secmark_refcount_dec,
5536 .req_classify_flow = selinux_req_classify_flow, 5622 .req_classify_flow = selinux_req_classify_flow,
5537 .tun_dev_create = selinux_tun_dev_create, 5623 .tun_dev_create = selinux_tun_dev_create,
5538 .tun_dev_post_create = selinux_tun_dev_post_create, 5624 .tun_dev_post_create = selinux_tun_dev_post_create,
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h
index e94e82f73818..47fda963495d 100644
--- a/security/selinux/include/avc.h
+++ b/security/selinux/include/avc.h
@@ -15,7 +15,6 @@
15#include <linux/audit.h> 15#include <linux/audit.h>
16#include <linux/lsm_audit.h> 16#include <linux/lsm_audit.h>
17#include <linux/in6.h> 17#include <linux/in6.h>
18#include <linux/path.h>
19#include <asm/system.h> 18#include <asm/system.h>
20#include "flask.h" 19#include "flask.h"
21#include "av_permissions.h" 20#include "av_permissions.h"
@@ -42,7 +41,6 @@ struct sk_buff;
42 */ 41 */
43struct avc_cache_stats { 42struct avc_cache_stats {
44 unsigned int lookups; 43 unsigned int lookups;
45 unsigned int hits;
46 unsigned int misses; 44 unsigned int misses;
47 unsigned int allocations; 45 unsigned int allocations;
48 unsigned int reclaims; 46 unsigned int reclaims;
@@ -55,11 +53,11 @@ struct avc_cache_stats {
55 53
56void __init avc_init(void); 54void __init avc_init(void);
57 55
58void avc_audit(u32 ssid, u32 tsid, 56int avc_audit(u32 ssid, u32 tsid,
59 u16 tclass, u32 requested, 57 u16 tclass, u32 requested,
60 struct av_decision *avd, 58 struct av_decision *avd,
61 int result, 59 int result,
62 struct common_audit_data *a); 60 struct common_audit_data *a, unsigned flags);
63 61
64#define AVC_STRICT 1 /* Ignore permissive mode. */ 62#define AVC_STRICT 1 /* Ignore permissive mode. */
65int avc_has_perm_noaudit(u32 ssid, u32 tsid, 63int avc_has_perm_noaudit(u32 ssid, u32 tsid,
@@ -67,9 +65,17 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
67 unsigned flags, 65 unsigned flags,
68 struct av_decision *avd); 66 struct av_decision *avd);
69 67
70int avc_has_perm(u32 ssid, u32 tsid, 68int avc_has_perm_flags(u32 ssid, u32 tsid,
71 u16 tclass, u32 requested, 69 u16 tclass, u32 requested,
72 struct common_audit_data *auditdata); 70 struct common_audit_data *auditdata,
71 unsigned);
72
73static inline int avc_has_perm(u32 ssid, u32 tsid,
74 u16 tclass, u32 requested,
75 struct common_audit_data *auditdata)
76{
77 return avc_has_perm_flags(ssid, tsid, tclass, requested, auditdata, 0);
78}
73 79
74u32 avc_policy_seqno(void); 80u32 avc_policy_seqno(void);
75 81
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index b4c9eb4bd6f9..b8c53723e09b 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -12,12 +12,16 @@
12#define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \ 12#define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \
13 "write", "associate", "unix_read", "unix_write" 13 "write", "associate", "unix_read", "unix_write"
14 14
15/*
16 * Note: The name for any socket class should be suffixed by "socket",
17 * and doesn't contain more than one substr of "socket".
18 */
15struct security_class_mapping secclass_map[] = { 19struct security_class_mapping secclass_map[] = {
16 { "security", 20 { "security",
17 { "compute_av", "compute_create", "compute_member", 21 { "compute_av", "compute_create", "compute_member",
18 "check_context", "load_policy", "compute_relabel", 22 "check_context", "load_policy", "compute_relabel",
19 "compute_user", "setenforce", "setbool", "setsecparam", 23 "compute_user", "setenforce", "setbool", "setsecparam",
20 "setcheckreqprot", NULL } }, 24 "setcheckreqprot", "read_policy", NULL } },
21 { "process", 25 { "process",
22 { "fork", "transition", "sigchld", "sigkill", 26 { "fork", "transition", "sigchld", "sigkill",
23 "sigstop", "signull", "signal", "ptrace", "getsched", "setsched", 27 "sigstop", "signull", "signal", "ptrace", "getsched", "setsched",
@@ -132,8 +136,7 @@ struct security_class_mapping secclass_map[] = {
132 { "appletalk_socket", 136 { "appletalk_socket",
133 { COMMON_SOCK_PERMS, NULL } }, 137 { COMMON_SOCK_PERMS, NULL } },
134 { "packet", 138 { "packet",
135 { "send", "recv", "relabelto", "flow_in", "flow_out", 139 { "send", "recv", "relabelto", "forward_in", "forward_out", NULL } },
136 "forward_in", "forward_out", NULL } },
137 { "key", 140 { "key",
138 { "view", "read", "write", "search", "link", "setattr", "create", 141 { "view", "read", "write", "search", "link", "setattr", "create",
139 NULL } }, 142 NULL } },
@@ -142,7 +145,7 @@ struct security_class_mapping secclass_map[] = {
142 "node_bind", "name_connect", NULL } }, 145 "node_bind", "name_connect", NULL } },
143 { "memprotect", { "mmap_zero", NULL } }, 146 { "memprotect", { "mmap_zero", NULL } },
144 { "peer", { "recv", NULL } }, 147 { "peer", { "recv", NULL } },
145 { "capability2", { "mac_override", "mac_admin", NULL } }, 148 { "capability2", { "mac_override", "mac_admin", "syslog", NULL } },
146 { "kernel_service", { "use_as_override", "create_files_as", NULL } }, 149 { "kernel_service", { "use_as_override", "create_files_as", NULL } },
147 { "tun_socket", 150 { "tun_socket",
148 { COMMON_SOCK_PERMS, NULL } }, 151 { COMMON_SOCK_PERMS, NULL } },
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 1f7c2491d3dc..3ba4feba048a 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -8,7 +8,9 @@
8#ifndef _SELINUX_SECURITY_H_ 8#ifndef _SELINUX_SECURITY_H_
9#define _SELINUX_SECURITY_H_ 9#define _SELINUX_SECURITY_H_
10 10
11#include <linux/dcache.h>
11#include <linux/magic.h> 12#include <linux/magic.h>
13#include <linux/types.h>
12#include "flask.h" 14#include "flask.h"
13 15
14#define SECSID_NULL 0x00000000 /* unspecified SID */ 16#define SECSID_NULL 0x00000000 /* unspecified SID */
@@ -27,13 +29,15 @@
27#define POLICYDB_VERSION_POLCAP 22 29#define POLICYDB_VERSION_POLCAP 22
28#define POLICYDB_VERSION_PERMISSIVE 23 30#define POLICYDB_VERSION_PERMISSIVE 23
29#define POLICYDB_VERSION_BOUNDARY 24 31#define POLICYDB_VERSION_BOUNDARY 24
32#define POLICYDB_VERSION_FILENAME_TRANS 25
33#define POLICYDB_VERSION_ROLETRANS 26
30 34
31/* Range of policy versions we understand*/ 35/* Range of policy versions we understand*/
32#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE 36#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
33#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX 37#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
34#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE 38#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
35#else 39#else
36#define POLICYDB_VERSION_MAX POLICYDB_VERSION_BOUNDARY 40#define POLICYDB_VERSION_MAX POLICYDB_VERSION_ROLETRANS
37#endif 41#endif
38 42
39/* Mask for just the mount related flags */ 43/* Mask for just the mount related flags */
@@ -82,6 +86,8 @@ extern int selinux_policycap_openperm;
82int security_mls_enabled(void); 86int security_mls_enabled(void);
83 87
84int security_load_policy(void *data, size_t len); 88int security_load_policy(void *data, size_t len);
89int security_read_policy(void **data, size_t *len);
90size_t security_policydb_len(void);
85 91
86int security_policycap_supported(unsigned int req_cap); 92int security_policycap_supported(unsigned int req_cap);
87 93
@@ -103,11 +109,11 @@ void security_compute_av(u32 ssid, u32 tsid,
103void security_compute_av_user(u32 ssid, u32 tsid, 109void security_compute_av_user(u32 ssid, u32 tsid,
104 u16 tclass, struct av_decision *avd); 110 u16 tclass, struct av_decision *avd);
105 111
106int security_transition_sid(u32 ssid, u32 tsid, 112int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
107 u16 tclass, u32 *out_sid); 113 const struct qstr *qstr, u32 *out_sid);
108 114
109int security_transition_sid_user(u32 ssid, u32 tsid, 115int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
110 u16 tclass, u32 *out_sid); 116 const char *objname, u32 *out_sid);
111 117
112int security_member_sid(u32 ssid, u32 tsid, 118int security_member_sid(u32 ssid, u32 tsid,
113 u16 tclass, u32 *out_sid); 119 u16 tclass, u32 *out_sid);
@@ -191,5 +197,25 @@ static inline int security_netlbl_sid_to_secattr(u32 sid,
191 197
192const char *security_get_initial_sid_context(u32 sid); 198const char *security_get_initial_sid_context(u32 sid);
193 199
200/*
201 * status notifier using mmap interface
202 */
203extern struct page *selinux_kernel_status_page(void);
204
205#define SELINUX_KERNEL_STATUS_VERSION 1
206struct selinux_kernel_status {
207 u32 version; /* version number of thie structure */
208 u32 sequence; /* sequence number of seqlock logic */
209 u32 enforcing; /* current setting of enforcing mode */
210 u32 policyload; /* times of policy reloaded */
211 u32 deny_unknown; /* current setting of deny_unknown */
212 /*
213 * The version > 0 supports above members.
214 */
215} __attribute__((packed));
216
217extern void selinux_status_update_setenforce(int enforcing);
218extern void selinux_status_update_policyload(int seqno);
219
194#endif /* _SELINUX_SECURITY_H_ */ 220#endif /* _SELINUX_SECURITY_H_ */
195 221
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 13128f9a3e5a..b43813c9e049 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -19,7 +19,7 @@ void selinux_xfrm_state_free(struct xfrm_state *x);
19int selinux_xfrm_state_delete(struct xfrm_state *x); 19int selinux_xfrm_state_delete(struct xfrm_state *x);
20int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir); 20int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);
21int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, 21int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
22 struct xfrm_policy *xp, struct flowi *fl); 22 struct xfrm_policy *xp, const struct flowi *fl);
23 23
24/* 24/*
25 * Extract the security blob from the sock (it's actually on the socket) 25 * Extract the security blob from the sock (it's actually on the socket)
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index d6095d63d831..58cc481c93d5 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -104,22 +104,6 @@ static int sel_netif_insert(struct sel_netif *netif)
104} 104}
105 105
106/** 106/**
107 * sel_netif_free - Frees an interface entry
108 * @p: the entry's RCU field
109 *
110 * Description:
111 * This function is designed to be used as a callback to the call_rcu()
112 * function so that memory allocated to a hash table interface entry can be
113 * released safely.
114 *
115 */
116static void sel_netif_free(struct rcu_head *p)
117{
118 struct sel_netif *netif = container_of(p, struct sel_netif, rcu_head);
119 kfree(netif);
120}
121
122/**
123 * sel_netif_destroy - Remove an interface record from the table 107 * sel_netif_destroy - Remove an interface record from the table
124 * @netif: the existing interface record 108 * @netif: the existing interface record
125 * 109 *
@@ -131,7 +115,7 @@ static void sel_netif_destroy(struct sel_netif *netif)
131{ 115{
132 list_del_rcu(&netif->list); 116 list_del_rcu(&netif->list);
133 sel_netif_total--; 117 sel_netif_total--;
134 call_rcu(&netif->rcu_head, sel_netif_free); 118 kfree_rcu(netif, rcu_head);
135} 119}
136 120
137/** 121/**
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index 1c2fc46544bf..c3bf3ed07b06 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -151,7 +151,7 @@ void selinux_netlbl_sk_security_free(struct sk_security_struct *sksec)
151 * 151 *
152 * Description: 152 * Description:
153 * Called when the NetLabel state of a sk_security_struct needs to be reset. 153 * Called when the NetLabel state of a sk_security_struct needs to be reset.
154 * The caller is responsibile for all the NetLabel sk_security_struct locking. 154 * The caller is responsible for all the NetLabel sk_security_struct locking.
155 * 155 *
156 */ 156 */
157void selinux_netlbl_sk_security_reset(struct sk_security_struct *sksec) 157void selinux_netlbl_sk_security_reset(struct sk_security_struct *sksec)
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index 65ebfe954f85..3618251d0fdb 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -141,6 +141,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
141 break; 141 break;
142 default: 142 default:
143 BUG(); 143 BUG();
144 return NULL;
144 } 145 }
145 146
146 list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list) 147 list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list)
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 75ec0c6ebacd..8b02b2137da2 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -65,6 +65,8 @@ static struct nlmsg_perm nlmsg_route_perms[] =
65 { RTM_NEWADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, 65 { RTM_NEWADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
66 { RTM_DELADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, 66 { RTM_DELADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
67 { RTM_GETADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_READ }, 67 { RTM_GETADDRLABEL, NETLINK_ROUTE_SOCKET__NLMSG_READ },
68 { RTM_GETDCB, NETLINK_ROUTE_SOCKET__NLMSG_READ },
69 { RTM_SETDCB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
68}; 70};
69 71
70static struct nlmsg_perm nlmsg_firewall_perms[] = 72static struct nlmsg_perm nlmsg_firewall_perms[] =
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 79a1bb635662..35459340019e 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -28,6 +28,8 @@
28#include <linux/percpu.h> 28#include <linux/percpu.h>
29#include <linux/audit.h> 29#include <linux/audit.h>
30#include <linux/uaccess.h> 30#include <linux/uaccess.h>
31#include <linux/kobject.h>
32#include <linux/ctype.h>
31 33
32/* selinuxfs pseudo filesystem for exporting the security policy API. 34/* selinuxfs pseudo filesystem for exporting the security policy API.
33 Based on the proc code and the fs/nfsd/nfsctl.c code. */ 35 Based on the proc code and the fs/nfsd/nfsctl.c code. */
@@ -68,6 +70,8 @@ static int *bool_pending_values;
68static struct dentry *class_dir; 70static struct dentry *class_dir;
69static unsigned long last_class_ino; 71static unsigned long last_class_ino;
70 72
73static char policy_opened;
74
71/* global data for policy capabilities */ 75/* global data for policy capabilities */
72static struct dentry *policycap_dir; 76static struct dentry *policycap_dir;
73 77
@@ -110,6 +114,8 @@ enum sel_inos {
110 SEL_COMPAT_NET, /* whether to use old compat network packet controls */ 114 SEL_COMPAT_NET, /* whether to use old compat network packet controls */
111 SEL_REJECT_UNKNOWN, /* export unknown reject handling to userspace */ 115 SEL_REJECT_UNKNOWN, /* export unknown reject handling to userspace */
112 SEL_DENY_UNKNOWN, /* export unknown deny handling to userspace */ 116 SEL_DENY_UNKNOWN, /* export unknown deny handling to userspace */
117 SEL_STATUS, /* export current status using mmap() */
118 SEL_POLICY, /* allow userspace to read the in kernel policy */
113 SEL_INO_NEXT, /* The next inode number to use */ 119 SEL_INO_NEXT, /* The next inode number to use */
114}; 120};
115 121
@@ -137,19 +143,24 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
137 size_t count, loff_t *ppos) 143 size_t count, loff_t *ppos)
138 144
139{ 145{
140 char *page; 146 char *page = NULL;
141 ssize_t length; 147 ssize_t length;
142 int new_value; 148 int new_value;
143 149
150 length = -ENOMEM;
144 if (count >= PAGE_SIZE) 151 if (count >= PAGE_SIZE)
145 return -ENOMEM; 152 goto out;
146 if (*ppos != 0) { 153
147 /* No partial writes. */ 154 /* No partial writes. */
148 return -EINVAL; 155 length = EINVAL;
149 } 156 if (*ppos != 0)
157 goto out;
158
159 length = -ENOMEM;
150 page = (char *)get_zeroed_page(GFP_KERNEL); 160 page = (char *)get_zeroed_page(GFP_KERNEL);
151 if (!page) 161 if (!page)
152 return -ENOMEM; 162 goto out;
163
153 length = -EFAULT; 164 length = -EFAULT;
154 if (copy_from_user(page, buf, count)) 165 if (copy_from_user(page, buf, count))
155 goto out; 166 goto out;
@@ -171,6 +182,7 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
171 if (selinux_enforcing) 182 if (selinux_enforcing)
172 avc_ss_reset(0); 183 avc_ss_reset(0);
173 selnl_notify_setenforce(selinux_enforcing); 184 selnl_notify_setenforce(selinux_enforcing);
185 selinux_status_update_setenforce(selinux_enforcing);
174 } 186 }
175 length = count; 187 length = count;
176out: 188out:
@@ -205,25 +217,83 @@ static const struct file_operations sel_handle_unknown_ops = {
205 .llseek = generic_file_llseek, 217 .llseek = generic_file_llseek,
206}; 218};
207 219
220static int sel_open_handle_status(struct inode *inode, struct file *filp)
221{
222 struct page *status = selinux_kernel_status_page();
223
224 if (!status)
225 return -ENOMEM;
226
227 filp->private_data = status;
228
229 return 0;
230}
231
232static ssize_t sel_read_handle_status(struct file *filp, char __user *buf,
233 size_t count, loff_t *ppos)
234{
235 struct page *status = filp->private_data;
236
237 BUG_ON(!status);
238
239 return simple_read_from_buffer(buf, count, ppos,
240 page_address(status),
241 sizeof(struct selinux_kernel_status));
242}
243
244static int sel_mmap_handle_status(struct file *filp,
245 struct vm_area_struct *vma)
246{
247 struct page *status = filp->private_data;
248 unsigned long size = vma->vm_end - vma->vm_start;
249
250 BUG_ON(!status);
251
252 /* only allows one page from the head */
253 if (vma->vm_pgoff > 0 || size != PAGE_SIZE)
254 return -EIO;
255 /* disallow writable mapping */
256 if (vma->vm_flags & VM_WRITE)
257 return -EPERM;
258 /* disallow mprotect() turns it into writable */
259 vma->vm_flags &= ~VM_MAYWRITE;
260
261 return remap_pfn_range(vma, vma->vm_start,
262 page_to_pfn(status),
263 size, vma->vm_page_prot);
264}
265
266static const struct file_operations sel_handle_status_ops = {
267 .open = sel_open_handle_status,
268 .read = sel_read_handle_status,
269 .mmap = sel_mmap_handle_status,
270 .llseek = generic_file_llseek,
271};
272
208#ifdef CONFIG_SECURITY_SELINUX_DISABLE 273#ifdef CONFIG_SECURITY_SELINUX_DISABLE
209static ssize_t sel_write_disable(struct file *file, const char __user *buf, 274static ssize_t sel_write_disable(struct file *file, const char __user *buf,
210 size_t count, loff_t *ppos) 275 size_t count, loff_t *ppos)
211 276
212{ 277{
213 char *page; 278 char *page = NULL;
214 ssize_t length; 279 ssize_t length;
215 int new_value; 280 int new_value;
216 extern int selinux_disable(void); 281 extern int selinux_disable(void);
217 282
283 length = -ENOMEM;
218 if (count >= PAGE_SIZE) 284 if (count >= PAGE_SIZE)
219 return -ENOMEM; 285 goto out;
220 if (*ppos != 0) { 286
221 /* No partial writes. */ 287 /* No partial writes. */
222 return -EINVAL; 288 length = -EINVAL;
223 } 289 if (*ppos != 0)
290 goto out;
291
292 length = -ENOMEM;
224 page = (char *)get_zeroed_page(GFP_KERNEL); 293 page = (char *)get_zeroed_page(GFP_KERNEL);
225 if (!page) 294 if (!page)
226 return -ENOMEM; 295 goto out;
296
227 length = -EFAULT; 297 length = -EFAULT;
228 if (copy_from_user(page, buf, count)) 298 if (copy_from_user(page, buf, count))
229 goto out; 299 goto out;
@@ -234,7 +304,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf,
234 304
235 if (new_value) { 305 if (new_value) {
236 length = selinux_disable(); 306 length = selinux_disable();
237 if (length < 0) 307 if (length)
238 goto out; 308 goto out;
239 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, 309 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
240 "selinux=0 auid=%u ses=%u", 310 "selinux=0 auid=%u ses=%u",
@@ -296,11 +366,145 @@ static const struct file_operations sel_mls_ops = {
296 .llseek = generic_file_llseek, 366 .llseek = generic_file_llseek,
297}; 367};
298 368
369struct policy_load_memory {
370 size_t len;
371 void *data;
372};
373
374static int sel_open_policy(struct inode *inode, struct file *filp)
375{
376 struct policy_load_memory *plm = NULL;
377 int rc;
378
379 BUG_ON(filp->private_data);
380
381 mutex_lock(&sel_mutex);
382
383 rc = task_has_security(current, SECURITY__READ_POLICY);
384 if (rc)
385 goto err;
386
387 rc = -EBUSY;
388 if (policy_opened)
389 goto err;
390
391 rc = -ENOMEM;
392 plm = kzalloc(sizeof(*plm), GFP_KERNEL);
393 if (!plm)
394 goto err;
395
396 if (i_size_read(inode) != security_policydb_len()) {
397 mutex_lock(&inode->i_mutex);
398 i_size_write(inode, security_policydb_len());
399 mutex_unlock(&inode->i_mutex);
400 }
401
402 rc = security_read_policy(&plm->data, &plm->len);
403 if (rc)
404 goto err;
405
406 policy_opened = 1;
407
408 filp->private_data = plm;
409
410 mutex_unlock(&sel_mutex);
411
412 return 0;
413err:
414 mutex_unlock(&sel_mutex);
415
416 if (plm)
417 vfree(plm->data);
418 kfree(plm);
419 return rc;
420}
421
422static int sel_release_policy(struct inode *inode, struct file *filp)
423{
424 struct policy_load_memory *plm = filp->private_data;
425
426 BUG_ON(!plm);
427
428 policy_opened = 0;
429
430 vfree(plm->data);
431 kfree(plm);
432
433 return 0;
434}
435
436static ssize_t sel_read_policy(struct file *filp, char __user *buf,
437 size_t count, loff_t *ppos)
438{
439 struct policy_load_memory *plm = filp->private_data;
440 int ret;
441
442 mutex_lock(&sel_mutex);
443
444 ret = task_has_security(current, SECURITY__READ_POLICY);
445 if (ret)
446 goto out;
447
448 ret = simple_read_from_buffer(buf, count, ppos, plm->data, plm->len);
449out:
450 mutex_unlock(&sel_mutex);
451 return ret;
452}
453
454static int sel_mmap_policy_fault(struct vm_area_struct *vma,
455 struct vm_fault *vmf)
456{
457 struct policy_load_memory *plm = vma->vm_file->private_data;
458 unsigned long offset;
459 struct page *page;
460
461 if (vmf->flags & (FAULT_FLAG_MKWRITE | FAULT_FLAG_WRITE))
462 return VM_FAULT_SIGBUS;
463
464 offset = vmf->pgoff << PAGE_SHIFT;
465 if (offset >= roundup(plm->len, PAGE_SIZE))
466 return VM_FAULT_SIGBUS;
467
468 page = vmalloc_to_page(plm->data + offset);
469 get_page(page);
470
471 vmf->page = page;
472
473 return 0;
474}
475
476static struct vm_operations_struct sel_mmap_policy_ops = {
477 .fault = sel_mmap_policy_fault,
478 .page_mkwrite = sel_mmap_policy_fault,
479};
480
481int sel_mmap_policy(struct file *filp, struct vm_area_struct *vma)
482{
483 if (vma->vm_flags & VM_SHARED) {
484 /* do not allow mprotect to make mapping writable */
485 vma->vm_flags &= ~VM_MAYWRITE;
486
487 if (vma->vm_flags & VM_WRITE)
488 return -EACCES;
489 }
490
491 vma->vm_flags |= VM_RESERVED;
492 vma->vm_ops = &sel_mmap_policy_ops;
493
494 return 0;
495}
496
497static const struct file_operations sel_policy_ops = {
498 .open = sel_open_policy,
499 .read = sel_read_policy,
500 .mmap = sel_mmap_policy,
501 .release = sel_release_policy,
502};
503
299static ssize_t sel_write_load(struct file *file, const char __user *buf, 504static ssize_t sel_write_load(struct file *file, const char __user *buf,
300 size_t count, loff_t *ppos) 505 size_t count, loff_t *ppos)
301 506
302{ 507{
303 int ret;
304 ssize_t length; 508 ssize_t length;
305 void *data = NULL; 509 void *data = NULL;
306 510
@@ -310,17 +514,19 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
310 if (length) 514 if (length)
311 goto out; 515 goto out;
312 516
313 if (*ppos != 0) { 517 /* No partial writes. */
314 /* No partial writes. */ 518 length = -EINVAL;
315 length = -EINVAL; 519 if (*ppos != 0)
316 goto out; 520 goto out;
317 }
318 521
319 if ((count > 64 * 1024 * 1024) 522 length = -EFBIG;
320 || (data = vmalloc(count)) == NULL) { 523 if (count > 64 * 1024 * 1024)
321 length = -ENOMEM; 524 goto out;
525
526 length = -ENOMEM;
527 data = vmalloc(count);
528 if (!data)
322 goto out; 529 goto out;
323 }
324 530
325 length = -EFAULT; 531 length = -EFAULT;
326 if (copy_from_user(data, buf, count) != 0) 532 if (copy_from_user(data, buf, count) != 0)
@@ -330,23 +536,19 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
330 if (length) 536 if (length)
331 goto out; 537 goto out;
332 538
333 ret = sel_make_bools(); 539 length = sel_make_bools();
334 if (ret) { 540 if (length)
335 length = ret;
336 goto out1; 541 goto out1;
337 }
338 542
339 ret = sel_make_classes(); 543 length = sel_make_classes();
340 if (ret) { 544 if (length)
341 length = ret;
342 goto out1; 545 goto out1;
343 }
344 546
345 ret = sel_make_policycap(); 547 length = sel_make_policycap();
346 if (ret) 548 if (length)
347 length = ret; 549 goto out1;
348 else 550
349 length = count; 551 length = count;
350 552
351out1: 553out1:
352 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD, 554 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
@@ -366,26 +568,26 @@ static const struct file_operations sel_load_ops = {
366 568
367static ssize_t sel_write_context(struct file *file, char *buf, size_t size) 569static ssize_t sel_write_context(struct file *file, char *buf, size_t size)
368{ 570{
369 char *canon; 571 char *canon = NULL;
370 u32 sid, len; 572 u32 sid, len;
371 ssize_t length; 573 ssize_t length;
372 574
373 length = task_has_security(current, SECURITY__CHECK_CONTEXT); 575 length = task_has_security(current, SECURITY__CHECK_CONTEXT);
374 if (length) 576 if (length)
375 return length; 577 goto out;
376 578
377 length = security_context_to_sid(buf, size, &sid); 579 length = security_context_to_sid(buf, size, &sid);
378 if (length < 0) 580 if (length)
379 return length; 581 goto out;
380 582
381 length = security_sid_to_context(sid, &canon, &len); 583 length = security_sid_to_context(sid, &canon, &len);
382 if (length < 0) 584 if (length)
383 return length; 585 goto out;
384 586
587 length = -ERANGE;
385 if (len > SIMPLE_TRANSACTION_LIMIT) { 588 if (len > SIMPLE_TRANSACTION_LIMIT) {
386 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds " 589 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds "
387 "payload max\n", __func__, len); 590 "payload max\n", __func__, len);
388 length = -ERANGE;
389 goto out; 591 goto out;
390 } 592 }
391 593
@@ -409,23 +611,28 @@ static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
409static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf, 611static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
410 size_t count, loff_t *ppos) 612 size_t count, loff_t *ppos)
411{ 613{
412 char *page; 614 char *page = NULL;
413 ssize_t length; 615 ssize_t length;
414 unsigned int new_value; 616 unsigned int new_value;
415 617
416 length = task_has_security(current, SECURITY__SETCHECKREQPROT); 618 length = task_has_security(current, SECURITY__SETCHECKREQPROT);
417 if (length) 619 if (length)
418 return length; 620 goto out;
419 621
622 length = -ENOMEM;
420 if (count >= PAGE_SIZE) 623 if (count >= PAGE_SIZE)
421 return -ENOMEM; 624 goto out;
422 if (*ppos != 0) { 625
423 /* No partial writes. */ 626 /* No partial writes. */
424 return -EINVAL; 627 length = -EINVAL;
425 } 628 if (*ppos != 0)
629 goto out;
630
631 length = -ENOMEM;
426 page = (char *)get_zeroed_page(GFP_KERNEL); 632 page = (char *)get_zeroed_page(GFP_KERNEL);
427 if (!page) 633 if (!page)
428 return -ENOMEM; 634 goto out;
635
429 length = -EFAULT; 636 length = -EFAULT;
430 if (copy_from_user(page, buf, count)) 637 if (copy_from_user(page, buf, count))
431 goto out; 638 goto out;
@@ -500,7 +707,7 @@ static const struct file_operations transaction_ops = {
500 707
501static ssize_t sel_write_access(struct file *file, char *buf, size_t size) 708static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
502{ 709{
503 char *scon, *tcon; 710 char *scon = NULL, *tcon = NULL;
504 u32 ssid, tsid; 711 u32 ssid, tsid;
505 u16 tclass; 712 u16 tclass;
506 struct av_decision avd; 713 struct av_decision avd;
@@ -508,27 +715,29 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
508 715
509 length = task_has_security(current, SECURITY__COMPUTE_AV); 716 length = task_has_security(current, SECURITY__COMPUTE_AV);
510 if (length) 717 if (length)
511 return length; 718 goto out;
512 719
513 length = -ENOMEM; 720 length = -ENOMEM;
514 scon = kzalloc(size + 1, GFP_KERNEL); 721 scon = kzalloc(size + 1, GFP_KERNEL);
515 if (!scon) 722 if (!scon)
516 return length; 723 goto out;
517 724
725 length = -ENOMEM;
518 tcon = kzalloc(size + 1, GFP_KERNEL); 726 tcon = kzalloc(size + 1, GFP_KERNEL);
519 if (!tcon) 727 if (!tcon)
520 goto out; 728 goto out;
521 729
522 length = -EINVAL; 730 length = -EINVAL;
523 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 731 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
524 goto out2; 732 goto out;
525 733
526 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 734 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
527 if (length < 0) 735 if (length)
528 goto out2; 736 goto out;
737
529 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 738 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
530 if (length < 0) 739 if (length)
531 goto out2; 740 goto out;
532 741
533 security_compute_av_user(ssid, tsid, tclass, &avd); 742 security_compute_av_user(ssid, tsid, tclass, &avd);
534 743
@@ -537,133 +746,177 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
537 avd.allowed, 0xffffffff, 746 avd.allowed, 0xffffffff,
538 avd.auditallow, avd.auditdeny, 747 avd.auditallow, avd.auditdeny,
539 avd.seqno, avd.flags); 748 avd.seqno, avd.flags);
540out2:
541 kfree(tcon);
542out: 749out:
750 kfree(tcon);
543 kfree(scon); 751 kfree(scon);
544 return length; 752 return length;
545} 753}
546 754
755static inline int hexcode_to_int(int code) {
756 if (code == '\0' || !isxdigit(code))
757 return -1;
758 if (isdigit(code))
759 return code - '0';
760 return tolower(code) - 'a' + 10;
761}
762
547static ssize_t sel_write_create(struct file *file, char *buf, size_t size) 763static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
548{ 764{
549 char *scon, *tcon; 765 char *scon = NULL, *tcon = NULL;
766 char *namebuf = NULL, *objname = NULL;
550 u32 ssid, tsid, newsid; 767 u32 ssid, tsid, newsid;
551 u16 tclass; 768 u16 tclass;
552 ssize_t length; 769 ssize_t length;
553 char *newcon; 770 char *newcon = NULL;
554 u32 len; 771 u32 len;
772 int nargs;
555 773
556 length = task_has_security(current, SECURITY__COMPUTE_CREATE); 774 length = task_has_security(current, SECURITY__COMPUTE_CREATE);
557 if (length) 775 if (length)
558 return length; 776 goto out;
559 777
560 length = -ENOMEM; 778 length = -ENOMEM;
561 scon = kzalloc(size + 1, GFP_KERNEL); 779 scon = kzalloc(size + 1, GFP_KERNEL);
562 if (!scon) 780 if (!scon)
563 return length; 781 goto out;
564 782
783 length = -ENOMEM;
565 tcon = kzalloc(size + 1, GFP_KERNEL); 784 tcon = kzalloc(size + 1, GFP_KERNEL);
566 if (!tcon) 785 if (!tcon)
567 goto out; 786 goto out;
568 787
788 length = -ENOMEM;
789 namebuf = kzalloc(size + 1, GFP_KERNEL);
790 if (!namebuf)
791 goto out;
792
569 length = -EINVAL; 793 length = -EINVAL;
570 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 794 nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf);
571 goto out2; 795 if (nargs < 3 || nargs > 4)
796 goto out;
797 if (nargs == 4) {
798 /*
799 * If and when the name of new object to be queried contains
800 * either whitespace or multibyte characters, they shall be
801 * encoded based on the percentage-encoding rule.
802 * If not encoded, the sscanf logic picks up only left-half
803 * of the supplied name; splitted by a whitespace unexpectedly.
804 */
805 char *r, *w;
806 int c1, c2;
807
808 r = w = namebuf;
809 do {
810 c1 = *r++;
811 if (c1 == '+')
812 c1 = ' ';
813 else if (c1 == '%') {
814 if ((c1 = hexcode_to_int(*r++)) < 0)
815 goto out;
816 if ((c2 = hexcode_to_int(*r++)) < 0)
817 goto out;
818 c1 = (c1 << 4) | c2;
819 }
820 *w++ = c1;
821 } while (c1 != '\0');
822
823 objname = namebuf;
824 }
572 825
573 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 826 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
574 if (length < 0) 827 if (length)
575 goto out2; 828 goto out;
829
576 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 830 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
577 if (length < 0) 831 if (length)
578 goto out2; 832 goto out;
579 833
580 length = security_transition_sid_user(ssid, tsid, tclass, &newsid); 834 length = security_transition_sid_user(ssid, tsid, tclass,
581 if (length < 0) 835 objname, &newsid);
582 goto out2; 836 if (length)
837 goto out;
583 838
584 length = security_sid_to_context(newsid, &newcon, &len); 839 length = security_sid_to_context(newsid, &newcon, &len);
585 if (length < 0) 840 if (length)
586 goto out2; 841 goto out;
587 842
843 length = -ERANGE;
588 if (len > SIMPLE_TRANSACTION_LIMIT) { 844 if (len > SIMPLE_TRANSACTION_LIMIT) {
589 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds " 845 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds "
590 "payload max\n", __func__, len); 846 "payload max\n", __func__, len);
591 length = -ERANGE; 847 goto out;
592 goto out3;
593 } 848 }
594 849
595 memcpy(buf, newcon, len); 850 memcpy(buf, newcon, len);
596 length = len; 851 length = len;
597out3: 852out:
598 kfree(newcon); 853 kfree(newcon);
599out2: 854 kfree(namebuf);
600 kfree(tcon); 855 kfree(tcon);
601out:
602 kfree(scon); 856 kfree(scon);
603 return length; 857 return length;
604} 858}
605 859
606static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size) 860static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
607{ 861{
608 char *scon, *tcon; 862 char *scon = NULL, *tcon = NULL;
609 u32 ssid, tsid, newsid; 863 u32 ssid, tsid, newsid;
610 u16 tclass; 864 u16 tclass;
611 ssize_t length; 865 ssize_t length;
612 char *newcon; 866 char *newcon = NULL;
613 u32 len; 867 u32 len;
614 868
615 length = task_has_security(current, SECURITY__COMPUTE_RELABEL); 869 length = task_has_security(current, SECURITY__COMPUTE_RELABEL);
616 if (length) 870 if (length)
617 return length; 871 goto out;
618 872
619 length = -ENOMEM; 873 length = -ENOMEM;
620 scon = kzalloc(size + 1, GFP_KERNEL); 874 scon = kzalloc(size + 1, GFP_KERNEL);
621 if (!scon) 875 if (!scon)
622 return length; 876 goto out;
623 877
878 length = -ENOMEM;
624 tcon = kzalloc(size + 1, GFP_KERNEL); 879 tcon = kzalloc(size + 1, GFP_KERNEL);
625 if (!tcon) 880 if (!tcon)
626 goto out; 881 goto out;
627 882
628 length = -EINVAL; 883 length = -EINVAL;
629 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 884 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
630 goto out2; 885 goto out;
631 886
632 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 887 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
633 if (length < 0) 888 if (length)
634 goto out2; 889 goto out;
890
635 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 891 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
636 if (length < 0) 892 if (length)
637 goto out2; 893 goto out;
638 894
639 length = security_change_sid(ssid, tsid, tclass, &newsid); 895 length = security_change_sid(ssid, tsid, tclass, &newsid);
640 if (length < 0) 896 if (length)
641 goto out2; 897 goto out;
642 898
643 length = security_sid_to_context(newsid, &newcon, &len); 899 length = security_sid_to_context(newsid, &newcon, &len);
644 if (length < 0) 900 if (length)
645 goto out2; 901 goto out;
646 902
647 if (len > SIMPLE_TRANSACTION_LIMIT) { 903 length = -ERANGE;
648 length = -ERANGE; 904 if (len > SIMPLE_TRANSACTION_LIMIT)
649 goto out3; 905 goto out;
650 }
651 906
652 memcpy(buf, newcon, len); 907 memcpy(buf, newcon, len);
653 length = len; 908 length = len;
654out3: 909out:
655 kfree(newcon); 910 kfree(newcon);
656out2:
657 kfree(tcon); 911 kfree(tcon);
658out:
659 kfree(scon); 912 kfree(scon);
660 return length; 913 return length;
661} 914}
662 915
663static ssize_t sel_write_user(struct file *file, char *buf, size_t size) 916static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
664{ 917{
665 char *con, *user, *ptr; 918 char *con = NULL, *user = NULL, *ptr;
666 u32 sid, *sids; 919 u32 sid, *sids = NULL;
667 ssize_t length; 920 ssize_t length;
668 char *newcon; 921 char *newcon;
669 int i, rc; 922 int i, rc;
@@ -671,28 +924,29 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
671 924
672 length = task_has_security(current, SECURITY__COMPUTE_USER); 925 length = task_has_security(current, SECURITY__COMPUTE_USER);
673 if (length) 926 if (length)
674 return length; 927 goto out;
675 928
676 length = -ENOMEM; 929 length = -ENOMEM;
677 con = kzalloc(size + 1, GFP_KERNEL); 930 con = kzalloc(size + 1, GFP_KERNEL);
678 if (!con) 931 if (!con)
679 return length; 932 goto out;
680 933
934 length = -ENOMEM;
681 user = kzalloc(size + 1, GFP_KERNEL); 935 user = kzalloc(size + 1, GFP_KERNEL);
682 if (!user) 936 if (!user)
683 goto out; 937 goto out;
684 938
685 length = -EINVAL; 939 length = -EINVAL;
686 if (sscanf(buf, "%s %s", con, user) != 2) 940 if (sscanf(buf, "%s %s", con, user) != 2)
687 goto out2; 941 goto out;
688 942
689 length = security_context_to_sid(con, strlen(con) + 1, &sid); 943 length = security_context_to_sid(con, strlen(con) + 1, &sid);
690 if (length < 0) 944 if (length)
691 goto out2; 945 goto out;
692 946
693 length = security_get_user_sids(sid, user, &sids, &nsids); 947 length = security_get_user_sids(sid, user, &sids, &nsids);
694 if (length < 0) 948 if (length)
695 goto out2; 949 goto out;
696 950
697 length = sprintf(buf, "%u", nsids) + 1; 951 length = sprintf(buf, "%u", nsids) + 1;
698 ptr = buf + length; 952 ptr = buf + length;
@@ -700,82 +954,80 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
700 rc = security_sid_to_context(sids[i], &newcon, &len); 954 rc = security_sid_to_context(sids[i], &newcon, &len);
701 if (rc) { 955 if (rc) {
702 length = rc; 956 length = rc;
703 goto out3; 957 goto out;
704 } 958 }
705 if ((length + len) >= SIMPLE_TRANSACTION_LIMIT) { 959 if ((length + len) >= SIMPLE_TRANSACTION_LIMIT) {
706 kfree(newcon); 960 kfree(newcon);
707 length = -ERANGE; 961 length = -ERANGE;
708 goto out3; 962 goto out;
709 } 963 }
710 memcpy(ptr, newcon, len); 964 memcpy(ptr, newcon, len);
711 kfree(newcon); 965 kfree(newcon);
712 ptr += len; 966 ptr += len;
713 length += len; 967 length += len;
714 } 968 }
715out3: 969out:
716 kfree(sids); 970 kfree(sids);
717out2:
718 kfree(user); 971 kfree(user);
719out:
720 kfree(con); 972 kfree(con);
721 return length; 973 return length;
722} 974}
723 975
724static ssize_t sel_write_member(struct file *file, char *buf, size_t size) 976static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
725{ 977{
726 char *scon, *tcon; 978 char *scon = NULL, *tcon = NULL;
727 u32 ssid, tsid, newsid; 979 u32 ssid, tsid, newsid;
728 u16 tclass; 980 u16 tclass;
729 ssize_t length; 981 ssize_t length;
730 char *newcon; 982 char *newcon = NULL;
731 u32 len; 983 u32 len;
732 984
733 length = task_has_security(current, SECURITY__COMPUTE_MEMBER); 985 length = task_has_security(current, SECURITY__COMPUTE_MEMBER);
734 if (length) 986 if (length)
735 return length; 987 goto out;
736 988
737 length = -ENOMEM; 989 length = -ENOMEM;
738 scon = kzalloc(size + 1, GFP_KERNEL); 990 scon = kzalloc(size + 1, GFP_KERNEL);
739 if (!scon) 991 if (!scon)
740 return length; 992 goto out;
741 993
994 length = -ENOMEM;
742 tcon = kzalloc(size + 1, GFP_KERNEL); 995 tcon = kzalloc(size + 1, GFP_KERNEL);
743 if (!tcon) 996 if (!tcon)
744 goto out; 997 goto out;
745 998
746 length = -EINVAL; 999 length = -EINVAL;
747 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 1000 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
748 goto out2; 1001 goto out;
749 1002
750 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 1003 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
751 if (length < 0) 1004 if (length)
752 goto out2; 1005 goto out;
1006
753 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); 1007 length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
754 if (length < 0) 1008 if (length)
755 goto out2; 1009 goto out;
756 1010
757 length = security_member_sid(ssid, tsid, tclass, &newsid); 1011 length = security_member_sid(ssid, tsid, tclass, &newsid);
758 if (length < 0) 1012 if (length)
759 goto out2; 1013 goto out;
760 1014
761 length = security_sid_to_context(newsid, &newcon, &len); 1015 length = security_sid_to_context(newsid, &newcon, &len);
762 if (length < 0) 1016 if (length)
763 goto out2; 1017 goto out;
764 1018
1019 length = -ERANGE;
765 if (len > SIMPLE_TRANSACTION_LIMIT) { 1020 if (len > SIMPLE_TRANSACTION_LIMIT) {
766 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds " 1021 printk(KERN_ERR "SELinux: %s: context size (%u) exceeds "
767 "payload max\n", __func__, len); 1022 "payload max\n", __func__, len);
768 length = -ERANGE; 1023 goto out;
769 goto out3;
770 } 1024 }
771 1025
772 memcpy(buf, newcon, len); 1026 memcpy(buf, newcon, len);
773 length = len; 1027 length = len;
774out3: 1028out:
775 kfree(newcon); 1029 kfree(newcon);
776out2:
777 kfree(tcon); 1030 kfree(tcon);
778out:
779 kfree(scon); 1031 kfree(scon);
780 return length; 1032 return length;
781} 1033}
@@ -804,16 +1056,14 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
804 1056
805 mutex_lock(&sel_mutex); 1057 mutex_lock(&sel_mutex);
806 1058
807 if (index >= bool_num || strcmp(name, bool_pending_names[index])) { 1059 ret = -EINVAL;
808 ret = -EINVAL; 1060 if (index >= bool_num || strcmp(name, bool_pending_names[index]))
809 goto out; 1061 goto out;
810 }
811 1062
1063 ret = -ENOMEM;
812 page = (char *)get_zeroed_page(GFP_KERNEL); 1064 page = (char *)get_zeroed_page(GFP_KERNEL);
813 if (!page) { 1065 if (!page)
814 ret = -ENOMEM;
815 goto out; 1066 goto out;
816 }
817 1067
818 cur_enforcing = security_get_bool_value(index); 1068 cur_enforcing = security_get_bool_value(index);
819 if (cur_enforcing < 0) { 1069 if (cur_enforcing < 0) {
@@ -825,8 +1075,7 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
825 ret = simple_read_from_buffer(buf, count, ppos, page, length); 1075 ret = simple_read_from_buffer(buf, count, ppos, page, length);
826out: 1076out:
827 mutex_unlock(&sel_mutex); 1077 mutex_unlock(&sel_mutex);
828 if (page) 1078 free_page((unsigned long)page);
829 free_page((unsigned long)page);
830 return ret; 1079 return ret;
831} 1080}
832 1081
@@ -846,26 +1095,23 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
846 if (length) 1095 if (length)
847 goto out; 1096 goto out;
848 1097
849 if (index >= bool_num || strcmp(name, bool_pending_names[index])) { 1098 length = -EINVAL;
850 length = -EINVAL; 1099 if (index >= bool_num || strcmp(name, bool_pending_names[index]))
851 goto out; 1100 goto out;
852 }
853 1101
854 if (count >= PAGE_SIZE) { 1102 length = -ENOMEM;
855 length = -ENOMEM; 1103 if (count >= PAGE_SIZE)
856 goto out; 1104 goto out;
857 }
858 1105
859 if (*ppos != 0) { 1106 /* No partial writes. */
860 /* No partial writes. */ 1107 length = -EINVAL;
861 length = -EINVAL; 1108 if (*ppos != 0)
862 goto out; 1109 goto out;
863 } 1110
1111 length = -ENOMEM;
864 page = (char *)get_zeroed_page(GFP_KERNEL); 1112 page = (char *)get_zeroed_page(GFP_KERNEL);
865 if (!page) { 1113 if (!page)
866 length = -ENOMEM;
867 goto out; 1114 goto out;
868 }
869 1115
870 length = -EFAULT; 1116 length = -EFAULT;
871 if (copy_from_user(page, buf, count)) 1117 if (copy_from_user(page, buf, count))
@@ -883,8 +1129,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
883 1129
884out: 1130out:
885 mutex_unlock(&sel_mutex); 1131 mutex_unlock(&sel_mutex);
886 if (page) 1132 free_page((unsigned long) page);
887 free_page((unsigned long) page);
888 return length; 1133 return length;
889} 1134}
890 1135
@@ -908,19 +1153,19 @@ static ssize_t sel_commit_bools_write(struct file *filep,
908 if (length) 1153 if (length)
909 goto out; 1154 goto out;
910 1155
911 if (count >= PAGE_SIZE) { 1156 length = -ENOMEM;
912 length = -ENOMEM; 1157 if (count >= PAGE_SIZE)
913 goto out; 1158 goto out;
914 } 1159
915 if (*ppos != 0) { 1160 /* No partial writes. */
916 /* No partial writes. */ 1161 length = -EINVAL;
1162 if (*ppos != 0)
917 goto out; 1163 goto out;
918 } 1164
1165 length = -ENOMEM;
919 page = (char *)get_zeroed_page(GFP_KERNEL); 1166 page = (char *)get_zeroed_page(GFP_KERNEL);
920 if (!page) { 1167 if (!page)
921 length = -ENOMEM;
922 goto out; 1168 goto out;
923 }
924 1169
925 length = -EFAULT; 1170 length = -EFAULT;
926 if (copy_from_user(page, buf, count)) 1171 if (copy_from_user(page, buf, count))
@@ -930,15 +1175,16 @@ static ssize_t sel_commit_bools_write(struct file *filep,
930 if (sscanf(page, "%d", &new_value) != 1) 1175 if (sscanf(page, "%d", &new_value) != 1)
931 goto out; 1176 goto out;
932 1177
1178 length = 0;
933 if (new_value && bool_pending_values) 1179 if (new_value && bool_pending_values)
934 security_set_bools(bool_num, bool_pending_values); 1180 length = security_set_bools(bool_num, bool_pending_values);
935 1181
936 length = count; 1182 if (!length)
1183 length = count;
937 1184
938out: 1185out:
939 mutex_unlock(&sel_mutex); 1186 mutex_unlock(&sel_mutex);
940 if (page) 1187 free_page((unsigned long) page);
941 free_page((unsigned long) page);
942 return length; 1188 return length;
943} 1189}
944 1190
@@ -951,31 +1197,35 @@ static void sel_remove_entries(struct dentry *de)
951{ 1197{
952 struct list_head *node; 1198 struct list_head *node;
953 1199
954 spin_lock(&dcache_lock); 1200 spin_lock(&de->d_lock);
955 node = de->d_subdirs.next; 1201 node = de->d_subdirs.next;
956 while (node != &de->d_subdirs) { 1202 while (node != &de->d_subdirs) {
957 struct dentry *d = list_entry(node, struct dentry, d_u.d_child); 1203 struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
1204
1205 spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
958 list_del_init(node); 1206 list_del_init(node);
959 1207
960 if (d->d_inode) { 1208 if (d->d_inode) {
961 d = dget_locked(d); 1209 dget_dlock(d);
962 spin_unlock(&dcache_lock); 1210 spin_unlock(&de->d_lock);
1211 spin_unlock(&d->d_lock);
963 d_delete(d); 1212 d_delete(d);
964 simple_unlink(de->d_inode, d); 1213 simple_unlink(de->d_inode, d);
965 dput(d); 1214 dput(d);
966 spin_lock(&dcache_lock); 1215 spin_lock(&de->d_lock);
967 } 1216 } else
1217 spin_unlock(&d->d_lock);
968 node = de->d_subdirs.next; 1218 node = de->d_subdirs.next;
969 } 1219 }
970 1220
971 spin_unlock(&dcache_lock); 1221 spin_unlock(&de->d_lock);
972} 1222}
973 1223
974#define BOOL_DIR_NAME "booleans" 1224#define BOOL_DIR_NAME "booleans"
975 1225
976static int sel_make_bools(void) 1226static int sel_make_bools(void)
977{ 1227{
978 int i, ret = 0; 1228 int i, ret;
979 ssize_t len; 1229 ssize_t len;
980 struct dentry *dentry = NULL; 1230 struct dentry *dentry = NULL;
981 struct dentry *dir = bool_dir; 1231 struct dentry *dir = bool_dir;
@@ -996,38 +1246,40 @@ static int sel_make_bools(void)
996 1246
997 sel_remove_entries(dir); 1247 sel_remove_entries(dir);
998 1248
1249 ret = -ENOMEM;
999 page = (char *)get_zeroed_page(GFP_KERNEL); 1250 page = (char *)get_zeroed_page(GFP_KERNEL);
1000 if (!page) 1251 if (!page)
1001 return -ENOMEM; 1252 goto out;
1002 1253
1003 ret = security_get_bools(&num, &names, &values); 1254 ret = security_get_bools(&num, &names, &values);
1004 if (ret != 0) 1255 if (ret)
1005 goto out; 1256 goto out;
1006 1257
1007 for (i = 0; i < num; i++) { 1258 for (i = 0; i < num; i++) {
1259 ret = -ENOMEM;
1008 dentry = d_alloc_name(dir, names[i]); 1260 dentry = d_alloc_name(dir, names[i]);
1009 if (!dentry) { 1261 if (!dentry)
1010 ret = -ENOMEM; 1262 goto out;
1011 goto err; 1263
1012 } 1264 ret = -ENOMEM;
1013 inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR); 1265 inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR);
1014 if (!inode) { 1266 if (!inode)
1015 ret = -ENOMEM; 1267 goto out;
1016 goto err;
1017 }
1018 1268
1269 ret = -EINVAL;
1019 len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]); 1270 len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]);
1020 if (len < 0) { 1271 if (len < 0)
1021 ret = -EINVAL; 1272 goto out;
1022 goto err; 1273
1023 } else if (len >= PAGE_SIZE) { 1274 ret = -ENAMETOOLONG;
1024 ret = -ENAMETOOLONG; 1275 if (len >= PAGE_SIZE)
1025 goto err; 1276 goto out;
1026 } 1277
1027 isec = (struct inode_security_struct *)inode->i_security; 1278 isec = (struct inode_security_struct *)inode->i_security;
1028 ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid); 1279 ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid);
1029 if (ret) 1280 if (ret)
1030 goto err; 1281 goto out;
1282
1031 isec->sid = sid; 1283 isec->sid = sid;
1032 isec->initialized = 1; 1284 isec->initialized = 1;
1033 inode->i_fop = &sel_bool_ops; 1285 inode->i_fop = &sel_bool_ops;
@@ -1037,10 +1289,12 @@ static int sel_make_bools(void)
1037 bool_num = num; 1289 bool_num = num;
1038 bool_pending_names = names; 1290 bool_pending_names = names;
1039 bool_pending_values = values; 1291 bool_pending_values = values;
1292
1293 free_page((unsigned long)page);
1294 return 0;
1040out: 1295out:
1041 free_page((unsigned long)page); 1296 free_page((unsigned long)page);
1042 return ret; 1297
1043err:
1044 if (names) { 1298 if (names) {
1045 for (i = 0; i < num; i++) 1299 for (i = 0; i < num; i++)
1046 kfree(names[i]); 1300 kfree(names[i]);
@@ -1048,8 +1302,8 @@ err:
1048 } 1302 }
1049 kfree(values); 1303 kfree(values);
1050 sel_remove_entries(dir); 1304 sel_remove_entries(dir);
1051 ret = -ENOMEM; 1305
1052 goto out; 1306 return ret;
1053} 1307}
1054 1308
1055#define NULL_FILE_NAME "null" 1309#define NULL_FILE_NAME "null"
@@ -1071,47 +1325,41 @@ static ssize_t sel_write_avc_cache_threshold(struct file *file,
1071 size_t count, loff_t *ppos) 1325 size_t count, loff_t *ppos)
1072 1326
1073{ 1327{
1074 char *page; 1328 char *page = NULL;
1075 ssize_t ret; 1329 ssize_t ret;
1076 int new_value; 1330 int new_value;
1077 1331
1078 if (count >= PAGE_SIZE) { 1332 ret = task_has_security(current, SECURITY__SETSECPARAM);
1079 ret = -ENOMEM; 1333 if (ret)
1080 goto out; 1334 goto out;
1081 }
1082 1335
1083 if (*ppos != 0) { 1336 ret = -ENOMEM;
1084 /* No partial writes. */ 1337 if (count >= PAGE_SIZE)
1085 ret = -EINVAL; 1338 goto out;
1339
1340 /* No partial writes. */
1341 ret = -EINVAL;
1342 if (*ppos != 0)
1086 goto out; 1343 goto out;
1087 }
1088 1344
1345 ret = -ENOMEM;
1089 page = (char *)get_zeroed_page(GFP_KERNEL); 1346 page = (char *)get_zeroed_page(GFP_KERNEL);
1090 if (!page) { 1347 if (!page)
1091 ret = -ENOMEM;
1092 goto out; 1348 goto out;
1093 }
1094 1349
1095 if (copy_from_user(page, buf, count)) { 1350 ret = -EFAULT;
1096 ret = -EFAULT; 1351 if (copy_from_user(page, buf, count))
1097 goto out_free; 1352 goto out;
1098 }
1099 1353
1100 if (sscanf(page, "%u", &new_value) != 1) { 1354 ret = -EINVAL;
1101 ret = -EINVAL; 1355 if (sscanf(page, "%u", &new_value) != 1)
1102 goto out; 1356 goto out;
1103 }
1104 1357
1105 if (new_value != avc_cache_threshold) { 1358 avc_cache_threshold = new_value;
1106 ret = task_has_security(current, SECURITY__SETSECPARAM); 1359
1107 if (ret)
1108 goto out_free;
1109 avc_cache_threshold = new_value;
1110 }
1111 ret = count; 1360 ret = count;
1112out_free:
1113 free_page((unsigned long)page);
1114out: 1361out:
1362 free_page((unsigned long)page);
1115 return ret; 1363 return ret;
1116} 1364}
1117 1365
@@ -1119,19 +1367,18 @@ static ssize_t sel_read_avc_hash_stats(struct file *filp, char __user *buf,
1119 size_t count, loff_t *ppos) 1367 size_t count, loff_t *ppos)
1120{ 1368{
1121 char *page; 1369 char *page;
1122 ssize_t ret = 0; 1370 ssize_t length;
1123 1371
1124 page = (char *)__get_free_page(GFP_KERNEL); 1372 page = (char *)__get_free_page(GFP_KERNEL);
1125 if (!page) { 1373 if (!page)
1126 ret = -ENOMEM; 1374 return -ENOMEM;
1127 goto out; 1375
1128 } 1376 length = avc_get_hash_stats(page);
1129 ret = avc_get_hash_stats(page); 1377 if (length >= 0)
1130 if (ret >= 0) 1378 length = simple_read_from_buffer(buf, count, ppos, page, length);
1131 ret = simple_read_from_buffer(buf, count, ppos, page, ret);
1132 free_page((unsigned long)page); 1379 free_page((unsigned long)page);
1133out: 1380
1134 return ret; 1381 return length;
1135} 1382}
1136 1383
1137static const struct file_operations sel_avc_cache_threshold_ops = { 1384static const struct file_operations sel_avc_cache_threshold_ops = {
@@ -1181,10 +1428,14 @@ static int sel_avc_stats_seq_show(struct seq_file *seq, void *v)
1181 if (v == SEQ_START_TOKEN) 1428 if (v == SEQ_START_TOKEN)
1182 seq_printf(seq, "lookups hits misses allocations reclaims " 1429 seq_printf(seq, "lookups hits misses allocations reclaims "
1183 "frees\n"); 1430 "frees\n");
1184 else 1431 else {
1185 seq_printf(seq, "%u %u %u %u %u %u\n", st->lookups, 1432 unsigned int lookups = st->lookups;
1186 st->hits, st->misses, st->allocations, 1433 unsigned int misses = st->misses;
1434 unsigned int hits = lookups - misses;
1435 seq_printf(seq, "%u %u %u %u %u %u\n", lookups,
1436 hits, misses, st->allocations,
1187 st->reclaims, st->frees); 1437 st->reclaims, st->frees);
1438 }
1188 return 0; 1439 return 0;
1189} 1440}
1190 1441
@@ -1213,7 +1464,7 @@ static const struct file_operations sel_avc_cache_stats_ops = {
1213 1464
1214static int sel_make_avc_files(struct dentry *dir) 1465static int sel_make_avc_files(struct dentry *dir)
1215{ 1466{
1216 int i, ret = 0; 1467 int i;
1217 static struct tree_descr files[] = { 1468 static struct tree_descr files[] = {
1218 { "cache_threshold", 1469 { "cache_threshold",
1219 &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR }, 1470 &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR },
@@ -1228,22 +1479,19 @@ static int sel_make_avc_files(struct dentry *dir)
1228 struct dentry *dentry; 1479 struct dentry *dentry;
1229 1480
1230 dentry = d_alloc_name(dir, files[i].name); 1481 dentry = d_alloc_name(dir, files[i].name);
1231 if (!dentry) { 1482 if (!dentry)
1232 ret = -ENOMEM; 1483 return -ENOMEM;
1233 goto out;
1234 }
1235 1484
1236 inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode); 1485 inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode);
1237 if (!inode) { 1486 if (!inode)
1238 ret = -ENOMEM; 1487 return -ENOMEM;
1239 goto out; 1488
1240 }
1241 inode->i_fop = files[i].ops; 1489 inode->i_fop = files[i].ops;
1242 inode->i_ino = ++sel_last_ino; 1490 inode->i_ino = ++sel_last_ino;
1243 d_add(dentry, inode); 1491 d_add(dentry, inode);
1244 } 1492 }
1245out: 1493
1246 return ret; 1494 return 0;
1247} 1495}
1248 1496
1249static ssize_t sel_read_initcon(struct file *file, char __user *buf, 1497static ssize_t sel_read_initcon(struct file *file, char __user *buf,
@@ -1257,7 +1505,7 @@ static ssize_t sel_read_initcon(struct file *file, char __user *buf,
1257 inode = file->f_path.dentry->d_inode; 1505 inode = file->f_path.dentry->d_inode;
1258 sid = inode->i_ino&SEL_INO_MASK; 1506 sid = inode->i_ino&SEL_INO_MASK;
1259 ret = security_sid_to_context(sid, &con, &len); 1507 ret = security_sid_to_context(sid, &con, &len);
1260 if (ret < 0) 1508 if (ret)
1261 return ret; 1509 return ret;
1262 1510
1263 ret = simple_read_from_buffer(buf, count, ppos, con, len); 1511 ret = simple_read_from_buffer(buf, count, ppos, con, len);
@@ -1272,28 +1520,25 @@ static const struct file_operations sel_initcon_ops = {
1272 1520
1273static int sel_make_initcon_files(struct dentry *dir) 1521static int sel_make_initcon_files(struct dentry *dir)
1274{ 1522{
1275 int i, ret = 0; 1523 int i;
1276 1524
1277 for (i = 1; i <= SECINITSID_NUM; i++) { 1525 for (i = 1; i <= SECINITSID_NUM; i++) {
1278 struct inode *inode; 1526 struct inode *inode;
1279 struct dentry *dentry; 1527 struct dentry *dentry;
1280 dentry = d_alloc_name(dir, security_get_initial_sid_context(i)); 1528 dentry = d_alloc_name(dir, security_get_initial_sid_context(i));
1281 if (!dentry) { 1529 if (!dentry)
1282 ret = -ENOMEM; 1530 return -ENOMEM;
1283 goto out;
1284 }
1285 1531
1286 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); 1532 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1287 if (!inode) { 1533 if (!inode)
1288 ret = -ENOMEM; 1534 return -ENOMEM;
1289 goto out; 1535
1290 }
1291 inode->i_fop = &sel_initcon_ops; 1536 inode->i_fop = &sel_initcon_ops;
1292 inode->i_ino = i|SEL_INITCON_INO_OFFSET; 1537 inode->i_ino = i|SEL_INITCON_INO_OFFSET;
1293 d_add(dentry, inode); 1538 d_add(dentry, inode);
1294 } 1539 }
1295out: 1540
1296 return ret; 1541 return 0;
1297} 1542}
1298 1543
1299static inline unsigned int sel_div(unsigned long a, unsigned long b) 1544static inline unsigned int sel_div(unsigned long a, unsigned long b)
@@ -1329,15 +1574,13 @@ static ssize_t sel_read_class(struct file *file, char __user *buf,
1329 unsigned long ino = file->f_path.dentry->d_inode->i_ino; 1574 unsigned long ino = file->f_path.dentry->d_inode->i_ino;
1330 1575
1331 page = (char *)__get_free_page(GFP_KERNEL); 1576 page = (char *)__get_free_page(GFP_KERNEL);
1332 if (!page) { 1577 if (!page)
1333 rc = -ENOMEM; 1578 return -ENOMEM;
1334 goto out;
1335 }
1336 1579
1337 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_class(ino)); 1580 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_class(ino));
1338 rc = simple_read_from_buffer(buf, count, ppos, page, len); 1581 rc = simple_read_from_buffer(buf, count, ppos, page, len);
1339 free_page((unsigned long)page); 1582 free_page((unsigned long)page);
1340out: 1583
1341 return rc; 1584 return rc;
1342} 1585}
1343 1586
@@ -1354,15 +1597,13 @@ static ssize_t sel_read_perm(struct file *file, char __user *buf,
1354 unsigned long ino = file->f_path.dentry->d_inode->i_ino; 1597 unsigned long ino = file->f_path.dentry->d_inode->i_ino;
1355 1598
1356 page = (char *)__get_free_page(GFP_KERNEL); 1599 page = (char *)__get_free_page(GFP_KERNEL);
1357 if (!page) { 1600 if (!page)
1358 rc = -ENOMEM; 1601 return -ENOMEM;
1359 goto out;
1360 }
1361 1602
1362 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_perm(ino)); 1603 len = snprintf(page, PAGE_SIZE, "%d", sel_ino_to_perm(ino));
1363 rc = simple_read_from_buffer(buf, count, ppos, page, len); 1604 rc = simple_read_from_buffer(buf, count, ppos, page, len);
1364 free_page((unsigned long)page); 1605 free_page((unsigned long)page);
1365out: 1606
1366 return rc; 1607 return rc;
1367} 1608}
1368 1609
@@ -1393,39 +1634,37 @@ static const struct file_operations sel_policycap_ops = {
1393static int sel_make_perm_files(char *objclass, int classvalue, 1634static int sel_make_perm_files(char *objclass, int classvalue,
1394 struct dentry *dir) 1635 struct dentry *dir)
1395{ 1636{
1396 int i, rc = 0, nperms; 1637 int i, rc, nperms;
1397 char **perms; 1638 char **perms;
1398 1639
1399 rc = security_get_permissions(objclass, &perms, &nperms); 1640 rc = security_get_permissions(objclass, &perms, &nperms);
1400 if (rc) 1641 if (rc)
1401 goto out; 1642 return rc;
1402 1643
1403 for (i = 0; i < nperms; i++) { 1644 for (i = 0; i < nperms; i++) {
1404 struct inode *inode; 1645 struct inode *inode;
1405 struct dentry *dentry; 1646 struct dentry *dentry;
1406 1647
1648 rc = -ENOMEM;
1407 dentry = d_alloc_name(dir, perms[i]); 1649 dentry = d_alloc_name(dir, perms[i]);
1408 if (!dentry) { 1650 if (!dentry)
1409 rc = -ENOMEM; 1651 goto out;
1410 goto out1;
1411 }
1412 1652
1653 rc = -ENOMEM;
1413 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); 1654 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1414 if (!inode) { 1655 if (!inode)
1415 rc = -ENOMEM; 1656 goto out;
1416 goto out1; 1657
1417 }
1418 inode->i_fop = &sel_perm_ops; 1658 inode->i_fop = &sel_perm_ops;
1419 /* i+1 since perm values are 1-indexed */ 1659 /* i+1 since perm values are 1-indexed */
1420 inode->i_ino = sel_perm_to_ino(classvalue, i + 1); 1660 inode->i_ino = sel_perm_to_ino(classvalue, i + 1);
1421 d_add(dentry, inode); 1661 d_add(dentry, inode);
1422 } 1662 }
1423 1663 rc = 0;
1424out1: 1664out:
1425 for (i = 0; i < nperms; i++) 1665 for (i = 0; i < nperms; i++)
1426 kfree(perms[i]); 1666 kfree(perms[i]);
1427 kfree(perms); 1667 kfree(perms);
1428out:
1429 return rc; 1668 return rc;
1430} 1669}
1431 1670
@@ -1437,34 +1676,27 @@ static int sel_make_class_dir_entries(char *classname, int index,
1437 int rc; 1676 int rc;
1438 1677
1439 dentry = d_alloc_name(dir, "index"); 1678 dentry = d_alloc_name(dir, "index");
1440 if (!dentry) { 1679 if (!dentry)
1441 rc = -ENOMEM; 1680 return -ENOMEM;
1442 goto out;
1443 }
1444 1681
1445 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO); 1682 inode = sel_make_inode(dir->d_sb, S_IFREG|S_IRUGO);
1446 if (!inode) { 1683 if (!inode)
1447 rc = -ENOMEM; 1684 return -ENOMEM;
1448 goto out;
1449 }
1450 1685
1451 inode->i_fop = &sel_class_ops; 1686 inode->i_fop = &sel_class_ops;
1452 inode->i_ino = sel_class_to_ino(index); 1687 inode->i_ino = sel_class_to_ino(index);
1453 d_add(dentry, inode); 1688 d_add(dentry, inode);
1454 1689
1455 dentry = d_alloc_name(dir, "perms"); 1690 dentry = d_alloc_name(dir, "perms");
1456 if (!dentry) { 1691 if (!dentry)
1457 rc = -ENOMEM; 1692 return -ENOMEM;
1458 goto out;
1459 }
1460 1693
1461 rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino); 1694 rc = sel_make_dir(dir->d_inode, dentry, &last_class_ino);
1462 if (rc) 1695 if (rc)
1463 goto out; 1696 return rc;
1464 1697
1465 rc = sel_make_perm_files(classname, index, dentry); 1698 rc = sel_make_perm_files(classname, index, dentry);
1466 1699
1467out:
1468 return rc; 1700 return rc;
1469} 1701}
1470 1702
@@ -1494,15 +1726,15 @@ static void sel_remove_classes(void)
1494 1726
1495static int sel_make_classes(void) 1727static int sel_make_classes(void)
1496{ 1728{
1497 int rc = 0, nclasses, i; 1729 int rc, nclasses, i;
1498 char **classes; 1730 char **classes;
1499 1731
1500 /* delete any existing entries */ 1732 /* delete any existing entries */
1501 sel_remove_classes(); 1733 sel_remove_classes();
1502 1734
1503 rc = security_get_classes(&classes, &nclasses); 1735 rc = security_get_classes(&classes, &nclasses);
1504 if (rc < 0) 1736 if (rc)
1505 goto out; 1737 return rc;
1506 1738
1507 /* +2 since classes are 1-indexed */ 1739 /* +2 since classes are 1-indexed */
1508 last_class_ino = sel_class_to_ino(nclasses + 2); 1740 last_class_ino = sel_class_to_ino(nclasses + 2);
@@ -1510,29 +1742,27 @@ static int sel_make_classes(void)
1510 for (i = 0; i < nclasses; i++) { 1742 for (i = 0; i < nclasses; i++) {
1511 struct dentry *class_name_dir; 1743 struct dentry *class_name_dir;
1512 1744
1745 rc = -ENOMEM;
1513 class_name_dir = d_alloc_name(class_dir, classes[i]); 1746 class_name_dir = d_alloc_name(class_dir, classes[i]);
1514 if (!class_name_dir) { 1747 if (!class_name_dir)
1515 rc = -ENOMEM; 1748 goto out;
1516 goto out1;
1517 }
1518 1749
1519 rc = sel_make_dir(class_dir->d_inode, class_name_dir, 1750 rc = sel_make_dir(class_dir->d_inode, class_name_dir,
1520 &last_class_ino); 1751 &last_class_ino);
1521 if (rc) 1752 if (rc)
1522 goto out1; 1753 goto out;
1523 1754
1524 /* i+1 since class values are 1-indexed */ 1755 /* i+1 since class values are 1-indexed */
1525 rc = sel_make_class_dir_entries(classes[i], i + 1, 1756 rc = sel_make_class_dir_entries(classes[i], i + 1,
1526 class_name_dir); 1757 class_name_dir);
1527 if (rc) 1758 if (rc)
1528 goto out1; 1759 goto out;
1529 } 1760 }
1530 1761 rc = 0;
1531out1: 1762out:
1532 for (i = 0; i < nclasses; i++) 1763 for (i = 0; i < nclasses; i++)
1533 kfree(classes[i]); 1764 kfree(classes[i]);
1534 kfree(classes); 1765 kfree(classes);
1535out:
1536 return rc; 1766 return rc;
1537} 1767}
1538 1768
@@ -1569,14 +1799,12 @@ static int sel_make_policycap(void)
1569static int sel_make_dir(struct inode *dir, struct dentry *dentry, 1799static int sel_make_dir(struct inode *dir, struct dentry *dentry,
1570 unsigned long *ino) 1800 unsigned long *ino)
1571{ 1801{
1572 int ret = 0;
1573 struct inode *inode; 1802 struct inode *inode;
1574 1803
1575 inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO); 1804 inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO);
1576 if (!inode) { 1805 if (!inode)
1577 ret = -ENOMEM; 1806 return -ENOMEM;
1578 goto out; 1807
1579 }
1580 inode->i_op = &simple_dir_inode_operations; 1808 inode->i_op = &simple_dir_inode_operations;
1581 inode->i_fop = &simple_dir_operations; 1809 inode->i_fop = &simple_dir_operations;
1582 inode->i_ino = ++(*ino); 1810 inode->i_ino = ++(*ino);
@@ -1585,8 +1813,8 @@ static int sel_make_dir(struct inode *dir, struct dentry *dentry,
1585 d_add(dentry, inode); 1813 d_add(dentry, inode);
1586 /* bump link count on parent directory, too */ 1814 /* bump link count on parent directory, too */
1587 inc_nlink(dir); 1815 inc_nlink(dir);
1588out: 1816
1589 return ret; 1817 return 0;
1590} 1818}
1591 1819
1592static int sel_fill_super(struct super_block *sb, void *data, int silent) 1820static int sel_fill_super(struct super_block *sb, void *data, int silent)
@@ -1612,6 +1840,8 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1612 [SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR}, 1840 [SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR},
1613 [SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO}, 1841 [SEL_REJECT_UNKNOWN] = {"reject_unknown", &sel_handle_unknown_ops, S_IRUGO},
1614 [SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO}, 1842 [SEL_DENY_UNKNOWN] = {"deny_unknown", &sel_handle_unknown_ops, S_IRUGO},
1843 [SEL_STATUS] = {"status", &sel_handle_status_ops, S_IRUGO},
1844 [SEL_POLICY] = {"policy", &sel_policy_ops, S_IRUSR},
1615 /* last one */ {""} 1845 /* last one */ {""}
1616 }; 1846 };
1617 ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files); 1847 ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files);
@@ -1620,11 +1850,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1620 1850
1621 root_inode = sb->s_root->d_inode; 1851 root_inode = sb->s_root->d_inode;
1622 1852
1853 ret = -ENOMEM;
1623 dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME); 1854 dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME);
1624 if (!dentry) { 1855 if (!dentry)
1625 ret = -ENOMEM;
1626 goto err; 1856 goto err;
1627 }
1628 1857
1629 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1858 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1630 if (ret) 1859 if (ret)
@@ -1632,17 +1861,16 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1632 1861
1633 bool_dir = dentry; 1862 bool_dir = dentry;
1634 1863
1864 ret = -ENOMEM;
1635 dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME); 1865 dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME);
1636 if (!dentry) { 1866 if (!dentry)
1637 ret = -ENOMEM;
1638 goto err; 1867 goto err;
1639 }
1640 1868
1869 ret = -ENOMEM;
1641 inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO); 1870 inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO);
1642 if (!inode) { 1871 if (!inode)
1643 ret = -ENOMEM;
1644 goto err; 1872 goto err;
1645 } 1873
1646 inode->i_ino = ++sel_last_ino; 1874 inode->i_ino = ++sel_last_ino;
1647 isec = (struct inode_security_struct *)inode->i_security; 1875 isec = (struct inode_security_struct *)inode->i_security;
1648 isec->sid = SECINITSID_DEVNULL; 1876 isec->sid = SECINITSID_DEVNULL;
@@ -1653,11 +1881,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1653 d_add(dentry, inode); 1881 d_add(dentry, inode);
1654 selinux_null = dentry; 1882 selinux_null = dentry;
1655 1883
1884 ret = -ENOMEM;
1656 dentry = d_alloc_name(sb->s_root, "avc"); 1885 dentry = d_alloc_name(sb->s_root, "avc");
1657 if (!dentry) { 1886 if (!dentry)
1658 ret = -ENOMEM;
1659 goto err; 1887 goto err;
1660 }
1661 1888
1662 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1889 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1663 if (ret) 1890 if (ret)
@@ -1667,11 +1894,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1667 if (ret) 1894 if (ret)
1668 goto err; 1895 goto err;
1669 1896
1897 ret = -ENOMEM;
1670 dentry = d_alloc_name(sb->s_root, "initial_contexts"); 1898 dentry = d_alloc_name(sb->s_root, "initial_contexts");
1671 if (!dentry) { 1899 if (!dentry)
1672 ret = -ENOMEM;
1673 goto err; 1900 goto err;
1674 }
1675 1901
1676 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1902 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1677 if (ret) 1903 if (ret)
@@ -1681,11 +1907,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1681 if (ret) 1907 if (ret)
1682 goto err; 1908 goto err;
1683 1909
1910 ret = -ENOMEM;
1684 dentry = d_alloc_name(sb->s_root, "class"); 1911 dentry = d_alloc_name(sb->s_root, "class");
1685 if (!dentry) { 1912 if (!dentry)
1686 ret = -ENOMEM;
1687 goto err; 1913 goto err;
1688 }
1689 1914
1690 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1915 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1691 if (ret) 1916 if (ret)
@@ -1693,11 +1918,10 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1693 1918
1694 class_dir = dentry; 1919 class_dir = dentry;
1695 1920
1921 ret = -ENOMEM;
1696 dentry = d_alloc_name(sb->s_root, "policy_capabilities"); 1922 dentry = d_alloc_name(sb->s_root, "policy_capabilities");
1697 if (!dentry) { 1923 if (!dentry)
1698 ret = -ENOMEM;
1699 goto err; 1924 goto err;
1700 }
1701 1925
1702 ret = sel_make_dir(root_inode, dentry, &sel_last_ino); 1926 ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
1703 if (ret) 1927 if (ret)
@@ -1705,28 +1929,27 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent)
1705 1929
1706 policycap_dir = dentry; 1930 policycap_dir = dentry;
1707 1931
1708out: 1932 return 0;
1709 return ret;
1710err: 1933err:
1711 printk(KERN_ERR "SELinux: %s: failed while creating inodes\n", 1934 printk(KERN_ERR "SELinux: %s: failed while creating inodes\n",
1712 __func__); 1935 __func__);
1713 goto out; 1936 return ret;
1714} 1937}
1715 1938
1716static int sel_get_sb(struct file_system_type *fs_type, 1939static struct dentry *sel_mount(struct file_system_type *fs_type,
1717 int flags, const char *dev_name, void *data, 1940 int flags, const char *dev_name, void *data)
1718 struct vfsmount *mnt)
1719{ 1941{
1720 return get_sb_single(fs_type, flags, data, sel_fill_super, mnt); 1942 return mount_single(fs_type, flags, data, sel_fill_super);
1721} 1943}
1722 1944
1723static struct file_system_type sel_fs_type = { 1945static struct file_system_type sel_fs_type = {
1724 .name = "selinuxfs", 1946 .name = "selinuxfs",
1725 .get_sb = sel_get_sb, 1947 .mount = sel_mount,
1726 .kill_sb = kill_litter_super, 1948 .kill_sb = kill_litter_super,
1727}; 1949};
1728 1950
1729struct vfsmount *selinuxfs_mount; 1951struct vfsmount *selinuxfs_mount;
1952static struct kobject *selinuxfs_kobj;
1730 1953
1731static int __init init_sel_fs(void) 1954static int __init init_sel_fs(void)
1732{ 1955{
@@ -1734,15 +1957,24 @@ static int __init init_sel_fs(void)
1734 1957
1735 if (!selinux_enabled) 1958 if (!selinux_enabled)
1736 return 0; 1959 return 0;
1960
1961 selinuxfs_kobj = kobject_create_and_add("selinux", fs_kobj);
1962 if (!selinuxfs_kobj)
1963 return -ENOMEM;
1964
1737 err = register_filesystem(&sel_fs_type); 1965 err = register_filesystem(&sel_fs_type);
1738 if (!err) { 1966 if (err) {
1739 selinuxfs_mount = kern_mount(&sel_fs_type); 1967 kobject_put(selinuxfs_kobj);
1740 if (IS_ERR(selinuxfs_mount)) { 1968 return err;
1741 printk(KERN_ERR "selinuxfs: could not mount!\n");
1742 err = PTR_ERR(selinuxfs_mount);
1743 selinuxfs_mount = NULL;
1744 }
1745 } 1969 }
1970
1971 selinuxfs_mount = kern_mount(&sel_fs_type);
1972 if (IS_ERR(selinuxfs_mount)) {
1973 printk(KERN_ERR "selinuxfs: could not mount!\n");
1974 err = PTR_ERR(selinuxfs_mount);
1975 selinuxfs_mount = NULL;
1976 }
1977
1746 return err; 1978 return err;
1747} 1979}
1748 1980
@@ -1751,6 +1983,7 @@ __initcall(init_sel_fs);
1751#ifdef CONFIG_SECURITY_SELINUX_DISABLE 1983#ifdef CONFIG_SECURITY_SELINUX_DISABLE
1752void exit_sel_fs(void) 1984void exit_sel_fs(void)
1753{ 1985{
1986 kobject_put(selinuxfs_kobj);
1754 unregister_filesystem(&sel_fs_type); 1987 unregister_filesystem(&sel_fs_type);
1755} 1988}
1756#endif 1989#endif
diff --git a/security/selinux/ss/Makefile b/security/selinux/ss/Makefile
deleted file mode 100644
index 15d4e62917de..000000000000
--- a/security/selinux/ss/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
1#
2# Makefile for building the SELinux security server as part of the kernel tree.
3#
4
5EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include
6obj-y := ss.o
7
8ss-y := ebitmap.o hashtab.o symtab.o sidtab.o avtab.o policydb.o services.o conditional.o mls.o
9
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index 929480c6c430..a3dd9faa19c0 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -266,8 +266,8 @@ int avtab_alloc(struct avtab *h, u32 nrules)
266 if (shift > 2) 266 if (shift > 2)
267 shift = shift - 2; 267 shift = shift - 2;
268 nslot = 1 << shift; 268 nslot = 1 << shift;
269 if (nslot > MAX_AVTAB_SIZE) 269 if (nslot > MAX_AVTAB_HASH_BUCKETS)
270 nslot = MAX_AVTAB_SIZE; 270 nslot = MAX_AVTAB_HASH_BUCKETS;
271 mask = nslot - 1; 271 mask = nslot - 1;
272 272
273 h->htable = kcalloc(nslot, sizeof(*(h->htable)), GFP_KERNEL); 273 h->htable = kcalloc(nslot, sizeof(*(h->htable)), GFP_KERNEL);
@@ -501,6 +501,48 @@ bad:
501 goto out; 501 goto out;
502} 502}
503 503
504int avtab_write_item(struct policydb *p, struct avtab_node *cur, void *fp)
505{
506 __le16 buf16[4];
507 __le32 buf32[1];
508 int rc;
509
510 buf16[0] = cpu_to_le16(cur->key.source_type);
511 buf16[1] = cpu_to_le16(cur->key.target_type);
512 buf16[2] = cpu_to_le16(cur->key.target_class);
513 buf16[3] = cpu_to_le16(cur->key.specified);
514 rc = put_entry(buf16, sizeof(u16), 4, fp);
515 if (rc)
516 return rc;
517 buf32[0] = cpu_to_le32(cur->datum.data);
518 rc = put_entry(buf32, sizeof(u32), 1, fp);
519 if (rc)
520 return rc;
521 return 0;
522}
523
524int avtab_write(struct policydb *p, struct avtab *a, void *fp)
525{
526 unsigned int i;
527 int rc = 0;
528 struct avtab_node *cur;
529 __le32 buf[1];
530
531 buf[0] = cpu_to_le32(a->nel);
532 rc = put_entry(buf, sizeof(u32), 1, fp);
533 if (rc)
534 return rc;
535
536 for (i = 0; i < a->nslot; i++) {
537 for (cur = a->htable[i]; cur; cur = cur->next) {
538 rc = avtab_write_item(p, cur, fp);
539 if (rc)
540 return rc;
541 }
542 }
543
544 return rc;
545}
504void avtab_cache_init(void) 546void avtab_cache_init(void)
505{ 547{
506 avtab_node_cachep = kmem_cache_create("avtab_node", 548 avtab_node_cachep = kmem_cache_create("avtab_node",
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index cd4f734e2749..63ce2f9e441d 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -14,7 +14,7 @@
14 * 14 *
15 * Copyright (C) 2003 Tresys Technology, LLC 15 * Copyright (C) 2003 Tresys Technology, LLC
16 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation, version 2. 18 * the Free Software Foundation, version 2.
19 * 19 *
20 * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp> 20 * Updated: Yuichi Nakamura <ynakam@hitachisoft.jp>
@@ -27,16 +27,16 @@ struct avtab_key {
27 u16 source_type; /* source type */ 27 u16 source_type; /* source type */
28 u16 target_type; /* target type */ 28 u16 target_type; /* target type */
29 u16 target_class; /* target object class */ 29 u16 target_class; /* target object class */
30#define AVTAB_ALLOWED 1 30#define AVTAB_ALLOWED 0x0001
31#define AVTAB_AUDITALLOW 2 31#define AVTAB_AUDITALLOW 0x0002
32#define AVTAB_AUDITDENY 4 32#define AVTAB_AUDITDENY 0x0004
33#define AVTAB_AV (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY) 33#define AVTAB_AV (AVTAB_ALLOWED | AVTAB_AUDITALLOW | AVTAB_AUDITDENY)
34#define AVTAB_TRANSITION 16 34#define AVTAB_TRANSITION 0x0010
35#define AVTAB_MEMBER 32 35#define AVTAB_MEMBER 0x0020
36#define AVTAB_CHANGE 64 36#define AVTAB_CHANGE 0x0040
37#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE) 37#define AVTAB_TYPE (AVTAB_TRANSITION | AVTAB_MEMBER | AVTAB_CHANGE)
38#define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */ 38#define AVTAB_ENABLED_OLD 0x80000000 /* reserved for used in cond_avtab */
39#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */ 39#define AVTAB_ENABLED 0x8000 /* reserved for used in cond_avtab */
40 u16 specified; /* what field is specified */ 40 u16 specified; /* what field is specified */
41}; 41};
42 42
@@ -71,6 +71,8 @@ int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
71 void *p); 71 void *p);
72 72
73int avtab_read(struct avtab *a, void *fp, struct policydb *pol); 73int avtab_read(struct avtab *a, void *fp, struct policydb *pol);
74int avtab_write_item(struct policydb *p, struct avtab_node *cur, void *fp);
75int avtab_write(struct policydb *p, struct avtab *a, void *fp);
74 76
75struct avtab_node *avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, 77struct avtab_node *avtab_insert_nonunique(struct avtab *h, struct avtab_key *key,
76 struct avtab_datum *datum); 78 struct avtab_datum *datum);
@@ -84,8 +86,6 @@ void avtab_cache_destroy(void);
84 86
85#define MAX_AVTAB_HASH_BITS 11 87#define MAX_AVTAB_HASH_BITS 11
86#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) 88#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
87#define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1)
88#define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS
89 89
90#endif /* _SS_AVTAB_H_ */ 90#endif /* _SS_AVTAB_H_ */
91 91
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index c91e150c3087..a53373207fb4 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -178,7 +178,7 @@ int cond_init_bool_indexes(struct policydb *p)
178 p->bool_val_to_struct = (struct cond_bool_datum **) 178 p->bool_val_to_struct = (struct cond_bool_datum **)
179 kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum *), GFP_KERNEL); 179 kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum *), GFP_KERNEL);
180 if (!p->bool_val_to_struct) 180 if (!p->bool_val_to_struct)
181 return -1; 181 return -ENOMEM;
182 return 0; 182 return 0;
183} 183}
184 184
@@ -193,6 +193,7 @@ int cond_index_bool(void *key, void *datum, void *datap)
193{ 193{
194 struct policydb *p; 194 struct policydb *p;
195 struct cond_bool_datum *booldatum; 195 struct cond_bool_datum *booldatum;
196 struct flex_array *fa;
196 197
197 booldatum = datum; 198 booldatum = datum;
198 p = datap; 199 p = datap;
@@ -200,7 +201,10 @@ int cond_index_bool(void *key, void *datum, void *datap)
200 if (!booldatum->value || booldatum->value > p->p_bools.nprim) 201 if (!booldatum->value || booldatum->value > p->p_bools.nprim)
201 return -EINVAL; 202 return -EINVAL;
202 203
203 p->p_bool_val_to_name[booldatum->value - 1] = key; 204 fa = p->sym_val_to_name[SYM_BOOLS];
205 if (flex_array_put_ptr(fa, booldatum->value - 1, key,
206 GFP_KERNEL | __GFP_ZERO))
207 BUG();
204 p->bool_val_to_struct[booldatum->value - 1] = booldatum; 208 p->bool_val_to_struct[booldatum->value - 1] = booldatum;
205 209
206 return 0; 210 return 0;
@@ -490,6 +494,129 @@ err:
490 return rc; 494 return rc;
491} 495}
492 496
497int cond_write_bool(void *vkey, void *datum, void *ptr)
498{
499 char *key = vkey;
500 struct cond_bool_datum *booldatum = datum;
501 struct policy_data *pd = ptr;
502 void *fp = pd->fp;
503 __le32 buf[3];
504 u32 len;
505 int rc;
506
507 len = strlen(key);
508 buf[0] = cpu_to_le32(booldatum->value);
509 buf[1] = cpu_to_le32(booldatum->state);
510 buf[2] = cpu_to_le32(len);
511 rc = put_entry(buf, sizeof(u32), 3, fp);
512 if (rc)
513 return rc;
514 rc = put_entry(key, 1, len, fp);
515 if (rc)
516 return rc;
517 return 0;
518}
519
520/*
521 * cond_write_cond_av_list doesn't write out the av_list nodes.
522 * Instead it writes out the key/value pairs from the avtab. This
523 * is necessary because there is no way to uniquely identifying rules
524 * in the avtab so it is not possible to associate individual rules
525 * in the avtab with a conditional without saving them as part of
526 * the conditional. This means that the avtab with the conditional
527 * rules will not be saved but will be rebuilt on policy load.
528 */
529static int cond_write_av_list(struct policydb *p,
530 struct cond_av_list *list, struct policy_file *fp)
531{
532 __le32 buf[1];
533 struct cond_av_list *cur_list;
534 u32 len;
535 int rc;
536
537 len = 0;
538 for (cur_list = list; cur_list != NULL; cur_list = cur_list->next)
539 len++;
540
541 buf[0] = cpu_to_le32(len);
542 rc = put_entry(buf, sizeof(u32), 1, fp);
543 if (rc)
544 return rc;
545
546 if (len == 0)
547 return 0;
548
549 for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) {
550 rc = avtab_write_item(p, cur_list->node, fp);
551 if (rc)
552 return rc;
553 }
554
555 return 0;
556}
557
558int cond_write_node(struct policydb *p, struct cond_node *node,
559 struct policy_file *fp)
560{
561 struct cond_expr *cur_expr;
562 __le32 buf[2];
563 int rc;
564 u32 len = 0;
565
566 buf[0] = cpu_to_le32(node->cur_state);
567 rc = put_entry(buf, sizeof(u32), 1, fp);
568 if (rc)
569 return rc;
570
571 for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next)
572 len++;
573
574 buf[0] = cpu_to_le32(len);
575 rc = put_entry(buf, sizeof(u32), 1, fp);
576 if (rc)
577 return rc;
578
579 for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) {
580 buf[0] = cpu_to_le32(cur_expr->expr_type);
581 buf[1] = cpu_to_le32(cur_expr->bool);
582 rc = put_entry(buf, sizeof(u32), 2, fp);
583 if (rc)
584 return rc;
585 }
586
587 rc = cond_write_av_list(p, node->true_list, fp);
588 if (rc)
589 return rc;
590 rc = cond_write_av_list(p, node->false_list, fp);
591 if (rc)
592 return rc;
593
594 return 0;
595}
596
597int cond_write_list(struct policydb *p, struct cond_node *list, void *fp)
598{
599 struct cond_node *cur;
600 u32 len;
601 __le32 buf[1];
602 int rc;
603
604 len = 0;
605 for (cur = list; cur != NULL; cur = cur->next)
606 len++;
607 buf[0] = cpu_to_le32(len);
608 rc = put_entry(buf, sizeof(u32), 1, fp);
609 if (rc)
610 return rc;
611
612 for (cur = list; cur != NULL; cur = cur->next) {
613 rc = cond_write_node(p, cur, fp);
614 if (rc)
615 return rc;
616 }
617
618 return 0;
619}
493/* Determine whether additional permissions are granted by the conditional 620/* Determine whether additional permissions are granted by the conditional
494 * av table, and if so, add them to the result 621 * av table, and if so, add them to the result
495 */ 622 */
diff --git a/security/selinux/ss/conditional.h b/security/selinux/ss/conditional.h
index 53ddb013ae57..3f209c635295 100644
--- a/security/selinux/ss/conditional.h
+++ b/security/selinux/ss/conditional.h
@@ -69,6 +69,8 @@ int cond_index_bool(void *key, void *datum, void *datap);
69 69
70int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp); 70int cond_read_bool(struct policydb *p, struct hashtab *h, void *fp);
71int cond_read_list(struct policydb *p, void *fp); 71int cond_read_list(struct policydb *p, void *fp);
72int cond_write_bool(void *key, void *datum, void *ptr);
73int cond_write_list(struct policydb *p, struct cond_node *list, void *fp);
72 74
73void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decision *avd); 75void cond_compute_av(struct avtab *ctab, struct avtab_key *key, struct av_decision *avd);
74 76
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 04b6145d767f..d42951fcbe87 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -22,6 +22,8 @@
22#include "ebitmap.h" 22#include "ebitmap.h"
23#include "policydb.h" 23#include "policydb.h"
24 24
25#define BITS_PER_U64 (sizeof(u64) * 8)
26
25int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2) 27int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2)
26{ 28{
27 struct ebitmap_node *n1, *n2; 29 struct ebitmap_node *n1, *n2;
@@ -363,10 +365,10 @@ int ebitmap_read(struct ebitmap *e, void *fp)
363 e->highbit = le32_to_cpu(buf[1]); 365 e->highbit = le32_to_cpu(buf[1]);
364 count = le32_to_cpu(buf[2]); 366 count = le32_to_cpu(buf[2]);
365 367
366 if (mapunit != sizeof(u64) * 8) { 368 if (mapunit != BITS_PER_U64) {
367 printk(KERN_ERR "SELinux: ebitmap: map size %u does not " 369 printk(KERN_ERR "SELinux: ebitmap: map size %u does not "
368 "match my size %Zd (high bit was %d)\n", 370 "match my size %Zd (high bit was %d)\n",
369 mapunit, sizeof(u64) * 8, e->highbit); 371 mapunit, BITS_PER_U64, e->highbit);
370 goto bad; 372 goto bad;
371 } 373 }
372 374
@@ -446,3 +448,78 @@ bad:
446 ebitmap_destroy(e); 448 ebitmap_destroy(e);
447 goto out; 449 goto out;
448} 450}
451
452int ebitmap_write(struct ebitmap *e, void *fp)
453{
454 struct ebitmap_node *n;
455 u32 count;
456 __le32 buf[3];
457 u64 map;
458 int bit, last_bit, last_startbit, rc;
459
460 buf[0] = cpu_to_le32(BITS_PER_U64);
461
462 count = 0;
463 last_bit = 0;
464 last_startbit = -1;
465 ebitmap_for_each_positive_bit(e, n, bit) {
466 if (rounddown(bit, (int)BITS_PER_U64) > last_startbit) {
467 count++;
468 last_startbit = rounddown(bit, BITS_PER_U64);
469 }
470 last_bit = roundup(bit + 1, BITS_PER_U64);
471 }
472 buf[1] = cpu_to_le32(last_bit);
473 buf[2] = cpu_to_le32(count);
474
475 rc = put_entry(buf, sizeof(u32), 3, fp);
476 if (rc)
477 return rc;
478
479 map = 0;
480 last_startbit = INT_MIN;
481 ebitmap_for_each_positive_bit(e, n, bit) {
482 if (rounddown(bit, (int)BITS_PER_U64) > last_startbit) {
483 __le64 buf64[1];
484
485 /* this is the very first bit */
486 if (!map) {
487 last_startbit = rounddown(bit, BITS_PER_U64);
488 map = (u64)1 << (bit - last_startbit);
489 continue;
490 }
491
492 /* write the last node */
493 buf[0] = cpu_to_le32(last_startbit);
494 rc = put_entry(buf, sizeof(u32), 1, fp);
495 if (rc)
496 return rc;
497
498 buf64[0] = cpu_to_le64(map);
499 rc = put_entry(buf64, sizeof(u64), 1, fp);
500 if (rc)
501 return rc;
502
503 /* set up for the next node */
504 map = 0;
505 last_startbit = rounddown(bit, BITS_PER_U64);
506 }
507 map |= (u64)1 << (bit - last_startbit);
508 }
509 /* write the last node */
510 if (map) {
511 __le64 buf64[1];
512
513 /* write the last node */
514 buf[0] = cpu_to_le32(last_startbit);
515 rc = put_entry(buf, sizeof(u32), 1, fp);
516 if (rc)
517 return rc;
518
519 buf64[0] = cpu_to_le64(map);
520 rc = put_entry(buf64, sizeof(u64), 1, fp);
521 if (rc)
522 return rc;
523 }
524 return 0;
525}
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index f283b4367f54..922f8afa89dd 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -36,7 +36,6 @@ struct ebitmap {
36}; 36};
37 37
38#define ebitmap_length(e) ((e)->highbit) 38#define ebitmap_length(e) ((e)->highbit)
39#define ebitmap_startbit(e) ((e)->node ? (e)->node->startbit : 0)
40 39
41static inline unsigned int ebitmap_start_positive(struct ebitmap *e, 40static inline unsigned int ebitmap_start_positive(struct ebitmap *e,
42 struct ebitmap_node **n) 41 struct ebitmap_node **n)
@@ -123,6 +122,7 @@ int ebitmap_get_bit(struct ebitmap *e, unsigned long bit);
123int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value); 122int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value);
124void ebitmap_destroy(struct ebitmap *e); 123void ebitmap_destroy(struct ebitmap *e);
125int ebitmap_read(struct ebitmap *e, void *fp); 124int ebitmap_read(struct ebitmap *e, void *fp);
125int ebitmap_write(struct ebitmap *e, void *fp);
126 126
127#ifdef CONFIG_NETLABEL 127#ifdef CONFIG_NETLABEL
128int ebitmap_netlbl_export(struct ebitmap *ebmap, 128int ebitmap_netlbl_export(struct ebitmap *ebmap,
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index b4eff7a60c50..e96174216bc9 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -45,7 +45,7 @@ int mls_compute_context_len(struct context *context)
45 len = 1; /* for the beginning ":" */ 45 len = 1; /* for the beginning ":" */
46 for (l = 0; l < 2; l++) { 46 for (l = 0; l < 2; l++) {
47 int index_sens = context->range.level[l].sens; 47 int index_sens = context->range.level[l].sens;
48 len += strlen(policydb.p_sens_val_to_name[index_sens - 1]); 48 len += strlen(sym_name(&policydb, SYM_LEVELS, index_sens - 1));
49 49
50 /* categories */ 50 /* categories */
51 head = -2; 51 head = -2;
@@ -55,17 +55,17 @@ int mls_compute_context_len(struct context *context)
55 if (i - prev > 1) { 55 if (i - prev > 1) {
56 /* one or more negative bits are skipped */ 56 /* one or more negative bits are skipped */
57 if (head != prev) { 57 if (head != prev) {
58 nm = policydb.p_cat_val_to_name[prev]; 58 nm = sym_name(&policydb, SYM_CATS, prev);
59 len += strlen(nm) + 1; 59 len += strlen(nm) + 1;
60 } 60 }
61 nm = policydb.p_cat_val_to_name[i]; 61 nm = sym_name(&policydb, SYM_CATS, i);
62 len += strlen(nm) + 1; 62 len += strlen(nm) + 1;
63 head = i; 63 head = i;
64 } 64 }
65 prev = i; 65 prev = i;
66 } 66 }
67 if (prev != head) { 67 if (prev != head) {
68 nm = policydb.p_cat_val_to_name[prev]; 68 nm = sym_name(&policydb, SYM_CATS, prev);
69 len += strlen(nm) + 1; 69 len += strlen(nm) + 1;
70 } 70 }
71 if (l == 0) { 71 if (l == 0) {
@@ -102,8 +102,8 @@ void mls_sid_to_context(struct context *context,
102 scontextp++; 102 scontextp++;
103 103
104 for (l = 0; l < 2; l++) { 104 for (l = 0; l < 2; l++) {
105 strcpy(scontextp, 105 strcpy(scontextp, sym_name(&policydb, SYM_LEVELS,
106 policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); 106 context->range.level[l].sens - 1));
107 scontextp += strlen(scontextp); 107 scontextp += strlen(scontextp);
108 108
109 /* categories */ 109 /* categories */
@@ -118,7 +118,7 @@ void mls_sid_to_context(struct context *context,
118 *scontextp++ = '.'; 118 *scontextp++ = '.';
119 else 119 else
120 *scontextp++ = ','; 120 *scontextp++ = ',';
121 nm = policydb.p_cat_val_to_name[prev]; 121 nm = sym_name(&policydb, SYM_CATS, prev);
122 strcpy(scontextp, nm); 122 strcpy(scontextp, nm);
123 scontextp += strlen(nm); 123 scontextp += strlen(nm);
124 } 124 }
@@ -126,7 +126,7 @@ void mls_sid_to_context(struct context *context,
126 *scontextp++ = ':'; 126 *scontextp++ = ':';
127 else 127 else
128 *scontextp++ = ','; 128 *scontextp++ = ',';
129 nm = policydb.p_cat_val_to_name[i]; 129 nm = sym_name(&policydb, SYM_CATS, i);
130 strcpy(scontextp, nm); 130 strcpy(scontextp, nm);
131 scontextp += strlen(nm); 131 scontextp += strlen(nm);
132 head = i; 132 head = i;
@@ -139,7 +139,7 @@ void mls_sid_to_context(struct context *context,
139 *scontextp++ = '.'; 139 *scontextp++ = '.';
140 else 140 else
141 *scontextp++ = ','; 141 *scontextp++ = ',';
142 nm = policydb.p_cat_val_to_name[prev]; 142 nm = sym_name(&policydb, SYM_CATS, prev);
143 strcpy(scontextp, nm); 143 strcpy(scontextp, nm);
144 scontextp += strlen(nm); 144 scontextp += strlen(nm);
145 } 145 }
@@ -166,7 +166,7 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l)
166 if (!l->sens || l->sens > p->p_levels.nprim) 166 if (!l->sens || l->sens > p->p_levels.nprim)
167 return 0; 167 return 0;
168 levdatum = hashtab_search(p->p_levels.table, 168 levdatum = hashtab_search(p->p_levels.table,
169 p->p_sens_val_to_name[l->sens - 1]); 169 sym_name(p, SYM_LEVELS, l->sens - 1));
170 if (!levdatum) 170 if (!levdatum)
171 return 0; 171 return 0;
172 172
@@ -482,7 +482,8 @@ int mls_convert_context(struct policydb *oldp,
482 482
483 for (l = 0; l < 2; l++) { 483 for (l = 0; l < 2; l++) {
484 levdatum = hashtab_search(newp->p_levels.table, 484 levdatum = hashtab_search(newp->p_levels.table,
485 oldp->p_sens_val_to_name[c->range.level[l].sens - 1]); 485 sym_name(oldp, SYM_LEVELS,
486 c->range.level[l].sens - 1));
486 487
487 if (!levdatum) 488 if (!levdatum)
488 return -EINVAL; 489 return -EINVAL;
@@ -493,7 +494,7 @@ int mls_convert_context(struct policydb *oldp,
493 int rc; 494 int rc;
494 495
495 catdatum = hashtab_search(newp->p_cats.table, 496 catdatum = hashtab_search(newp->p_cats.table,
496 oldp->p_cat_val_to_name[i]); 497 sym_name(oldp, SYM_CATS, i));
497 if (!catdatum) 498 if (!catdatum)
498 return -EINVAL; 499 return -EINVAL;
499 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); 500 rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1);
@@ -511,7 +512,8 @@ int mls_compute_sid(struct context *scontext,
511 struct context *tcontext, 512 struct context *tcontext,
512 u16 tclass, 513 u16 tclass,
513 u32 specified, 514 u32 specified,
514 struct context *newcontext) 515 struct context *newcontext,
516 bool sock)
515{ 517{
516 struct range_trans rtr; 518 struct range_trans rtr;
517 struct mls_range *r; 519 struct mls_range *r;
@@ -530,7 +532,7 @@ int mls_compute_sid(struct context *scontext,
530 return mls_range_set(newcontext, r); 532 return mls_range_set(newcontext, r);
531 /* Fallthrough */ 533 /* Fallthrough */
532 case AVTAB_CHANGE: 534 case AVTAB_CHANGE:
533 if (tclass == policydb.process_class) 535 if ((tclass == policydb.process_class) || (sock == true))
534 /* Use the process MLS attributes. */ 536 /* Use the process MLS attributes. */
535 return mls_context_cpy(newcontext, scontext); 537 return mls_context_cpy(newcontext, scontext);
536 else 538 else
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
index cd9152632e54..037bf9d82d41 100644
--- a/security/selinux/ss/mls.h
+++ b/security/selinux/ss/mls.h
@@ -49,7 +49,8 @@ int mls_compute_sid(struct context *scontext,
49 struct context *tcontext, 49 struct context *tcontext,
50 u16 tclass, 50 u16 tclass,
51 u32 specified, 51 u32 specified,
52 struct context *newcontext); 52 struct context *newcontext,
53 bool sock);
53 54
54int mls_setup_user_range(struct context *fromcon, struct user_datum *user, 55int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
55 struct context *usercon); 56 struct context *usercon);
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 3a29704be8ce..d246aca3f4fb 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -37,6 +37,7 @@
37#include "policydb.h" 37#include "policydb.h"
38#include "conditional.h" 38#include "conditional.h"
39#include "mls.h" 39#include "mls.h"
40#include "services.h"
40 41
41#define _DEBUG_HASHES 42#define _DEBUG_HASHES
42 43
@@ -122,6 +123,16 @@ static struct policydb_compat_info policydb_compat[] = {
122 .sym_num = SYM_NUM, 123 .sym_num = SYM_NUM,
123 .ocon_num = OCON_NUM, 124 .ocon_num = OCON_NUM,
124 }, 125 },
126 {
127 .version = POLICYDB_VERSION_FILENAME_TRANS,
128 .sym_num = SYM_NUM,
129 .ocon_num = OCON_NUM,
130 },
131 {
132 .version = POLICYDB_VERSION_ROLETRANS,
133 .sym_num = SYM_NUM,
134 .ocon_num = OCON_NUM,
135 },
125}; 136};
126 137
127static struct policydb_compat_info *policydb_lookup_compat(int version) 138static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -147,32 +158,67 @@ static int roles_init(struct policydb *p)
147 int rc; 158 int rc;
148 struct role_datum *role; 159 struct role_datum *role;
149 160
161 rc = -ENOMEM;
150 role = kzalloc(sizeof(*role), GFP_KERNEL); 162 role = kzalloc(sizeof(*role), GFP_KERNEL);
151 if (!role) { 163 if (!role)
152 rc = -ENOMEM;
153 goto out; 164 goto out;
154 } 165
166 rc = -EINVAL;
155 role->value = ++p->p_roles.nprim; 167 role->value = ++p->p_roles.nprim;
156 if (role->value != OBJECT_R_VAL) { 168 if (role->value != OBJECT_R_VAL)
157 rc = -EINVAL; 169 goto out;
158 goto out_free_role; 170
159 } 171 rc = -ENOMEM;
160 key = kstrdup(OBJECT_R, GFP_KERNEL); 172 key = kstrdup(OBJECT_R, GFP_KERNEL);
161 if (!key) { 173 if (!key)
162 rc = -ENOMEM; 174 goto out;
163 goto out_free_role; 175
164 }
165 rc = hashtab_insert(p->p_roles.table, key, role); 176 rc = hashtab_insert(p->p_roles.table, key, role);
166 if (rc) 177 if (rc)
167 goto out_free_key; 178 goto out;
168out:
169 return rc;
170 179
171out_free_key: 180 return 0;
181out:
172 kfree(key); 182 kfree(key);
173out_free_role:
174 kfree(role); 183 kfree(role);
175 goto out; 184 return rc;
185}
186
187static u32 filenametr_hash(struct hashtab *h, const void *k)
188{
189 const struct filename_trans *ft = k;
190 unsigned long hash;
191 unsigned int byte_num;
192 unsigned char focus;
193
194 hash = ft->stype ^ ft->ttype ^ ft->tclass;
195
196 byte_num = 0;
197 while ((focus = ft->name[byte_num++]))
198 hash = partial_name_hash(focus, hash);
199 return hash & (h->size - 1);
200}
201
202static int filenametr_cmp(struct hashtab *h, const void *k1, const void *k2)
203{
204 const struct filename_trans *ft1 = k1;
205 const struct filename_trans *ft2 = k2;
206 int v;
207
208 v = ft1->stype - ft2->stype;
209 if (v)
210 return v;
211
212 v = ft1->ttype - ft2->ttype;
213 if (v)
214 return v;
215
216 v = ft1->tclass - ft2->tclass;
217 if (v)
218 return v;
219
220 return strcmp(ft1->name, ft2->name);
221
176} 222}
177 223
178static u32 rangetr_hash(struct hashtab *h, const void *k) 224static u32 rangetr_hash(struct hashtab *h, const void *k)
@@ -185,9 +231,19 @@ static u32 rangetr_hash(struct hashtab *h, const void *k)
185static int rangetr_cmp(struct hashtab *h, const void *k1, const void *k2) 231static int rangetr_cmp(struct hashtab *h, const void *k1, const void *k2)
186{ 232{
187 const struct range_trans *key1 = k1, *key2 = k2; 233 const struct range_trans *key1 = k1, *key2 = k2;
188 return (key1->source_type != key2->source_type || 234 int v;
189 key1->target_type != key2->target_type || 235
190 key1->target_class != key2->target_class); 236 v = key1->source_type - key2->source_type;
237 if (v)
238 return v;
239
240 v = key1->target_type - key2->target_type;
241 if (v)
242 return v;
243
244 v = key1->target_class - key2->target_class;
245
246 return v;
191} 247}
192 248
193/* 249/*
@@ -202,35 +258,40 @@ static int policydb_init(struct policydb *p)
202 for (i = 0; i < SYM_NUM; i++) { 258 for (i = 0; i < SYM_NUM; i++) {
203 rc = symtab_init(&p->symtab[i], symtab_sizes[i]); 259 rc = symtab_init(&p->symtab[i], symtab_sizes[i]);
204 if (rc) 260 if (rc)
205 goto out_free_symtab; 261 goto out;
206 } 262 }
207 263
208 rc = avtab_init(&p->te_avtab); 264 rc = avtab_init(&p->te_avtab);
209 if (rc) 265 if (rc)
210 goto out_free_symtab; 266 goto out;
211 267
212 rc = roles_init(p); 268 rc = roles_init(p);
213 if (rc) 269 if (rc)
214 goto out_free_symtab; 270 goto out;
215 271
216 rc = cond_policydb_init(p); 272 rc = cond_policydb_init(p);
217 if (rc) 273 if (rc)
218 goto out_free_symtab; 274 goto out;
275
276 p->filename_trans = hashtab_create(filenametr_hash, filenametr_cmp, (1 << 10));
277 if (!p->filename_trans)
278 goto out;
219 279
220 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256); 280 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
221 if (!p->range_tr) 281 if (!p->range_tr)
222 goto out_free_symtab; 282 goto out;
223 283
284 ebitmap_init(&p->filename_trans_ttypes);
224 ebitmap_init(&p->policycaps); 285 ebitmap_init(&p->policycaps);
225 ebitmap_init(&p->permissive_map); 286 ebitmap_init(&p->permissive_map);
226 287
288 return 0;
227out: 289out:
228 return rc; 290 hashtab_destroy(p->filename_trans);
229 291 hashtab_destroy(p->range_tr);
230out_free_symtab:
231 for (i = 0; i < SYM_NUM; i++) 292 for (i = 0; i < SYM_NUM; i++)
232 hashtab_destroy(p->symtab[i].table); 293 hashtab_destroy(p->symtab[i].table);
233 goto out; 294 return rc;
234} 295}
235 296
236/* 297/*
@@ -247,12 +308,17 @@ static int common_index(void *key, void *datum, void *datap)
247{ 308{
248 struct policydb *p; 309 struct policydb *p;
249 struct common_datum *comdatum; 310 struct common_datum *comdatum;
311 struct flex_array *fa;
250 312
251 comdatum = datum; 313 comdatum = datum;
252 p = datap; 314 p = datap;
253 if (!comdatum->value || comdatum->value > p->p_commons.nprim) 315 if (!comdatum->value || comdatum->value > p->p_commons.nprim)
254 return -EINVAL; 316 return -EINVAL;
255 p->p_common_val_to_name[comdatum->value - 1] = key; 317
318 fa = p->sym_val_to_name[SYM_COMMONS];
319 if (flex_array_put_ptr(fa, comdatum->value - 1, key,
320 GFP_KERNEL | __GFP_ZERO))
321 BUG();
256 return 0; 322 return 0;
257} 323}
258 324
@@ -260,12 +326,16 @@ static int class_index(void *key, void *datum, void *datap)
260{ 326{
261 struct policydb *p; 327 struct policydb *p;
262 struct class_datum *cladatum; 328 struct class_datum *cladatum;
329 struct flex_array *fa;
263 330
264 cladatum = datum; 331 cladatum = datum;
265 p = datap; 332 p = datap;
266 if (!cladatum->value || cladatum->value > p->p_classes.nprim) 333 if (!cladatum->value || cladatum->value > p->p_classes.nprim)
267 return -EINVAL; 334 return -EINVAL;
268 p->p_class_val_to_name[cladatum->value - 1] = key; 335 fa = p->sym_val_to_name[SYM_CLASSES];
336 if (flex_array_put_ptr(fa, cladatum->value - 1, key,
337 GFP_KERNEL | __GFP_ZERO))
338 BUG();
269 p->class_val_to_struct[cladatum->value - 1] = cladatum; 339 p->class_val_to_struct[cladatum->value - 1] = cladatum;
270 return 0; 340 return 0;
271} 341}
@@ -274,6 +344,7 @@ static int role_index(void *key, void *datum, void *datap)
274{ 344{
275 struct policydb *p; 345 struct policydb *p;
276 struct role_datum *role; 346 struct role_datum *role;
347 struct flex_array *fa;
277 348
278 role = datum; 349 role = datum;
279 p = datap; 350 p = datap;
@@ -281,7 +352,11 @@ static int role_index(void *key, void *datum, void *datap)
281 || role->value > p->p_roles.nprim 352 || role->value > p->p_roles.nprim
282 || role->bounds > p->p_roles.nprim) 353 || role->bounds > p->p_roles.nprim)
283 return -EINVAL; 354 return -EINVAL;
284 p->p_role_val_to_name[role->value - 1] = key; 355
356 fa = p->sym_val_to_name[SYM_ROLES];
357 if (flex_array_put_ptr(fa, role->value - 1, key,
358 GFP_KERNEL | __GFP_ZERO))
359 BUG();
285 p->role_val_to_struct[role->value - 1] = role; 360 p->role_val_to_struct[role->value - 1] = role;
286 return 0; 361 return 0;
287} 362}
@@ -290,6 +365,7 @@ static int type_index(void *key, void *datum, void *datap)
290{ 365{
291 struct policydb *p; 366 struct policydb *p;
292 struct type_datum *typdatum; 367 struct type_datum *typdatum;
368 struct flex_array *fa;
293 369
294 typdatum = datum; 370 typdatum = datum;
295 p = datap; 371 p = datap;
@@ -299,8 +375,15 @@ static int type_index(void *key, void *datum, void *datap)
299 || typdatum->value > p->p_types.nprim 375 || typdatum->value > p->p_types.nprim
300 || typdatum->bounds > p->p_types.nprim) 376 || typdatum->bounds > p->p_types.nprim)
301 return -EINVAL; 377 return -EINVAL;
302 p->p_type_val_to_name[typdatum->value - 1] = key; 378 fa = p->sym_val_to_name[SYM_TYPES];
303 p->type_val_to_struct[typdatum->value - 1] = typdatum; 379 if (flex_array_put_ptr(fa, typdatum->value - 1, key,
380 GFP_KERNEL | __GFP_ZERO))
381 BUG();
382
383 fa = p->type_val_to_struct_array;
384 if (flex_array_put_ptr(fa, typdatum->value - 1, typdatum,
385 GFP_KERNEL | __GFP_ZERO))
386 BUG();
304 } 387 }
305 388
306 return 0; 389 return 0;
@@ -310,6 +393,7 @@ static int user_index(void *key, void *datum, void *datap)
310{ 393{
311 struct policydb *p; 394 struct policydb *p;
312 struct user_datum *usrdatum; 395 struct user_datum *usrdatum;
396 struct flex_array *fa;
313 397
314 usrdatum = datum; 398 usrdatum = datum;
315 p = datap; 399 p = datap;
@@ -317,7 +401,11 @@ static int user_index(void *key, void *datum, void *datap)
317 || usrdatum->value > p->p_users.nprim 401 || usrdatum->value > p->p_users.nprim
318 || usrdatum->bounds > p->p_users.nprim) 402 || usrdatum->bounds > p->p_users.nprim)
319 return -EINVAL; 403 return -EINVAL;
320 p->p_user_val_to_name[usrdatum->value - 1] = key; 404
405 fa = p->sym_val_to_name[SYM_USERS];
406 if (flex_array_put_ptr(fa, usrdatum->value - 1, key,
407 GFP_KERNEL | __GFP_ZERO))
408 BUG();
321 p->user_val_to_struct[usrdatum->value - 1] = usrdatum; 409 p->user_val_to_struct[usrdatum->value - 1] = usrdatum;
322 return 0; 410 return 0;
323} 411}
@@ -326,6 +414,7 @@ static int sens_index(void *key, void *datum, void *datap)
326{ 414{
327 struct policydb *p; 415 struct policydb *p;
328 struct level_datum *levdatum; 416 struct level_datum *levdatum;
417 struct flex_array *fa;
329 418
330 levdatum = datum; 419 levdatum = datum;
331 p = datap; 420 p = datap;
@@ -334,7 +423,10 @@ static int sens_index(void *key, void *datum, void *datap)
334 if (!levdatum->level->sens || 423 if (!levdatum->level->sens ||
335 levdatum->level->sens > p->p_levels.nprim) 424 levdatum->level->sens > p->p_levels.nprim)
336 return -EINVAL; 425 return -EINVAL;
337 p->p_sens_val_to_name[levdatum->level->sens - 1] = key; 426 fa = p->sym_val_to_name[SYM_LEVELS];
427 if (flex_array_put_ptr(fa, levdatum->level->sens - 1, key,
428 GFP_KERNEL | __GFP_ZERO))
429 BUG();
338 } 430 }
339 431
340 return 0; 432 return 0;
@@ -344,6 +436,7 @@ static int cat_index(void *key, void *datum, void *datap)
344{ 436{
345 struct policydb *p; 437 struct policydb *p;
346 struct cat_datum *catdatum; 438 struct cat_datum *catdatum;
439 struct flex_array *fa;
347 440
348 catdatum = datum; 441 catdatum = datum;
349 p = datap; 442 p = datap;
@@ -351,7 +444,10 @@ static int cat_index(void *key, void *datum, void *datap)
351 if (!catdatum->isalias) { 444 if (!catdatum->isalias) {
352 if (!catdatum->value || catdatum->value > p->p_cats.nprim) 445 if (!catdatum->value || catdatum->value > p->p_cats.nprim)
353 return -EINVAL; 446 return -EINVAL;
354 p->p_cat_val_to_name[catdatum->value - 1] = key; 447 fa = p->sym_val_to_name[SYM_CATS];
448 if (flex_array_put_ptr(fa, catdatum->value - 1, key,
449 GFP_KERNEL | __GFP_ZERO))
450 BUG();
355 } 451 }
356 452
357 return 0; 453 return 0;
@@ -369,74 +465,27 @@ static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) =
369 cat_index, 465 cat_index,
370}; 466};
371 467
372/* 468#ifdef DEBUG_HASHES
373 * Define the common val_to_name array and the class 469static void hash_eval(struct hashtab *h, const char *hash_name)
374 * val_to_name and val_to_struct arrays in a policy
375 * database structure.
376 *
377 * Caller must clean up upon failure.
378 */
379static int policydb_index_classes(struct policydb *p)
380{ 470{
381 int rc; 471 struct hashtab_info info;
382
383 p->p_common_val_to_name =
384 kmalloc(p->p_commons.nprim * sizeof(char *), GFP_KERNEL);
385 if (!p->p_common_val_to_name) {
386 rc = -ENOMEM;
387 goto out;
388 }
389
390 rc = hashtab_map(p->p_commons.table, common_index, p);
391 if (rc)
392 goto out;
393
394 p->class_val_to_struct =
395 kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)), GFP_KERNEL);
396 if (!p->class_val_to_struct) {
397 rc = -ENOMEM;
398 goto out;
399 }
400
401 p->p_class_val_to_name =
402 kmalloc(p->p_classes.nprim * sizeof(char *), GFP_KERNEL);
403 if (!p->p_class_val_to_name) {
404 rc = -ENOMEM;
405 goto out;
406 }
407 472
408 rc = hashtab_map(p->p_classes.table, class_index, p); 473 hashtab_stat(h, &info);
409out: 474 printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, "
410 return rc; 475 "longest chain length %d\n", hash_name, h->nel,
476 info.slots_used, h->size, info.max_chain_len);
411} 477}
412 478
413#ifdef DEBUG_HASHES
414static void symtab_hash_eval(struct symtab *s) 479static void symtab_hash_eval(struct symtab *s)
415{ 480{
416 int i; 481 int i;
417 482
418 for (i = 0; i < SYM_NUM; i++) { 483 for (i = 0; i < SYM_NUM; i++)
419 struct hashtab *h = s[i].table; 484 hash_eval(s[i].table, symtab_name[i]);
420 struct hashtab_info info;
421
422 hashtab_stat(h, &info);
423 printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, "
424 "longest chain length %d\n", symtab_name[i], h->nel,
425 info.slots_used, h->size, info.max_chain_len);
426 }
427} 485}
428 486
429static void rangetr_hash_eval(struct hashtab *h)
430{
431 struct hashtab_info info;
432
433 hashtab_stat(h, &info);
434 printk(KERN_DEBUG "SELinux: rangetr: %d entries and %d/%d buckets used, "
435 "longest chain length %d\n", h->nel,
436 info.slots_used, h->size, info.max_chain_len);
437}
438#else 487#else
439static inline void rangetr_hash_eval(struct hashtab *h) 488static inline void hash_eval(struct hashtab *h, char *hash_name)
440{ 489{
441} 490}
442#endif 491#endif
@@ -447,9 +496,9 @@ static inline void rangetr_hash_eval(struct hashtab *h)
447 * 496 *
448 * Caller must clean up on failure. 497 * Caller must clean up on failure.
449 */ 498 */
450static int policydb_index_others(struct policydb *p) 499static int policydb_index(struct policydb *p)
451{ 500{
452 int i, rc = 0; 501 int i, rc;
453 502
454 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools", 503 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools",
455 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); 504 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
@@ -466,47 +515,63 @@ static int policydb_index_others(struct policydb *p)
466 symtab_hash_eval(p->symtab); 515 symtab_hash_eval(p->symtab);
467#endif 516#endif
468 517
518 rc = -ENOMEM;
519 p->class_val_to_struct =
520 kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)),
521 GFP_KERNEL);
522 if (!p->class_val_to_struct)
523 goto out;
524
525 rc = -ENOMEM;
469 p->role_val_to_struct = 526 p->role_val_to_struct =
470 kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)), 527 kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)),
471 GFP_KERNEL); 528 GFP_KERNEL);
472 if (!p->role_val_to_struct) { 529 if (!p->role_val_to_struct)
473 rc = -ENOMEM;
474 goto out; 530 goto out;
475 }
476 531
532 rc = -ENOMEM;
477 p->user_val_to_struct = 533 p->user_val_to_struct =
478 kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)), 534 kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)),
479 GFP_KERNEL); 535 GFP_KERNEL);
480 if (!p->user_val_to_struct) { 536 if (!p->user_val_to_struct)
481 rc = -ENOMEM;
482 goto out; 537 goto out;
483 }
484 538
485 p->type_val_to_struct = 539 /* Yes, I want the sizeof the pointer, not the structure */
486 kmalloc(p->p_types.nprim * sizeof(*(p->type_val_to_struct)), 540 rc = -ENOMEM;
487 GFP_KERNEL); 541 p->type_val_to_struct_array = flex_array_alloc(sizeof(struct type_datum *),
488 if (!p->type_val_to_struct) { 542 p->p_types.nprim,
489 rc = -ENOMEM; 543 GFP_KERNEL | __GFP_ZERO);
544 if (!p->type_val_to_struct_array)
490 goto out; 545 goto out;
491 }
492 546
493 if (cond_init_bool_indexes(p)) { 547 rc = flex_array_prealloc(p->type_val_to_struct_array, 0,
494 rc = -ENOMEM; 548 p->p_types.nprim, GFP_KERNEL | __GFP_ZERO);
549 if (rc)
495 goto out; 550 goto out;
496 }
497 551
498 for (i = SYM_ROLES; i < SYM_NUM; i++) { 552 rc = cond_init_bool_indexes(p);
499 p->sym_val_to_name[i] = 553 if (rc)
500 kmalloc(p->symtab[i].nprim * sizeof(char *), GFP_KERNEL); 554 goto out;
501 if (!p->sym_val_to_name[i]) { 555
502 rc = -ENOMEM; 556 for (i = 0; i < SYM_NUM; i++) {
557 rc = -ENOMEM;
558 p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *),
559 p->symtab[i].nprim,
560 GFP_KERNEL | __GFP_ZERO);
561 if (!p->sym_val_to_name[i])
503 goto out; 562 goto out;
504 } 563
564 rc = flex_array_prealloc(p->sym_val_to_name[i],
565 0, p->symtab[i].nprim,
566 GFP_KERNEL | __GFP_ZERO);
567 if (rc)
568 goto out;
569
505 rc = hashtab_map(p->symtab[i].table, index_f[i], p); 570 rc = hashtab_map(p->symtab[i].table, index_f[i], p);
506 if (rc) 571 if (rc)
507 goto out; 572 goto out;
508 } 573 }
509 574 rc = 0;
510out: 575out:
511 return rc; 576 return rc;
512} 577}
@@ -529,9 +594,11 @@ static int common_destroy(void *key, void *datum, void *p)
529 struct common_datum *comdatum; 594 struct common_datum *comdatum;
530 595
531 kfree(key); 596 kfree(key);
532 comdatum = datum; 597 if (datum) {
533 hashtab_map(comdatum->permissions.table, perm_destroy, NULL); 598 comdatum = datum;
534 hashtab_destroy(comdatum->permissions.table); 599 hashtab_map(comdatum->permissions.table, perm_destroy, NULL);
600 hashtab_destroy(comdatum->permissions.table);
601 }
535 kfree(datum); 602 kfree(datum);
536 return 0; 603 return 0;
537} 604}
@@ -543,38 +610,40 @@ static int cls_destroy(void *key, void *datum, void *p)
543 struct constraint_expr *e, *etmp; 610 struct constraint_expr *e, *etmp;
544 611
545 kfree(key); 612 kfree(key);
546 cladatum = datum; 613 if (datum) {
547 hashtab_map(cladatum->permissions.table, perm_destroy, NULL); 614 cladatum = datum;
548 hashtab_destroy(cladatum->permissions.table); 615 hashtab_map(cladatum->permissions.table, perm_destroy, NULL);
549 constraint = cladatum->constraints; 616 hashtab_destroy(cladatum->permissions.table);
550 while (constraint) { 617 constraint = cladatum->constraints;
551 e = constraint->expr; 618 while (constraint) {
552 while (e) { 619 e = constraint->expr;
553 ebitmap_destroy(&e->names); 620 while (e) {
554 etmp = e; 621 ebitmap_destroy(&e->names);
555 e = e->next; 622 etmp = e;
556 kfree(etmp); 623 e = e->next;
624 kfree(etmp);
625 }
626 ctemp = constraint;
627 constraint = constraint->next;
628 kfree(ctemp);
557 } 629 }
558 ctemp = constraint; 630
559 constraint = constraint->next; 631 constraint = cladatum->validatetrans;
560 kfree(ctemp); 632 while (constraint) {
561 } 633 e = constraint->expr;
562 634 while (e) {
563 constraint = cladatum->validatetrans; 635 ebitmap_destroy(&e->names);
564 while (constraint) { 636 etmp = e;
565 e = constraint->expr; 637 e = e->next;
566 while (e) { 638 kfree(etmp);
567 ebitmap_destroy(&e->names); 639 }
568 etmp = e; 640 ctemp = constraint;
569 e = e->next; 641 constraint = constraint->next;
570 kfree(etmp); 642 kfree(ctemp);
571 } 643 }
572 ctemp = constraint;
573 constraint = constraint->next;
574 kfree(ctemp);
575 }
576 644
577 kfree(cladatum->comkey); 645 kfree(cladatum->comkey);
646 }
578 kfree(datum); 647 kfree(datum);
579 return 0; 648 return 0;
580} 649}
@@ -584,9 +653,11 @@ static int role_destroy(void *key, void *datum, void *p)
584 struct role_datum *role; 653 struct role_datum *role;
585 654
586 kfree(key); 655 kfree(key);
587 role = datum; 656 if (datum) {
588 ebitmap_destroy(&role->dominates); 657 role = datum;
589 ebitmap_destroy(&role->types); 658 ebitmap_destroy(&role->dominates);
659 ebitmap_destroy(&role->types);
660 }
590 kfree(datum); 661 kfree(datum);
591 return 0; 662 return 0;
592} 663}
@@ -603,11 +674,13 @@ static int user_destroy(void *key, void *datum, void *p)
603 struct user_datum *usrdatum; 674 struct user_datum *usrdatum;
604 675
605 kfree(key); 676 kfree(key);
606 usrdatum = datum; 677 if (datum) {
607 ebitmap_destroy(&usrdatum->roles); 678 usrdatum = datum;
608 ebitmap_destroy(&usrdatum->range.level[0].cat); 679 ebitmap_destroy(&usrdatum->roles);
609 ebitmap_destroy(&usrdatum->range.level[1].cat); 680 ebitmap_destroy(&usrdatum->range.level[0].cat);
610 ebitmap_destroy(&usrdatum->dfltlevel.cat); 681 ebitmap_destroy(&usrdatum->range.level[1].cat);
682 ebitmap_destroy(&usrdatum->dfltlevel.cat);
683 }
611 kfree(datum); 684 kfree(datum);
612 return 0; 685 return 0;
613} 686}
@@ -617,9 +690,11 @@ static int sens_destroy(void *key, void *datum, void *p)
617 struct level_datum *levdatum; 690 struct level_datum *levdatum;
618 691
619 kfree(key); 692 kfree(key);
620 levdatum = datum; 693 if (datum) {
621 ebitmap_destroy(&levdatum->level->cat); 694 levdatum = datum;
622 kfree(levdatum->level); 695 ebitmap_destroy(&levdatum->level->cat);
696 kfree(levdatum->level);
697 }
623 kfree(datum); 698 kfree(datum);
624 return 0; 699 return 0;
625} 700}
@@ -643,6 +718,16 @@ static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) =
643 cat_destroy, 718 cat_destroy,
644}; 719};
645 720
721static int filenametr_destroy(void *key, void *datum, void *p)
722{
723 struct filename_trans *ft = key;
724 kfree(ft->name);
725 kfree(key);
726 kfree(datum);
727 cond_resched();
728 return 0;
729}
730
646static int range_tr_destroy(void *key, void *datum, void *p) 731static int range_tr_destroy(void *key, void *datum, void *p)
647{ 732{
648 struct mls_range *rt = datum; 733 struct mls_range *rt = datum;
@@ -684,13 +769,16 @@ void policydb_destroy(struct policydb *p)
684 hashtab_destroy(p->symtab[i].table); 769 hashtab_destroy(p->symtab[i].table);
685 } 770 }
686 771
687 for (i = 0; i < SYM_NUM; i++) 772 for (i = 0; i < SYM_NUM; i++) {
688 kfree(p->sym_val_to_name[i]); 773 if (p->sym_val_to_name[i])
774 flex_array_free(p->sym_val_to_name[i]);
775 }
689 776
690 kfree(p->class_val_to_struct); 777 kfree(p->class_val_to_struct);
691 kfree(p->role_val_to_struct); 778 kfree(p->role_val_to_struct);
692 kfree(p->user_val_to_struct); 779 kfree(p->user_val_to_struct);
693 kfree(p->type_val_to_struct); 780 if (p->type_val_to_struct_array)
781 flex_array_free(p->type_val_to_struct_array);
694 782
695 avtab_destroy(&p->te_avtab); 783 avtab_destroy(&p->te_avtab);
696 784
@@ -737,6 +825,9 @@ void policydb_destroy(struct policydb *p)
737 } 825 }
738 kfree(lra); 826 kfree(lra);
739 827
828 hashtab_map(p->filename_trans, filenametr_destroy, NULL);
829 hashtab_destroy(p->filename_trans);
830
740 hashtab_map(p->range_tr, range_tr_destroy, NULL); 831 hashtab_map(p->range_tr, range_tr_destroy, NULL);
741 hashtab_destroy(p->range_tr); 832 hashtab_destroy(p->range_tr);
742 833
@@ -751,6 +842,8 @@ void policydb_destroy(struct policydb *p)
751 } 842 }
752 flex_array_free(p->type_attr_map_array); 843 flex_array_free(p->type_attr_map_array);
753 } 844 }
845
846 ebitmap_destroy(&p->filename_trans_ttypes);
754 ebitmap_destroy(&p->policycaps); 847 ebitmap_destroy(&p->policycaps);
755 ebitmap_destroy(&p->permissive_map); 848 ebitmap_destroy(&p->permissive_map);
756 849
@@ -774,19 +867,21 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s)
774 867
775 head = p->ocontexts[OCON_ISID]; 868 head = p->ocontexts[OCON_ISID];
776 for (c = head; c; c = c->next) { 869 for (c = head; c; c = c->next) {
870 rc = -EINVAL;
777 if (!c->context[0].user) { 871 if (!c->context[0].user) {
778 printk(KERN_ERR "SELinux: SID %s was never " 872 printk(KERN_ERR "SELinux: SID %s was never defined.\n",
779 "defined.\n", c->u.name); 873 c->u.name);
780 rc = -EINVAL;
781 goto out; 874 goto out;
782 } 875 }
783 if (sidtab_insert(s, c->sid[0], &c->context[0])) { 876
784 printk(KERN_ERR "SELinux: unable to load initial " 877 rc = sidtab_insert(s, c->sid[0], &c->context[0]);
785 "SID %s.\n", c->u.name); 878 if (rc) {
786 rc = -EINVAL; 879 printk(KERN_ERR "SELinux: unable to load initial SID %s.\n",
880 c->u.name);
787 goto out; 881 goto out;
788 } 882 }
789 } 883 }
884 rc = 0;
790out: 885out:
791 return rc; 886 return rc;
792} 887}
@@ -835,8 +930,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
835 * Role must be authorized for the type. 930 * Role must be authorized for the type.
836 */ 931 */
837 role = p->role_val_to_struct[c->role - 1]; 932 role = p->role_val_to_struct[c->role - 1];
838 if (!ebitmap_get_bit(&role->types, 933 if (!ebitmap_get_bit(&role->types, c->type - 1))
839 c->type - 1))
840 /* role may not be associated with type */ 934 /* role may not be associated with type */
841 return 0; 935 return 0;
842 936
@@ -847,8 +941,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
847 if (!usrdatum) 941 if (!usrdatum)
848 return 0; 942 return 0;
849 943
850 if (!ebitmap_get_bit(&usrdatum->roles, 944 if (!ebitmap_get_bit(&usrdatum->roles, c->role - 1))
851 c->role - 1))
852 /* user may not be associated with role */ 945 /* user may not be associated with role */
853 return 0; 946 return 0;
854 } 947 }
@@ -870,20 +963,22 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
870 int rc; 963 int rc;
871 964
872 rc = next_entry(buf, fp, sizeof(u32)); 965 rc = next_entry(buf, fp, sizeof(u32));
873 if (rc < 0) 966 if (rc)
874 goto out; 967 goto out;
875 968
969 rc = -EINVAL;
876 items = le32_to_cpu(buf[0]); 970 items = le32_to_cpu(buf[0]);
877 if (items > ARRAY_SIZE(buf)) { 971 if (items > ARRAY_SIZE(buf)) {
878 printk(KERN_ERR "SELinux: mls: range overflow\n"); 972 printk(KERN_ERR "SELinux: mls: range overflow\n");
879 rc = -EINVAL;
880 goto out; 973 goto out;
881 } 974 }
975
882 rc = next_entry(buf, fp, sizeof(u32) * items); 976 rc = next_entry(buf, fp, sizeof(u32) * items);
883 if (rc < 0) { 977 if (rc) {
884 printk(KERN_ERR "SELinux: mls: truncated range\n"); 978 printk(KERN_ERR "SELinux: mls: truncated range\n");
885 goto out; 979 goto out;
886 } 980 }
981
887 r->level[0].sens = le32_to_cpu(buf[0]); 982 r->level[0].sens = le32_to_cpu(buf[0]);
888 if (items > 1) 983 if (items > 1)
889 r->level[1].sens = le32_to_cpu(buf[1]); 984 r->level[1].sens = le32_to_cpu(buf[1]);
@@ -892,15 +987,13 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
892 987
893 rc = ebitmap_read(&r->level[0].cat, fp); 988 rc = ebitmap_read(&r->level[0].cat, fp);
894 if (rc) { 989 if (rc) {
895 printk(KERN_ERR "SELinux: mls: error reading low " 990 printk(KERN_ERR "SELinux: mls: error reading low categories\n");
896 "categories\n");
897 goto out; 991 goto out;
898 } 992 }
899 if (items > 1) { 993 if (items > 1) {
900 rc = ebitmap_read(&r->level[1].cat, fp); 994 rc = ebitmap_read(&r->level[1].cat, fp);
901 if (rc) { 995 if (rc) {
902 printk(KERN_ERR "SELinux: mls: error reading high " 996 printk(KERN_ERR "SELinux: mls: error reading high categories\n");
903 "categories\n");
904 goto bad_high; 997 goto bad_high;
905 } 998 }
906 } else { 999 } else {
@@ -911,12 +1004,11 @@ static int mls_read_range_helper(struct mls_range *r, void *fp)
911 } 1004 }
912 } 1005 }
913 1006
914 rc = 0; 1007 return 0;
915out:
916 return rc;
917bad_high: 1008bad_high:
918 ebitmap_destroy(&r->level[0].cat); 1009 ebitmap_destroy(&r->level[0].cat);
919 goto out; 1010out:
1011 return rc;
920} 1012}
921 1013
922/* 1014/*
@@ -931,7 +1023,7 @@ static int context_read_and_validate(struct context *c,
931 int rc; 1023 int rc;
932 1024
933 rc = next_entry(buf, fp, sizeof buf); 1025 rc = next_entry(buf, fp, sizeof buf);
934 if (rc < 0) { 1026 if (rc) {
935 printk(KERN_ERR "SELinux: context truncated\n"); 1027 printk(KERN_ERR "SELinux: context truncated\n");
936 goto out; 1028 goto out;
937 } 1029 }
@@ -939,19 +1031,20 @@ static int context_read_and_validate(struct context *c,
939 c->role = le32_to_cpu(buf[1]); 1031 c->role = le32_to_cpu(buf[1]);
940 c->type = le32_to_cpu(buf[2]); 1032 c->type = le32_to_cpu(buf[2]);
941 if (p->policyvers >= POLICYDB_VERSION_MLS) { 1033 if (p->policyvers >= POLICYDB_VERSION_MLS) {
942 if (mls_read_range_helper(&c->range, fp)) { 1034 rc = mls_read_range_helper(&c->range, fp);
943 printk(KERN_ERR "SELinux: error reading MLS range of " 1035 if (rc) {
944 "context\n"); 1036 printk(KERN_ERR "SELinux: error reading MLS range of context\n");
945 rc = -EINVAL;
946 goto out; 1037 goto out;
947 } 1038 }
948 } 1039 }
949 1040
1041 rc = -EINVAL;
950 if (!policydb_context_isvalid(p, c)) { 1042 if (!policydb_context_isvalid(p, c)) {
951 printk(KERN_ERR "SELinux: invalid security context\n"); 1043 printk(KERN_ERR "SELinux: invalid security context\n");
952 context_destroy(c); 1044 context_destroy(c);
953 rc = -EINVAL; 1045 goto out;
954 } 1046 }
1047 rc = 0;
955out: 1048out:
956 return rc; 1049 return rc;
957} 1050}
@@ -970,37 +1063,36 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
970 __le32 buf[2]; 1063 __le32 buf[2];
971 u32 len; 1064 u32 len;
972 1065
1066 rc = -ENOMEM;
973 perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL); 1067 perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL);
974 if (!perdatum) { 1068 if (!perdatum)
975 rc = -ENOMEM; 1069 goto bad;
976 goto out;
977 }
978 1070
979 rc = next_entry(buf, fp, sizeof buf); 1071 rc = next_entry(buf, fp, sizeof buf);
980 if (rc < 0) 1072 if (rc)
981 goto bad; 1073 goto bad;
982 1074
983 len = le32_to_cpu(buf[0]); 1075 len = le32_to_cpu(buf[0]);
984 perdatum->value = le32_to_cpu(buf[1]); 1076 perdatum->value = le32_to_cpu(buf[1]);
985 1077
1078 rc = -ENOMEM;
986 key = kmalloc(len + 1, GFP_KERNEL); 1079 key = kmalloc(len + 1, GFP_KERNEL);
987 if (!key) { 1080 if (!key)
988 rc = -ENOMEM;
989 goto bad; 1081 goto bad;
990 } 1082
991 rc = next_entry(key, fp, len); 1083 rc = next_entry(key, fp, len);
992 if (rc < 0) 1084 if (rc)
993 goto bad; 1085 goto bad;
994 key[len] = '\0'; 1086 key[len] = '\0';
995 1087
996 rc = hashtab_insert(h, key, perdatum); 1088 rc = hashtab_insert(h, key, perdatum);
997 if (rc) 1089 if (rc)
998 goto bad; 1090 goto bad;
999out: 1091
1000 return rc; 1092 return 0;
1001bad: 1093bad:
1002 perm_destroy(key, perdatum, NULL); 1094 perm_destroy(key, perdatum, NULL);
1003 goto out; 1095 return rc;
1004} 1096}
1005 1097
1006static int common_read(struct policydb *p, struct hashtab *h, void *fp) 1098static int common_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1011,14 +1103,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1011 u32 len, nel; 1103 u32 len, nel;
1012 int i, rc; 1104 int i, rc;
1013 1105
1106 rc = -ENOMEM;
1014 comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL); 1107 comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL);
1015 if (!comdatum) { 1108 if (!comdatum)
1016 rc = -ENOMEM; 1109 goto bad;
1017 goto out;
1018 }
1019 1110
1020 rc = next_entry(buf, fp, sizeof buf); 1111 rc = next_entry(buf, fp, sizeof buf);
1021 if (rc < 0) 1112 if (rc)
1022 goto bad; 1113 goto bad;
1023 1114
1024 len = le32_to_cpu(buf[0]); 1115 len = le32_to_cpu(buf[0]);
@@ -1030,13 +1121,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1030 comdatum->permissions.nprim = le32_to_cpu(buf[2]); 1121 comdatum->permissions.nprim = le32_to_cpu(buf[2]);
1031 nel = le32_to_cpu(buf[3]); 1122 nel = le32_to_cpu(buf[3]);
1032 1123
1124 rc = -ENOMEM;
1033 key = kmalloc(len + 1, GFP_KERNEL); 1125 key = kmalloc(len + 1, GFP_KERNEL);
1034 if (!key) { 1126 if (!key)
1035 rc = -ENOMEM;
1036 goto bad; 1127 goto bad;
1037 } 1128
1038 rc = next_entry(key, fp, len); 1129 rc = next_entry(key, fp, len);
1039 if (rc < 0) 1130 if (rc)
1040 goto bad; 1131 goto bad;
1041 key[len] = '\0'; 1132 key[len] = '\0';
1042 1133
@@ -1049,11 +1140,10 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
1049 rc = hashtab_insert(h, key, comdatum); 1140 rc = hashtab_insert(h, key, comdatum);
1050 if (rc) 1141 if (rc)
1051 goto bad; 1142 goto bad;
1052out: 1143 return 0;
1053 return rc;
1054bad: 1144bad:
1055 common_destroy(key, comdatum, NULL); 1145 common_destroy(key, comdatum, NULL);
1056 goto out; 1146 return rc;
1057} 1147}
1058 1148
1059static int read_cons_helper(struct constraint_node **nodep, int ncons, 1149static int read_cons_helper(struct constraint_node **nodep, int ncons,
@@ -1077,7 +1167,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1077 *nodep = c; 1167 *nodep = c;
1078 1168
1079 rc = next_entry(buf, fp, (sizeof(u32) * 2)); 1169 rc = next_entry(buf, fp, (sizeof(u32) * 2));
1080 if (rc < 0) 1170 if (rc)
1081 return rc; 1171 return rc;
1082 c->permissions = le32_to_cpu(buf[0]); 1172 c->permissions = le32_to_cpu(buf[0]);
1083 nexpr = le32_to_cpu(buf[1]); 1173 nexpr = le32_to_cpu(buf[1]);
@@ -1094,7 +1184,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1094 c->expr = e; 1184 c->expr = e;
1095 1185
1096 rc = next_entry(buf, fp, (sizeof(u32) * 3)); 1186 rc = next_entry(buf, fp, (sizeof(u32) * 3));
1097 if (rc < 0) 1187 if (rc)
1098 return rc; 1188 return rc;
1099 e->expr_type = le32_to_cpu(buf[0]); 1189 e->expr_type = le32_to_cpu(buf[0]);
1100 e->attr = le32_to_cpu(buf[1]); 1190 e->attr = le32_to_cpu(buf[1]);
@@ -1122,8 +1212,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
1122 if (depth == (CEXPR_MAXDEPTH - 1)) 1212 if (depth == (CEXPR_MAXDEPTH - 1))
1123 return -EINVAL; 1213 return -EINVAL;
1124 depth++; 1214 depth++;
1125 if (ebitmap_read(&e->names, fp)) 1215 rc = ebitmap_read(&e->names, fp);
1126 return -EINVAL; 1216 if (rc)
1217 return rc;
1127 break; 1218 break;
1128 default: 1219 default:
1129 return -EINVAL; 1220 return -EINVAL;
@@ -1146,14 +1237,13 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1146 u32 len, len2, ncons, nel; 1237 u32 len, len2, ncons, nel;
1147 int i, rc; 1238 int i, rc;
1148 1239
1240 rc = -ENOMEM;
1149 cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL); 1241 cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL);
1150 if (!cladatum) { 1242 if (!cladatum)
1151 rc = -ENOMEM; 1243 goto bad;
1152 goto out;
1153 }
1154 1244
1155 rc = next_entry(buf, fp, sizeof(u32)*6); 1245 rc = next_entry(buf, fp, sizeof(u32)*6);
1156 if (rc < 0) 1246 if (rc)
1157 goto bad; 1247 goto bad;
1158 1248
1159 len = le32_to_cpu(buf[0]); 1249 len = le32_to_cpu(buf[0]);
@@ -1168,33 +1258,30 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1168 1258
1169 ncons = le32_to_cpu(buf[5]); 1259 ncons = le32_to_cpu(buf[5]);
1170 1260
1261 rc = -ENOMEM;
1171 key = kmalloc(len + 1, GFP_KERNEL); 1262 key = kmalloc(len + 1, GFP_KERNEL);
1172 if (!key) { 1263 if (!key)
1173 rc = -ENOMEM;
1174 goto bad; 1264 goto bad;
1175 } 1265
1176 rc = next_entry(key, fp, len); 1266 rc = next_entry(key, fp, len);
1177 if (rc < 0) 1267 if (rc)
1178 goto bad; 1268 goto bad;
1179 key[len] = '\0'; 1269 key[len] = '\0';
1180 1270
1181 if (len2) { 1271 if (len2) {
1272 rc = -ENOMEM;
1182 cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL); 1273 cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL);
1183 if (!cladatum->comkey) { 1274 if (!cladatum->comkey)
1184 rc = -ENOMEM;
1185 goto bad; 1275 goto bad;
1186 }
1187 rc = next_entry(cladatum->comkey, fp, len2); 1276 rc = next_entry(cladatum->comkey, fp, len2);
1188 if (rc < 0) 1277 if (rc)
1189 goto bad; 1278 goto bad;
1190 cladatum->comkey[len2] = '\0'; 1279 cladatum->comkey[len2] = '\0';
1191 1280
1192 cladatum->comdatum = hashtab_search(p->p_commons.table, 1281 rc = -EINVAL;
1193 cladatum->comkey); 1282 cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey);
1194 if (!cladatum->comdatum) { 1283 if (!cladatum->comdatum) {
1195 printk(KERN_ERR "SELinux: unknown common %s\n", 1284 printk(KERN_ERR "SELinux: unknown common %s\n", cladatum->comkey);
1196 cladatum->comkey);
1197 rc = -EINVAL;
1198 goto bad; 1285 goto bad;
1199 } 1286 }
1200 } 1287 }
@@ -1211,7 +1298,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1211 if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) { 1298 if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) {
1212 /* grab the validatetrans rules */ 1299 /* grab the validatetrans rules */
1213 rc = next_entry(buf, fp, sizeof(u32)); 1300 rc = next_entry(buf, fp, sizeof(u32));
1214 if (rc < 0) 1301 if (rc)
1215 goto bad; 1302 goto bad;
1216 ncons = le32_to_cpu(buf[0]); 1303 ncons = le32_to_cpu(buf[0]);
1217 rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp); 1304 rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp);
@@ -1223,12 +1310,10 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1223 if (rc) 1310 if (rc)
1224 goto bad; 1311 goto bad;
1225 1312
1226 rc = 0; 1313 return 0;
1227out:
1228 return rc;
1229bad: 1314bad:
1230 cls_destroy(key, cladatum, NULL); 1315 cls_destroy(key, cladatum, NULL);
1231 goto out; 1316 return rc;
1232} 1317}
1233 1318
1234static int role_read(struct policydb *p, struct hashtab *h, void *fp) 1319static int role_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1239,17 +1324,16 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1239 __le32 buf[3]; 1324 __le32 buf[3];
1240 u32 len; 1325 u32 len;
1241 1326
1327 rc = -ENOMEM;
1242 role = kzalloc(sizeof(*role), GFP_KERNEL); 1328 role = kzalloc(sizeof(*role), GFP_KERNEL);
1243 if (!role) { 1329 if (!role)
1244 rc = -ENOMEM; 1330 goto bad;
1245 goto out;
1246 }
1247 1331
1248 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1332 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1249 to_read = 3; 1333 to_read = 3;
1250 1334
1251 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); 1335 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
1252 if (rc < 0) 1336 if (rc)
1253 goto bad; 1337 goto bad;
1254 1338
1255 len = le32_to_cpu(buf[0]); 1339 len = le32_to_cpu(buf[0]);
@@ -1257,13 +1341,13 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1257 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1341 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1258 role->bounds = le32_to_cpu(buf[2]); 1342 role->bounds = le32_to_cpu(buf[2]);
1259 1343
1344 rc = -ENOMEM;
1260 key = kmalloc(len + 1, GFP_KERNEL); 1345 key = kmalloc(len + 1, GFP_KERNEL);
1261 if (!key) { 1346 if (!key)
1262 rc = -ENOMEM;
1263 goto bad; 1347 goto bad;
1264 } 1348
1265 rc = next_entry(key, fp, len); 1349 rc = next_entry(key, fp, len);
1266 if (rc < 0) 1350 if (rc)
1267 goto bad; 1351 goto bad;
1268 key[len] = '\0'; 1352 key[len] = '\0';
1269 1353
@@ -1276,10 +1360,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1276 goto bad; 1360 goto bad;
1277 1361
1278 if (strcmp(key, OBJECT_R) == 0) { 1362 if (strcmp(key, OBJECT_R) == 0) {
1363 rc = -EINVAL;
1279 if (role->value != OBJECT_R_VAL) { 1364 if (role->value != OBJECT_R_VAL) {
1280 printk(KERN_ERR "SELinux: Role %s has wrong value %d\n", 1365 printk(KERN_ERR "SELinux: Role %s has wrong value %d\n",
1281 OBJECT_R, role->value); 1366 OBJECT_R, role->value);
1282 rc = -EINVAL;
1283 goto bad; 1367 goto bad;
1284 } 1368 }
1285 rc = 0; 1369 rc = 0;
@@ -1289,11 +1373,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
1289 rc = hashtab_insert(h, key, role); 1373 rc = hashtab_insert(h, key, role);
1290 if (rc) 1374 if (rc)
1291 goto bad; 1375 goto bad;
1292out: 1376 return 0;
1293 return rc;
1294bad: 1377bad:
1295 role_destroy(key, role, NULL); 1378 role_destroy(key, role, NULL);
1296 goto out; 1379 return rc;
1297} 1380}
1298 1381
1299static int type_read(struct policydb *p, struct hashtab *h, void *fp) 1382static int type_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1304,17 +1387,16 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1304 __le32 buf[4]; 1387 __le32 buf[4];
1305 u32 len; 1388 u32 len;
1306 1389
1390 rc = -ENOMEM;
1307 typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL); 1391 typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL);
1308 if (!typdatum) { 1392 if (!typdatum)
1309 rc = -ENOMEM; 1393 goto bad;
1310 return rc;
1311 }
1312 1394
1313 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1395 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1314 to_read = 4; 1396 to_read = 4;
1315 1397
1316 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); 1398 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
1317 if (rc < 0) 1399 if (rc)
1318 goto bad; 1400 goto bad;
1319 1401
1320 len = le32_to_cpu(buf[0]); 1402 len = le32_to_cpu(buf[0]);
@@ -1332,24 +1414,22 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
1332 typdatum->primary = le32_to_cpu(buf[2]); 1414 typdatum->primary = le32_to_cpu(buf[2]);
1333 } 1415 }
1334 1416
1417 rc = -ENOMEM;
1335 key = kmalloc(len + 1, GFP_KERNEL); 1418 key = kmalloc(len + 1, GFP_KERNEL);
1336 if (!key) { 1419 if (!key)
1337 rc = -ENOMEM;
1338 goto bad; 1420 goto bad;
1339 }
1340 rc = next_entry(key, fp, len); 1421 rc = next_entry(key, fp, len);
1341 if (rc < 0) 1422 if (rc)
1342 goto bad; 1423 goto bad;
1343 key[len] = '\0'; 1424 key[len] = '\0';
1344 1425
1345 rc = hashtab_insert(h, key, typdatum); 1426 rc = hashtab_insert(h, key, typdatum);
1346 if (rc) 1427 if (rc)
1347 goto bad; 1428 goto bad;
1348out: 1429 return 0;
1349 return rc;
1350bad: 1430bad:
1351 type_destroy(key, typdatum, NULL); 1431 type_destroy(key, typdatum, NULL);
1352 goto out; 1432 return rc;
1353} 1433}
1354 1434
1355 1435
@@ -1365,22 +1445,18 @@ static int mls_read_level(struct mls_level *lp, void *fp)
1365 memset(lp, 0, sizeof(*lp)); 1445 memset(lp, 0, sizeof(*lp));
1366 1446
1367 rc = next_entry(buf, fp, sizeof buf); 1447 rc = next_entry(buf, fp, sizeof buf);
1368 if (rc < 0) { 1448 if (rc) {
1369 printk(KERN_ERR "SELinux: mls: truncated level\n"); 1449 printk(KERN_ERR "SELinux: mls: truncated level\n");
1370 goto bad; 1450 return rc;
1371 } 1451 }
1372 lp->sens = le32_to_cpu(buf[0]); 1452 lp->sens = le32_to_cpu(buf[0]);
1373 1453
1374 if (ebitmap_read(&lp->cat, fp)) { 1454 rc = ebitmap_read(&lp->cat, fp);
1375 printk(KERN_ERR "SELinux: mls: error reading level " 1455 if (rc) {
1376 "categories\n"); 1456 printk(KERN_ERR "SELinux: mls: error reading level categories\n");
1377 goto bad; 1457 return rc;
1378 } 1458 }
1379
1380 return 0; 1459 return 0;
1381
1382bad:
1383 return -EINVAL;
1384} 1460}
1385 1461
1386static int user_read(struct policydb *p, struct hashtab *h, void *fp) 1462static int user_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1391,17 +1467,16 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1391 __le32 buf[3]; 1467 __le32 buf[3];
1392 u32 len; 1468 u32 len;
1393 1469
1470 rc = -ENOMEM;
1394 usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL); 1471 usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL);
1395 if (!usrdatum) { 1472 if (!usrdatum)
1396 rc = -ENOMEM; 1473 goto bad;
1397 goto out;
1398 }
1399 1474
1400 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1475 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1401 to_read = 3; 1476 to_read = 3;
1402 1477
1403 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); 1478 rc = next_entry(buf, fp, sizeof(buf[0]) * to_read);
1404 if (rc < 0) 1479 if (rc)
1405 goto bad; 1480 goto bad;
1406 1481
1407 len = le32_to_cpu(buf[0]); 1482 len = le32_to_cpu(buf[0]);
@@ -1409,13 +1484,12 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1409 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) 1484 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
1410 usrdatum->bounds = le32_to_cpu(buf[2]); 1485 usrdatum->bounds = le32_to_cpu(buf[2]);
1411 1486
1487 rc = -ENOMEM;
1412 key = kmalloc(len + 1, GFP_KERNEL); 1488 key = kmalloc(len + 1, GFP_KERNEL);
1413 if (!key) { 1489 if (!key)
1414 rc = -ENOMEM;
1415 goto bad; 1490 goto bad;
1416 }
1417 rc = next_entry(key, fp, len); 1491 rc = next_entry(key, fp, len);
1418 if (rc < 0) 1492 if (rc)
1419 goto bad; 1493 goto bad;
1420 key[len] = '\0'; 1494 key[len] = '\0';
1421 1495
@@ -1435,11 +1509,10 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
1435 rc = hashtab_insert(h, key, usrdatum); 1509 rc = hashtab_insert(h, key, usrdatum);
1436 if (rc) 1510 if (rc)
1437 goto bad; 1511 goto bad;
1438out: 1512 return 0;
1439 return rc;
1440bad: 1513bad:
1441 user_destroy(key, usrdatum, NULL); 1514 user_destroy(key, usrdatum, NULL);
1442 goto out; 1515 return rc;
1443} 1516}
1444 1517
1445static int sens_read(struct policydb *p, struct hashtab *h, void *fp) 1518static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1450,47 +1523,43 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
1450 __le32 buf[2]; 1523 __le32 buf[2];
1451 u32 len; 1524 u32 len;
1452 1525
1526 rc = -ENOMEM;
1453 levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC); 1527 levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC);
1454 if (!levdatum) { 1528 if (!levdatum)
1455 rc = -ENOMEM; 1529 goto bad;
1456 goto out;
1457 }
1458 1530
1459 rc = next_entry(buf, fp, sizeof buf); 1531 rc = next_entry(buf, fp, sizeof buf);
1460 if (rc < 0) 1532 if (rc)
1461 goto bad; 1533 goto bad;
1462 1534
1463 len = le32_to_cpu(buf[0]); 1535 len = le32_to_cpu(buf[0]);
1464 levdatum->isalias = le32_to_cpu(buf[1]); 1536 levdatum->isalias = le32_to_cpu(buf[1]);
1465 1537
1538 rc = -ENOMEM;
1466 key = kmalloc(len + 1, GFP_ATOMIC); 1539 key = kmalloc(len + 1, GFP_ATOMIC);
1467 if (!key) { 1540 if (!key)
1468 rc = -ENOMEM;
1469 goto bad; 1541 goto bad;
1470 }
1471 rc = next_entry(key, fp, len); 1542 rc = next_entry(key, fp, len);
1472 if (rc < 0) 1543 if (rc)
1473 goto bad; 1544 goto bad;
1474 key[len] = '\0'; 1545 key[len] = '\0';
1475 1546
1547 rc = -ENOMEM;
1476 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC); 1548 levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC);
1477 if (!levdatum->level) { 1549 if (!levdatum->level)
1478 rc = -ENOMEM;
1479 goto bad; 1550 goto bad;
1480 } 1551
1481 if (mls_read_level(levdatum->level, fp)) { 1552 rc = mls_read_level(levdatum->level, fp);
1482 rc = -EINVAL; 1553 if (rc)
1483 goto bad; 1554 goto bad;
1484 }
1485 1555
1486 rc = hashtab_insert(h, key, levdatum); 1556 rc = hashtab_insert(h, key, levdatum);
1487 if (rc) 1557 if (rc)
1488 goto bad; 1558 goto bad;
1489out: 1559 return 0;
1490 return rc;
1491bad: 1560bad:
1492 sens_destroy(key, levdatum, NULL); 1561 sens_destroy(key, levdatum, NULL);
1493 goto out; 1562 return rc;
1494} 1563}
1495 1564
1496static int cat_read(struct policydb *p, struct hashtab *h, void *fp) 1565static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
@@ -1501,39 +1570,35 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
1501 __le32 buf[3]; 1570 __le32 buf[3];
1502 u32 len; 1571 u32 len;
1503 1572
1573 rc = -ENOMEM;
1504 catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC); 1574 catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC);
1505 if (!catdatum) { 1575 if (!catdatum)
1506 rc = -ENOMEM; 1576 goto bad;
1507 goto out;
1508 }
1509 1577
1510 rc = next_entry(buf, fp, sizeof buf); 1578 rc = next_entry(buf, fp, sizeof buf);
1511 if (rc < 0) 1579 if (rc)
1512 goto bad; 1580 goto bad;
1513 1581
1514 len = le32_to_cpu(buf[0]); 1582 len = le32_to_cpu(buf[0]);
1515 catdatum->value = le32_to_cpu(buf[1]); 1583 catdatum->value = le32_to_cpu(buf[1]);
1516 catdatum->isalias = le32_to_cpu(buf[2]); 1584 catdatum->isalias = le32_to_cpu(buf[2]);
1517 1585
1586 rc = -ENOMEM;
1518 key = kmalloc(len + 1, GFP_ATOMIC); 1587 key = kmalloc(len + 1, GFP_ATOMIC);
1519 if (!key) { 1588 if (!key)
1520 rc = -ENOMEM;
1521 goto bad; 1589 goto bad;
1522 }
1523 rc = next_entry(key, fp, len); 1590 rc = next_entry(key, fp, len);
1524 if (rc < 0) 1591 if (rc)
1525 goto bad; 1592 goto bad;
1526 key[len] = '\0'; 1593 key[len] = '\0';
1527 1594
1528 rc = hashtab_insert(h, key, catdatum); 1595 rc = hashtab_insert(h, key, catdatum);
1529 if (rc) 1596 if (rc)
1530 goto bad; 1597 goto bad;
1531out: 1598 return 0;
1532 return rc;
1533
1534bad: 1599bad:
1535 cat_destroy(key, catdatum, NULL); 1600 cat_destroy(key, catdatum, NULL);
1536 goto out; 1601 return rc;
1537} 1602}
1538 1603
1539static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) = 1604static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) =
@@ -1574,9 +1639,9 @@ static int user_bounds_sanity_check(void *key, void *datum, void *datap)
1574 printk(KERN_ERR 1639 printk(KERN_ERR
1575 "SELinux: boundary violated policy: " 1640 "SELinux: boundary violated policy: "
1576 "user=%s role=%s bounds=%s\n", 1641 "user=%s role=%s bounds=%s\n",
1577 p->p_user_val_to_name[user->value - 1], 1642 sym_name(p, SYM_USERS, user->value - 1),
1578 p->p_role_val_to_name[bit], 1643 sym_name(p, SYM_ROLES, bit),
1579 p->p_user_val_to_name[upper->value - 1]); 1644 sym_name(p, SYM_USERS, upper->value - 1));
1580 1645
1581 return -EINVAL; 1646 return -EINVAL;
1582 } 1647 }
@@ -1611,9 +1676,9 @@ static int role_bounds_sanity_check(void *key, void *datum, void *datap)
1611 printk(KERN_ERR 1676 printk(KERN_ERR
1612 "SELinux: boundary violated policy: " 1677 "SELinux: boundary violated policy: "
1613 "role=%s type=%s bounds=%s\n", 1678 "role=%s type=%s bounds=%s\n",
1614 p->p_role_val_to_name[role->value - 1], 1679 sym_name(p, SYM_ROLES, role->value - 1),
1615 p->p_type_val_to_name[bit], 1680 sym_name(p, SYM_TYPES, bit),
1616 p->p_role_val_to_name[upper->value - 1]); 1681 sym_name(p, SYM_ROLES, upper->value - 1));
1617 1682
1618 return -EINVAL; 1683 return -EINVAL;
1619 } 1684 }
@@ -1624,11 +1689,11 @@ static int role_bounds_sanity_check(void *key, void *datum, void *datap)
1624 1689
1625static int type_bounds_sanity_check(void *key, void *datum, void *datap) 1690static int type_bounds_sanity_check(void *key, void *datum, void *datap)
1626{ 1691{
1627 struct type_datum *upper, *type; 1692 struct type_datum *upper;
1628 struct policydb *p = datap; 1693 struct policydb *p = datap;
1629 int depth = 0; 1694 int depth = 0;
1630 1695
1631 upper = type = datum; 1696 upper = datum;
1632 while (upper->bounds) { 1697 while (upper->bounds) {
1633 if (++depth == POLICYDB_BOUNDS_MAXDEPTH) { 1698 if (++depth == POLICYDB_BOUNDS_MAXDEPTH) {
1634 printk(KERN_ERR "SELinux: type %s: " 1699 printk(KERN_ERR "SELinux: type %s: "
@@ -1637,12 +1702,15 @@ static int type_bounds_sanity_check(void *key, void *datum, void *datap)
1637 return -EINVAL; 1702 return -EINVAL;
1638 } 1703 }
1639 1704
1640 upper = p->type_val_to_struct[upper->bounds - 1]; 1705 upper = flex_array_get_ptr(p->type_val_to_struct_array,
1706 upper->bounds - 1);
1707 BUG_ON(!upper);
1708
1641 if (upper->attribute) { 1709 if (upper->attribute) {
1642 printk(KERN_ERR "SELinux: type %s: " 1710 printk(KERN_ERR "SELinux: type %s: "
1643 "bounded by attribute %s", 1711 "bounded by attribute %s",
1644 (char *) key, 1712 (char *) key,
1645 p->p_type_val_to_name[upper->value - 1]); 1713 sym_name(p, SYM_TYPES, upper->value - 1));
1646 return -EINVAL; 1714 return -EINVAL;
1647 } 1715 }
1648 } 1716 }
@@ -1775,7 +1843,7 @@ static int range_read(struct policydb *p, void *fp)
1775 rt = NULL; 1843 rt = NULL;
1776 r = NULL; 1844 r = NULL;
1777 } 1845 }
1778 rangetr_hash_eval(p->range_tr); 1846 hash_eval(p->range_tr, "rangetr");
1779 rc = 0; 1847 rc = 0;
1780out: 1848out:
1781 kfree(rt); 1849 kfree(rt);
@@ -1783,6 +1851,83 @@ out:
1783 return rc; 1851 return rc;
1784} 1852}
1785 1853
1854static int filename_trans_read(struct policydb *p, void *fp)
1855{
1856 struct filename_trans *ft;
1857 struct filename_trans_datum *otype;
1858 char *name;
1859 u32 nel, len;
1860 __le32 buf[4];
1861 int rc, i;
1862
1863 if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)
1864 return 0;
1865
1866 rc = next_entry(buf, fp, sizeof(u32));
1867 if (rc)
1868 return rc;
1869 nel = le32_to_cpu(buf[0]);
1870
1871 for (i = 0; i < nel; i++) {
1872 ft = NULL;
1873 otype = NULL;
1874 name = NULL;
1875
1876 rc = -ENOMEM;
1877 ft = kzalloc(sizeof(*ft), GFP_KERNEL);
1878 if (!ft)
1879 goto out;
1880
1881 rc = -ENOMEM;
1882 otype = kmalloc(sizeof(*otype), GFP_KERNEL);
1883 if (!otype)
1884 goto out;
1885
1886 /* length of the path component string */
1887 rc = next_entry(buf, fp, sizeof(u32));
1888 if (rc)
1889 goto out;
1890 len = le32_to_cpu(buf[0]);
1891
1892 rc = -ENOMEM;
1893 name = kmalloc(len + 1, GFP_KERNEL);
1894 if (!name)
1895 goto out;
1896
1897 ft->name = name;
1898
1899 /* path component string */
1900 rc = next_entry(name, fp, len);
1901 if (rc)
1902 goto out;
1903 name[len] = 0;
1904
1905 rc = next_entry(buf, fp, sizeof(u32) * 4);
1906 if (rc)
1907 goto out;
1908
1909 ft->stype = le32_to_cpu(buf[0]);
1910 ft->ttype = le32_to_cpu(buf[1]);
1911 ft->tclass = le32_to_cpu(buf[2]);
1912
1913 otype->otype = le32_to_cpu(buf[3]);
1914
1915 rc = ebitmap_set_bit(&p->filename_trans_ttypes, ft->ttype, 1);
1916 if (rc)
1917 goto out;
1918
1919 hashtab_insert(p->filename_trans, ft, otype);
1920 }
1921 hash_eval(p->filename_trans, "filenametr");
1922 return 0;
1923out:
1924 kfree(ft);
1925 kfree(name);
1926 kfree(otype);
1927
1928 return rc;
1929}
1930
1786static int genfs_read(struct policydb *p, void *fp) 1931static int genfs_read(struct policydb *p, void *fp)
1787{ 1932{
1788 int i, j, rc; 1933 int i, j, rc;
@@ -2055,13 +2200,14 @@ int policydb_read(struct policydb *p, void *fp)
2055 2200
2056 rc = policydb_init(p); 2201 rc = policydb_init(p);
2057 if (rc) 2202 if (rc)
2058 goto out; 2203 return rc;
2059 2204
2060 /* Read the magic number and string length. */ 2205 /* Read the magic number and string length. */
2061 rc = next_entry(buf, fp, sizeof(u32) * 2); 2206 rc = next_entry(buf, fp, sizeof(u32) * 2);
2062 if (rc < 0) 2207 if (rc)
2063 goto bad; 2208 goto bad;
2064 2209
2210 rc = -EINVAL;
2065 if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) { 2211 if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) {
2066 printk(KERN_ERR "SELinux: policydb magic number 0x%x does " 2212 printk(KERN_ERR "SELinux: policydb magic number 0x%x does "
2067 "not match expected magic number 0x%x\n", 2213 "not match expected magic number 0x%x\n",
@@ -2069,6 +2215,7 @@ int policydb_read(struct policydb *p, void *fp)
2069 goto bad; 2215 goto bad;
2070 } 2216 }
2071 2217
2218 rc = -EINVAL;
2072 len = le32_to_cpu(buf[1]); 2219 len = le32_to_cpu(buf[1]);
2073 if (len != strlen(POLICYDB_STRING)) { 2220 if (len != strlen(POLICYDB_STRING)) {
2074 printk(KERN_ERR "SELinux: policydb string length %d does not " 2221 printk(KERN_ERR "SELinux: policydb string length %d does not "
@@ -2076,19 +2223,23 @@ int policydb_read(struct policydb *p, void *fp)
2076 len, strlen(POLICYDB_STRING)); 2223 len, strlen(POLICYDB_STRING));
2077 goto bad; 2224 goto bad;
2078 } 2225 }
2226
2227 rc = -ENOMEM;
2079 policydb_str = kmalloc(len + 1, GFP_KERNEL); 2228 policydb_str = kmalloc(len + 1, GFP_KERNEL);
2080 if (!policydb_str) { 2229 if (!policydb_str) {
2081 printk(KERN_ERR "SELinux: unable to allocate memory for policydb " 2230 printk(KERN_ERR "SELinux: unable to allocate memory for policydb "
2082 "string of length %d\n", len); 2231 "string of length %d\n", len);
2083 rc = -ENOMEM;
2084 goto bad; 2232 goto bad;
2085 } 2233 }
2234
2086 rc = next_entry(policydb_str, fp, len); 2235 rc = next_entry(policydb_str, fp, len);
2087 if (rc < 0) { 2236 if (rc) {
2088 printk(KERN_ERR "SELinux: truncated policydb string identifier\n"); 2237 printk(KERN_ERR "SELinux: truncated policydb string identifier\n");
2089 kfree(policydb_str); 2238 kfree(policydb_str);
2090 goto bad; 2239 goto bad;
2091 } 2240 }
2241
2242 rc = -EINVAL;
2092 policydb_str[len] = '\0'; 2243 policydb_str[len] = '\0';
2093 if (strcmp(policydb_str, POLICYDB_STRING)) { 2244 if (strcmp(policydb_str, POLICYDB_STRING)) {
2094 printk(KERN_ERR "SELinux: policydb string %s does not match " 2245 printk(KERN_ERR "SELinux: policydb string %s does not match "
@@ -2102,9 +2253,10 @@ int policydb_read(struct policydb *p, void *fp)
2102 2253
2103 /* Read the version and table sizes. */ 2254 /* Read the version and table sizes. */
2104 rc = next_entry(buf, fp, sizeof(u32)*4); 2255 rc = next_entry(buf, fp, sizeof(u32)*4);
2105 if (rc < 0) 2256 if (rc)
2106 goto bad; 2257 goto bad;
2107 2258
2259 rc = -EINVAL;
2108 p->policyvers = le32_to_cpu(buf[0]); 2260 p->policyvers = le32_to_cpu(buf[0]);
2109 if (p->policyvers < POLICYDB_VERSION_MIN || 2261 if (p->policyvers < POLICYDB_VERSION_MIN ||
2110 p->policyvers > POLICYDB_VERSION_MAX) { 2262 p->policyvers > POLICYDB_VERSION_MAX) {
@@ -2117,6 +2269,7 @@ int policydb_read(struct policydb *p, void *fp)
2117 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { 2269 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
2118 p->mls_enabled = 1; 2270 p->mls_enabled = 1;
2119 2271
2272 rc = -EINVAL;
2120 if (p->policyvers < POLICYDB_VERSION_MLS) { 2273 if (p->policyvers < POLICYDB_VERSION_MLS) {
2121 printk(KERN_ERR "SELinux: security policydb version %d " 2274 printk(KERN_ERR "SELinux: security policydb version %d "
2122 "(MLS) not backwards compatible\n", 2275 "(MLS) not backwards compatible\n",
@@ -2127,14 +2280,19 @@ int policydb_read(struct policydb *p, void *fp)
2127 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); 2280 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
2128 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); 2281 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
2129 2282
2130 if (p->policyvers >= POLICYDB_VERSION_POLCAP && 2283 if (p->policyvers >= POLICYDB_VERSION_POLCAP) {
2131 ebitmap_read(&p->policycaps, fp) != 0) 2284 rc = ebitmap_read(&p->policycaps, fp);
2132 goto bad; 2285 if (rc)
2286 goto bad;
2287 }
2133 2288
2134 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && 2289 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE) {
2135 ebitmap_read(&p->permissive_map, fp) != 0) 2290 rc = ebitmap_read(&p->permissive_map, fp);
2136 goto bad; 2291 if (rc)
2292 goto bad;
2293 }
2137 2294
2295 rc = -EINVAL;
2138 info = policydb_lookup_compat(p->policyvers); 2296 info = policydb_lookup_compat(p->policyvers);
2139 if (!info) { 2297 if (!info) {
2140 printk(KERN_ERR "SELinux: unable to find policy compat info " 2298 printk(KERN_ERR "SELinux: unable to find policy compat info "
@@ -2142,6 +2300,7 @@ int policydb_read(struct policydb *p, void *fp)
2142 goto bad; 2300 goto bad;
2143 } 2301 }
2144 2302
2303 rc = -EINVAL;
2145 if (le32_to_cpu(buf[2]) != info->sym_num || 2304 if (le32_to_cpu(buf[2]) != info->sym_num ||
2146 le32_to_cpu(buf[3]) != info->ocon_num) { 2305 le32_to_cpu(buf[3]) != info->ocon_num) {
2147 printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do " 2306 printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do "
@@ -2153,7 +2312,7 @@ int policydb_read(struct policydb *p, void *fp)
2153 2312
2154 for (i = 0; i < info->sym_num; i++) { 2313 for (i = 0; i < info->sym_num; i++) {
2155 rc = next_entry(buf, fp, sizeof(u32)*2); 2314 rc = next_entry(buf, fp, sizeof(u32)*2);
2156 if (rc < 0) 2315 if (rc)
2157 goto bad; 2316 goto bad;
2158 nprim = le32_to_cpu(buf[0]); 2317 nprim = le32_to_cpu(buf[0]);
2159 nel = le32_to_cpu(buf[1]); 2318 nel = le32_to_cpu(buf[1]);
@@ -2166,6 +2325,11 @@ int policydb_read(struct policydb *p, void *fp)
2166 p->symtab[i].nprim = nprim; 2325 p->symtab[i].nprim = nprim;
2167 } 2326 }
2168 2327
2328 rc = -EINVAL;
2329 p->process_class = string_to_security_class(p, "process");
2330 if (!p->process_class)
2331 goto bad;
2332
2169 rc = avtab_read(&p->te_avtab, fp, p); 2333 rc = avtab_read(&p->te_avtab, fp, p);
2170 if (rc) 2334 if (rc)
2171 goto bad; 2335 goto bad;
@@ -2177,78 +2341,81 @@ int policydb_read(struct policydb *p, void *fp)
2177 } 2341 }
2178 2342
2179 rc = next_entry(buf, fp, sizeof(u32)); 2343 rc = next_entry(buf, fp, sizeof(u32));
2180 if (rc < 0) 2344 if (rc)
2181 goto bad; 2345 goto bad;
2182 nel = le32_to_cpu(buf[0]); 2346 nel = le32_to_cpu(buf[0]);
2183 ltr = NULL; 2347 ltr = NULL;
2184 for (i = 0; i < nel; i++) { 2348 for (i = 0; i < nel; i++) {
2349 rc = -ENOMEM;
2185 tr = kzalloc(sizeof(*tr), GFP_KERNEL); 2350 tr = kzalloc(sizeof(*tr), GFP_KERNEL);
2186 if (!tr) { 2351 if (!tr)
2187 rc = -ENOMEM;
2188 goto bad; 2352 goto bad;
2189 }
2190 if (ltr) 2353 if (ltr)
2191 ltr->next = tr; 2354 ltr->next = tr;
2192 else 2355 else
2193 p->role_tr = tr; 2356 p->role_tr = tr;
2194 rc = next_entry(buf, fp, sizeof(u32)*3); 2357 rc = next_entry(buf, fp, sizeof(u32)*3);
2195 if (rc < 0) 2358 if (rc)
2196 goto bad; 2359 goto bad;
2360
2361 rc = -EINVAL;
2197 tr->role = le32_to_cpu(buf[0]); 2362 tr->role = le32_to_cpu(buf[0]);
2198 tr->type = le32_to_cpu(buf[1]); 2363 tr->type = le32_to_cpu(buf[1]);
2199 tr->new_role = le32_to_cpu(buf[2]); 2364 tr->new_role = le32_to_cpu(buf[2]);
2365 if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
2366 rc = next_entry(buf, fp, sizeof(u32));
2367 if (rc)
2368 goto bad;
2369 tr->tclass = le32_to_cpu(buf[0]);
2370 } else
2371 tr->tclass = p->process_class;
2372
2200 if (!policydb_role_isvalid(p, tr->role) || 2373 if (!policydb_role_isvalid(p, tr->role) ||
2201 !policydb_type_isvalid(p, tr->type) || 2374 !policydb_type_isvalid(p, tr->type) ||
2202 !policydb_role_isvalid(p, tr->new_role)) { 2375 !policydb_class_isvalid(p, tr->tclass) ||
2203 rc = -EINVAL; 2376 !policydb_role_isvalid(p, tr->new_role))
2204 goto bad; 2377 goto bad;
2205 }
2206 ltr = tr; 2378 ltr = tr;
2207 } 2379 }
2208 2380
2209 rc = next_entry(buf, fp, sizeof(u32)); 2381 rc = next_entry(buf, fp, sizeof(u32));
2210 if (rc < 0) 2382 if (rc)
2211 goto bad; 2383 goto bad;
2212 nel = le32_to_cpu(buf[0]); 2384 nel = le32_to_cpu(buf[0]);
2213 lra = NULL; 2385 lra = NULL;
2214 for (i = 0; i < nel; i++) { 2386 for (i = 0; i < nel; i++) {
2387 rc = -ENOMEM;
2215 ra = kzalloc(sizeof(*ra), GFP_KERNEL); 2388 ra = kzalloc(sizeof(*ra), GFP_KERNEL);
2216 if (!ra) { 2389 if (!ra)
2217 rc = -ENOMEM;
2218 goto bad; 2390 goto bad;
2219 }
2220 if (lra) 2391 if (lra)
2221 lra->next = ra; 2392 lra->next = ra;
2222 else 2393 else
2223 p->role_allow = ra; 2394 p->role_allow = ra;
2224 rc = next_entry(buf, fp, sizeof(u32)*2); 2395 rc = next_entry(buf, fp, sizeof(u32)*2);
2225 if (rc < 0) 2396 if (rc)
2226 goto bad; 2397 goto bad;
2398
2399 rc = -EINVAL;
2227 ra->role = le32_to_cpu(buf[0]); 2400 ra->role = le32_to_cpu(buf[0]);
2228 ra->new_role = le32_to_cpu(buf[1]); 2401 ra->new_role = le32_to_cpu(buf[1]);
2229 if (!policydb_role_isvalid(p, ra->role) || 2402 if (!policydb_role_isvalid(p, ra->role) ||
2230 !policydb_role_isvalid(p, ra->new_role)) { 2403 !policydb_role_isvalid(p, ra->new_role))
2231 rc = -EINVAL;
2232 goto bad; 2404 goto bad;
2233 }
2234 lra = ra; 2405 lra = ra;
2235 } 2406 }
2236 2407
2237 rc = policydb_index_classes(p); 2408 rc = filename_trans_read(p, fp);
2238 if (rc) 2409 if (rc)
2239 goto bad; 2410 goto bad;
2240 2411
2241 rc = policydb_index_others(p); 2412 rc = policydb_index(p);
2242 if (rc) 2413 if (rc)
2243 goto bad; 2414 goto bad;
2244 2415
2245 p->process_class = string_to_security_class(p, "process"); 2416 rc = -EINVAL;
2246 if (!p->process_class) 2417 p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition");
2247 goto bad; 2418 p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition");
2248 p->process_trans_perms = string_to_av_perm(p, p->process_class,
2249 "transition");
2250 p->process_trans_perms |= string_to_av_perm(p, p->process_class,
2251 "dyntransition");
2252 if (!p->process_trans_perms) 2419 if (!p->process_trans_perms)
2253 goto bad; 2420 goto bad;
2254 2421
@@ -2272,7 +2439,7 @@ int policydb_read(struct policydb *p, void *fp)
2272 goto bad; 2439 goto bad;
2273 2440
2274 /* preallocate so we don't have to worry about the put ever failing */ 2441 /* preallocate so we don't have to worry about the put ever failing */
2275 rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim - 1, 2442 rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim,
2276 GFP_KERNEL | __GFP_ZERO); 2443 GFP_KERNEL | __GFP_ZERO);
2277 if (rc) 2444 if (rc)
2278 goto bad; 2445 goto bad;
@@ -2301,8 +2468,914 @@ int policydb_read(struct policydb *p, void *fp)
2301out: 2468out:
2302 return rc; 2469 return rc;
2303bad: 2470bad:
2304 if (!rc)
2305 rc = -EINVAL;
2306 policydb_destroy(p); 2471 policydb_destroy(p);
2307 goto out; 2472 goto out;
2308} 2473}
2474
2475/*
2476 * Write a MLS level structure to a policydb binary
2477 * representation file.
2478 */
2479static int mls_write_level(struct mls_level *l, void *fp)
2480{
2481 __le32 buf[1];
2482 int rc;
2483
2484 buf[0] = cpu_to_le32(l->sens);
2485 rc = put_entry(buf, sizeof(u32), 1, fp);
2486 if (rc)
2487 return rc;
2488
2489 rc = ebitmap_write(&l->cat, fp);
2490 if (rc)
2491 return rc;
2492
2493 return 0;
2494}
2495
2496/*
2497 * Write a MLS range structure to a policydb binary
2498 * representation file.
2499 */
2500static int mls_write_range_helper(struct mls_range *r, void *fp)
2501{
2502 __le32 buf[3];
2503 size_t items;
2504 int rc, eq;
2505
2506 eq = mls_level_eq(&r->level[1], &r->level[0]);
2507
2508 if (eq)
2509 items = 2;
2510 else
2511 items = 3;
2512 buf[0] = cpu_to_le32(items-1);
2513 buf[1] = cpu_to_le32(r->level[0].sens);
2514 if (!eq)
2515 buf[2] = cpu_to_le32(r->level[1].sens);
2516
2517 BUG_ON(items > (sizeof(buf)/sizeof(buf[0])));
2518
2519 rc = put_entry(buf, sizeof(u32), items, fp);
2520 if (rc)
2521 return rc;
2522
2523 rc = ebitmap_write(&r->level[0].cat, fp);
2524 if (rc)
2525 return rc;
2526 if (!eq) {
2527 rc = ebitmap_write(&r->level[1].cat, fp);
2528 if (rc)
2529 return rc;
2530 }
2531
2532 return 0;
2533}
2534
2535static int sens_write(void *vkey, void *datum, void *ptr)
2536{
2537 char *key = vkey;
2538 struct level_datum *levdatum = datum;
2539 struct policy_data *pd = ptr;
2540 void *fp = pd->fp;
2541 __le32 buf[2];
2542 size_t len;
2543 int rc;
2544
2545 len = strlen(key);
2546 buf[0] = cpu_to_le32(len);
2547 buf[1] = cpu_to_le32(levdatum->isalias);
2548 rc = put_entry(buf, sizeof(u32), 2, fp);
2549 if (rc)
2550 return rc;
2551
2552 rc = put_entry(key, 1, len, fp);
2553 if (rc)
2554 return rc;
2555
2556 rc = mls_write_level(levdatum->level, fp);
2557 if (rc)
2558 return rc;
2559
2560 return 0;
2561}
2562
2563static int cat_write(void *vkey, void *datum, void *ptr)
2564{
2565 char *key = vkey;
2566 struct cat_datum *catdatum = datum;
2567 struct policy_data *pd = ptr;
2568 void *fp = pd->fp;
2569 __le32 buf[3];
2570 size_t len;
2571 int rc;
2572
2573 len = strlen(key);
2574 buf[0] = cpu_to_le32(len);
2575 buf[1] = cpu_to_le32(catdatum->value);
2576 buf[2] = cpu_to_le32(catdatum->isalias);
2577 rc = put_entry(buf, sizeof(u32), 3, fp);
2578 if (rc)
2579 return rc;
2580
2581 rc = put_entry(key, 1, len, fp);
2582 if (rc)
2583 return rc;
2584
2585 return 0;
2586}
2587
2588static int role_trans_write(struct policydb *p, void *fp)
2589{
2590 struct role_trans *r = p->role_tr;
2591 struct role_trans *tr;
2592 u32 buf[3];
2593 size_t nel;
2594 int rc;
2595
2596 nel = 0;
2597 for (tr = r; tr; tr = tr->next)
2598 nel++;
2599 buf[0] = cpu_to_le32(nel);
2600 rc = put_entry(buf, sizeof(u32), 1, fp);
2601 if (rc)
2602 return rc;
2603 for (tr = r; tr; tr = tr->next) {
2604 buf[0] = cpu_to_le32(tr->role);
2605 buf[1] = cpu_to_le32(tr->type);
2606 buf[2] = cpu_to_le32(tr->new_role);
2607 rc = put_entry(buf, sizeof(u32), 3, fp);
2608 if (rc)
2609 return rc;
2610 if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
2611 buf[0] = cpu_to_le32(tr->tclass);
2612 rc = put_entry(buf, sizeof(u32), 1, fp);
2613 if (rc)
2614 return rc;
2615 }
2616 }
2617
2618 return 0;
2619}
2620
2621static int role_allow_write(struct role_allow *r, void *fp)
2622{
2623 struct role_allow *ra;
2624 u32 buf[2];
2625 size_t nel;
2626 int rc;
2627
2628 nel = 0;
2629 for (ra = r; ra; ra = ra->next)
2630 nel++;
2631 buf[0] = cpu_to_le32(nel);
2632 rc = put_entry(buf, sizeof(u32), 1, fp);
2633 if (rc)
2634 return rc;
2635 for (ra = r; ra; ra = ra->next) {
2636 buf[0] = cpu_to_le32(ra->role);
2637 buf[1] = cpu_to_le32(ra->new_role);
2638 rc = put_entry(buf, sizeof(u32), 2, fp);
2639 if (rc)
2640 return rc;
2641 }
2642 return 0;
2643}
2644
2645/*
2646 * Write a security context structure
2647 * to a policydb binary representation file.
2648 */
2649static int context_write(struct policydb *p, struct context *c,
2650 void *fp)
2651{
2652 int rc;
2653 __le32 buf[3];
2654
2655 buf[0] = cpu_to_le32(c->user);
2656 buf[1] = cpu_to_le32(c->role);
2657 buf[2] = cpu_to_le32(c->type);
2658
2659 rc = put_entry(buf, sizeof(u32), 3, fp);
2660 if (rc)
2661 return rc;
2662
2663 rc = mls_write_range_helper(&c->range, fp);
2664 if (rc)
2665 return rc;
2666
2667 return 0;
2668}
2669
2670/*
2671 * The following *_write functions are used to
2672 * write the symbol data to a policy database
2673 * binary representation file.
2674 */
2675
2676static int perm_write(void *vkey, void *datum, void *fp)
2677{
2678 char *key = vkey;
2679 struct perm_datum *perdatum = datum;
2680 __le32 buf[2];
2681 size_t len;
2682 int rc;
2683
2684 len = strlen(key);
2685 buf[0] = cpu_to_le32(len);
2686 buf[1] = cpu_to_le32(perdatum->value);
2687 rc = put_entry(buf, sizeof(u32), 2, fp);
2688 if (rc)
2689 return rc;
2690
2691 rc = put_entry(key, 1, len, fp);
2692 if (rc)
2693 return rc;
2694
2695 return 0;
2696}
2697
2698static int common_write(void *vkey, void *datum, void *ptr)
2699{
2700 char *key = vkey;
2701 struct common_datum *comdatum = datum;
2702 struct policy_data *pd = ptr;
2703 void *fp = pd->fp;
2704 __le32 buf[4];
2705 size_t len;
2706 int rc;
2707
2708 len = strlen(key);
2709 buf[0] = cpu_to_le32(len);
2710 buf[1] = cpu_to_le32(comdatum->value);
2711 buf[2] = cpu_to_le32(comdatum->permissions.nprim);
2712 buf[3] = cpu_to_le32(comdatum->permissions.table->nel);
2713 rc = put_entry(buf, sizeof(u32), 4, fp);
2714 if (rc)
2715 return rc;
2716
2717 rc = put_entry(key, 1, len, fp);
2718 if (rc)
2719 return rc;
2720
2721 rc = hashtab_map(comdatum->permissions.table, perm_write, fp);
2722 if (rc)
2723 return rc;
2724
2725 return 0;
2726}
2727
2728static int write_cons_helper(struct policydb *p, struct constraint_node *node,
2729 void *fp)
2730{
2731 struct constraint_node *c;
2732 struct constraint_expr *e;
2733 __le32 buf[3];
2734 u32 nel;
2735 int rc;
2736
2737 for (c = node; c; c = c->next) {
2738 nel = 0;
2739 for (e = c->expr; e; e = e->next)
2740 nel++;
2741 buf[0] = cpu_to_le32(c->permissions);
2742 buf[1] = cpu_to_le32(nel);
2743 rc = put_entry(buf, sizeof(u32), 2, fp);
2744 if (rc)
2745 return rc;
2746 for (e = c->expr; e; e = e->next) {
2747 buf[0] = cpu_to_le32(e->expr_type);
2748 buf[1] = cpu_to_le32(e->attr);
2749 buf[2] = cpu_to_le32(e->op);
2750 rc = put_entry(buf, sizeof(u32), 3, fp);
2751 if (rc)
2752 return rc;
2753
2754 switch (e->expr_type) {
2755 case CEXPR_NAMES:
2756 rc = ebitmap_write(&e->names, fp);
2757 if (rc)
2758 return rc;
2759 break;
2760 default:
2761 break;
2762 }
2763 }
2764 }
2765
2766 return 0;
2767}
2768
2769static int class_write(void *vkey, void *datum, void *ptr)
2770{
2771 char *key = vkey;
2772 struct class_datum *cladatum = datum;
2773 struct policy_data *pd = ptr;
2774 void *fp = pd->fp;
2775 struct policydb *p = pd->p;
2776 struct constraint_node *c;
2777 __le32 buf[6];
2778 u32 ncons;
2779 size_t len, len2;
2780 int rc;
2781
2782 len = strlen(key);
2783 if (cladatum->comkey)
2784 len2 = strlen(cladatum->comkey);
2785 else
2786 len2 = 0;
2787
2788 ncons = 0;
2789 for (c = cladatum->constraints; c; c = c->next)
2790 ncons++;
2791
2792 buf[0] = cpu_to_le32(len);
2793 buf[1] = cpu_to_le32(len2);
2794 buf[2] = cpu_to_le32(cladatum->value);
2795 buf[3] = cpu_to_le32(cladatum->permissions.nprim);
2796 if (cladatum->permissions.table)
2797 buf[4] = cpu_to_le32(cladatum->permissions.table->nel);
2798 else
2799 buf[4] = 0;
2800 buf[5] = cpu_to_le32(ncons);
2801 rc = put_entry(buf, sizeof(u32), 6, fp);
2802 if (rc)
2803 return rc;
2804
2805 rc = put_entry(key, 1, len, fp);
2806 if (rc)
2807 return rc;
2808
2809 if (cladatum->comkey) {
2810 rc = put_entry(cladatum->comkey, 1, len2, fp);
2811 if (rc)
2812 return rc;
2813 }
2814
2815 rc = hashtab_map(cladatum->permissions.table, perm_write, fp);
2816 if (rc)
2817 return rc;
2818
2819 rc = write_cons_helper(p, cladatum->constraints, fp);
2820 if (rc)
2821 return rc;
2822
2823 /* write out the validatetrans rule */
2824 ncons = 0;
2825 for (c = cladatum->validatetrans; c; c = c->next)
2826 ncons++;
2827
2828 buf[0] = cpu_to_le32(ncons);
2829 rc = put_entry(buf, sizeof(u32), 1, fp);
2830 if (rc)
2831 return rc;
2832
2833 rc = write_cons_helper(p, cladatum->validatetrans, fp);
2834 if (rc)
2835 return rc;
2836
2837 return 0;
2838}
2839
2840static int role_write(void *vkey, void *datum, void *ptr)
2841{
2842 char *key = vkey;
2843 struct role_datum *role = datum;
2844 struct policy_data *pd = ptr;
2845 void *fp = pd->fp;
2846 struct policydb *p = pd->p;
2847 __le32 buf[3];
2848 size_t items, len;
2849 int rc;
2850
2851 len = strlen(key);
2852 items = 0;
2853 buf[items++] = cpu_to_le32(len);
2854 buf[items++] = cpu_to_le32(role->value);
2855 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
2856 buf[items++] = cpu_to_le32(role->bounds);
2857
2858 BUG_ON(items > (sizeof(buf)/sizeof(buf[0])));
2859
2860 rc = put_entry(buf, sizeof(u32), items, fp);
2861 if (rc)
2862 return rc;
2863
2864 rc = put_entry(key, 1, len, fp);
2865 if (rc)
2866 return rc;
2867
2868 rc = ebitmap_write(&role->dominates, fp);
2869 if (rc)
2870 return rc;
2871
2872 rc = ebitmap_write(&role->types, fp);
2873 if (rc)
2874 return rc;
2875
2876 return 0;
2877}
2878
2879static int type_write(void *vkey, void *datum, void *ptr)
2880{
2881 char *key = vkey;
2882 struct type_datum *typdatum = datum;
2883 struct policy_data *pd = ptr;
2884 struct policydb *p = pd->p;
2885 void *fp = pd->fp;
2886 __le32 buf[4];
2887 int rc;
2888 size_t items, len;
2889
2890 len = strlen(key);
2891 items = 0;
2892 buf[items++] = cpu_to_le32(len);
2893 buf[items++] = cpu_to_le32(typdatum->value);
2894 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) {
2895 u32 properties = 0;
2896
2897 if (typdatum->primary)
2898 properties |= TYPEDATUM_PROPERTY_PRIMARY;
2899
2900 if (typdatum->attribute)
2901 properties |= TYPEDATUM_PROPERTY_ATTRIBUTE;
2902
2903 buf[items++] = cpu_to_le32(properties);
2904 buf[items++] = cpu_to_le32(typdatum->bounds);
2905 } else {
2906 buf[items++] = cpu_to_le32(typdatum->primary);
2907 }
2908 BUG_ON(items > (sizeof(buf) / sizeof(buf[0])));
2909 rc = put_entry(buf, sizeof(u32), items, fp);
2910 if (rc)
2911 return rc;
2912
2913 rc = put_entry(key, 1, len, fp);
2914 if (rc)
2915 return rc;
2916
2917 return 0;
2918}
2919
2920static int user_write(void *vkey, void *datum, void *ptr)
2921{
2922 char *key = vkey;
2923 struct user_datum *usrdatum = datum;
2924 struct policy_data *pd = ptr;
2925 struct policydb *p = pd->p;
2926 void *fp = pd->fp;
2927 __le32 buf[3];
2928 size_t items, len;
2929 int rc;
2930
2931 len = strlen(key);
2932 items = 0;
2933 buf[items++] = cpu_to_le32(len);
2934 buf[items++] = cpu_to_le32(usrdatum->value);
2935 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
2936 buf[items++] = cpu_to_le32(usrdatum->bounds);
2937 BUG_ON(items > (sizeof(buf) / sizeof(buf[0])));
2938 rc = put_entry(buf, sizeof(u32), items, fp);
2939 if (rc)
2940 return rc;
2941
2942 rc = put_entry(key, 1, len, fp);
2943 if (rc)
2944 return rc;
2945
2946 rc = ebitmap_write(&usrdatum->roles, fp);
2947 if (rc)
2948 return rc;
2949
2950 rc = mls_write_range_helper(&usrdatum->range, fp);
2951 if (rc)
2952 return rc;
2953
2954 rc = mls_write_level(&usrdatum->dfltlevel, fp);
2955 if (rc)
2956 return rc;
2957
2958 return 0;
2959}
2960
2961static int (*write_f[SYM_NUM]) (void *key, void *datum,
2962 void *datap) =
2963{
2964 common_write,
2965 class_write,
2966 role_write,
2967 type_write,
2968 user_write,
2969 cond_write_bool,
2970 sens_write,
2971 cat_write,
2972};
2973
2974static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,
2975 void *fp)
2976{
2977 unsigned int i, j, rc;
2978 size_t nel, len;
2979 __le32 buf[3];
2980 u32 nodebuf[8];
2981 struct ocontext *c;
2982 for (i = 0; i < info->ocon_num; i++) {
2983 nel = 0;
2984 for (c = p->ocontexts[i]; c; c = c->next)
2985 nel++;
2986 buf[0] = cpu_to_le32(nel);
2987 rc = put_entry(buf, sizeof(u32), 1, fp);
2988 if (rc)
2989 return rc;
2990 for (c = p->ocontexts[i]; c; c = c->next) {
2991 switch (i) {
2992 case OCON_ISID:
2993 buf[0] = cpu_to_le32(c->sid[0]);
2994 rc = put_entry(buf, sizeof(u32), 1, fp);
2995 if (rc)
2996 return rc;
2997 rc = context_write(p, &c->context[0], fp);
2998 if (rc)
2999 return rc;
3000 break;
3001 case OCON_FS:
3002 case OCON_NETIF:
3003 len = strlen(c->u.name);
3004 buf[0] = cpu_to_le32(len);
3005 rc = put_entry(buf, sizeof(u32), 1, fp);
3006 if (rc)
3007 return rc;
3008 rc = put_entry(c->u.name, 1, len, fp);
3009 if (rc)
3010 return rc;
3011 rc = context_write(p, &c->context[0], fp);
3012 if (rc)
3013 return rc;
3014 rc = context_write(p, &c->context[1], fp);
3015 if (rc)
3016 return rc;
3017 break;
3018 case OCON_PORT:
3019 buf[0] = cpu_to_le32(c->u.port.protocol);
3020 buf[1] = cpu_to_le32(c->u.port.low_port);
3021 buf[2] = cpu_to_le32(c->u.port.high_port);
3022 rc = put_entry(buf, sizeof(u32), 3, fp);
3023 if (rc)
3024 return rc;
3025 rc = context_write(p, &c->context[0], fp);
3026 if (rc)
3027 return rc;
3028 break;
3029 case OCON_NODE:
3030 nodebuf[0] = c->u.node.addr; /* network order */
3031 nodebuf[1] = c->u.node.mask; /* network order */
3032 rc = put_entry(nodebuf, sizeof(u32), 2, fp);
3033 if (rc)
3034 return rc;
3035 rc = context_write(p, &c->context[0], fp);
3036 if (rc)
3037 return rc;
3038 break;
3039 case OCON_FSUSE:
3040 buf[0] = cpu_to_le32(c->v.behavior);
3041 len = strlen(c->u.name);
3042 buf[1] = cpu_to_le32(len);
3043 rc = put_entry(buf, sizeof(u32), 2, fp);
3044 if (rc)
3045 return rc;
3046 rc = put_entry(c->u.name, 1, len, fp);
3047 if (rc)
3048 return rc;
3049 rc = context_write(p, &c->context[0], fp);
3050 if (rc)
3051 return rc;
3052 break;
3053 case OCON_NODE6:
3054 for (j = 0; j < 4; j++)
3055 nodebuf[j] = c->u.node6.addr[j]; /* network order */
3056 for (j = 0; j < 4; j++)
3057 nodebuf[j + 4] = c->u.node6.mask[j]; /* network order */
3058 rc = put_entry(nodebuf, sizeof(u32), 8, fp);
3059 if (rc)
3060 return rc;
3061 rc = context_write(p, &c->context[0], fp);
3062 if (rc)
3063 return rc;
3064 break;
3065 }
3066 }
3067 }
3068 return 0;
3069}
3070
3071static int genfs_write(struct policydb *p, void *fp)
3072{
3073 struct genfs *genfs;
3074 struct ocontext *c;
3075 size_t len;
3076 __le32 buf[1];
3077 int rc;
3078
3079 len = 0;
3080 for (genfs = p->genfs; genfs; genfs = genfs->next)
3081 len++;
3082 buf[0] = cpu_to_le32(len);
3083 rc = put_entry(buf, sizeof(u32), 1, fp);
3084 if (rc)
3085 return rc;
3086 for (genfs = p->genfs; genfs; genfs = genfs->next) {
3087 len = strlen(genfs->fstype);
3088 buf[0] = cpu_to_le32(len);
3089 rc = put_entry(buf, sizeof(u32), 1, fp);
3090 if (rc)
3091 return rc;
3092 rc = put_entry(genfs->fstype, 1, len, fp);
3093 if (rc)
3094 return rc;
3095 len = 0;
3096 for (c = genfs->head; c; c = c->next)
3097 len++;
3098 buf[0] = cpu_to_le32(len);
3099 rc = put_entry(buf, sizeof(u32), 1, fp);
3100 if (rc)
3101 return rc;
3102 for (c = genfs->head; c; c = c->next) {
3103 len = strlen(c->u.name);
3104 buf[0] = cpu_to_le32(len);
3105 rc = put_entry(buf, sizeof(u32), 1, fp);
3106 if (rc)
3107 return rc;
3108 rc = put_entry(c->u.name, 1, len, fp);
3109 if (rc)
3110 return rc;
3111 buf[0] = cpu_to_le32(c->v.sclass);
3112 rc = put_entry(buf, sizeof(u32), 1, fp);
3113 if (rc)
3114 return rc;
3115 rc = context_write(p, &c->context[0], fp);
3116 if (rc)
3117 return rc;
3118 }
3119 }
3120 return 0;
3121}
3122
3123static int hashtab_cnt(void *key, void *data, void *ptr)
3124{
3125 int *cnt = ptr;
3126 *cnt = *cnt + 1;
3127
3128 return 0;
3129}
3130
3131static int range_write_helper(void *key, void *data, void *ptr)
3132{
3133 __le32 buf[2];
3134 struct range_trans *rt = key;
3135 struct mls_range *r = data;
3136 struct policy_data *pd = ptr;
3137 void *fp = pd->fp;
3138 struct policydb *p = pd->p;
3139 int rc;
3140
3141 buf[0] = cpu_to_le32(rt->source_type);
3142 buf[1] = cpu_to_le32(rt->target_type);
3143 rc = put_entry(buf, sizeof(u32), 2, fp);
3144 if (rc)
3145 return rc;
3146 if (p->policyvers >= POLICYDB_VERSION_RANGETRANS) {
3147 buf[0] = cpu_to_le32(rt->target_class);
3148 rc = put_entry(buf, sizeof(u32), 1, fp);
3149 if (rc)
3150 return rc;
3151 }
3152 rc = mls_write_range_helper(r, fp);
3153 if (rc)
3154 return rc;
3155
3156 return 0;
3157}
3158
3159static int range_write(struct policydb *p, void *fp)
3160{
3161 size_t nel;
3162 __le32 buf[1];
3163 int rc;
3164 struct policy_data pd;
3165
3166 pd.p = p;
3167 pd.fp = fp;
3168
3169 /* count the number of entries in the hashtab */
3170 nel = 0;
3171 rc = hashtab_map(p->range_tr, hashtab_cnt, &nel);
3172 if (rc)
3173 return rc;
3174
3175 buf[0] = cpu_to_le32(nel);
3176 rc = put_entry(buf, sizeof(u32), 1, fp);
3177 if (rc)
3178 return rc;
3179
3180 /* actually write all of the entries */
3181 rc = hashtab_map(p->range_tr, range_write_helper, &pd);
3182 if (rc)
3183 return rc;
3184
3185 return 0;
3186}
3187
3188static int filename_write_helper(void *key, void *data, void *ptr)
3189{
3190 __le32 buf[4];
3191 struct filename_trans *ft = key;
3192 struct filename_trans_datum *otype = data;
3193 void *fp = ptr;
3194 int rc;
3195 u32 len;
3196
3197 len = strlen(ft->name);
3198 buf[0] = cpu_to_le32(len);
3199 rc = put_entry(buf, sizeof(u32), 1, fp);
3200 if (rc)
3201 return rc;
3202
3203 rc = put_entry(ft->name, sizeof(char), len, fp);
3204 if (rc)
3205 return rc;
3206
3207 buf[0] = ft->stype;
3208 buf[1] = ft->ttype;
3209 buf[2] = ft->tclass;
3210 buf[3] = otype->otype;
3211
3212 rc = put_entry(buf, sizeof(u32), 4, fp);
3213 if (rc)
3214 return rc;
3215
3216 return 0;
3217}
3218
3219static int filename_trans_write(struct policydb *p, void *fp)
3220{
3221 u32 nel;
3222 __le32 buf[1];
3223 int rc;
3224
3225 if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)
3226 return 0;
3227
3228 nel = 0;
3229 rc = hashtab_map(p->filename_trans, hashtab_cnt, &nel);
3230 if (rc)
3231 return rc;
3232
3233 buf[0] = cpu_to_le32(nel);
3234 rc = put_entry(buf, sizeof(u32), 1, fp);
3235 if (rc)
3236 return rc;
3237
3238 rc = hashtab_map(p->filename_trans, filename_write_helper, fp);
3239 if (rc)
3240 return rc;
3241
3242 return 0;
3243}
3244
3245/*
3246 * Write the configuration data in a policy database
3247 * structure to a policy database binary representation
3248 * file.
3249 */
3250int policydb_write(struct policydb *p, void *fp)
3251{
3252 unsigned int i, num_syms;
3253 int rc;
3254 __le32 buf[4];
3255 u32 config;
3256 size_t len;
3257 struct policydb_compat_info *info;
3258
3259 /*
3260 * refuse to write policy older than compressed avtab
3261 * to simplify the writer. There are other tests dropped
3262 * since we assume this throughout the writer code. Be
3263 * careful if you ever try to remove this restriction
3264 */
3265 if (p->policyvers < POLICYDB_VERSION_AVTAB) {
3266 printk(KERN_ERR "SELinux: refusing to write policy version %d."
3267 " Because it is less than version %d\n", p->policyvers,
3268 POLICYDB_VERSION_AVTAB);
3269 return -EINVAL;
3270 }
3271
3272 config = 0;
3273 if (p->mls_enabled)
3274 config |= POLICYDB_CONFIG_MLS;
3275
3276 if (p->reject_unknown)
3277 config |= REJECT_UNKNOWN;
3278 if (p->allow_unknown)
3279 config |= ALLOW_UNKNOWN;
3280
3281 /* Write the magic number and string identifiers. */
3282 buf[0] = cpu_to_le32(POLICYDB_MAGIC);
3283 len = strlen(POLICYDB_STRING);
3284 buf[1] = cpu_to_le32(len);
3285 rc = put_entry(buf, sizeof(u32), 2, fp);
3286 if (rc)
3287 return rc;
3288 rc = put_entry(POLICYDB_STRING, 1, len, fp);
3289 if (rc)
3290 return rc;
3291
3292 /* Write the version, config, and table sizes. */
3293 info = policydb_lookup_compat(p->policyvers);
3294 if (!info) {
3295 printk(KERN_ERR "SELinux: compatibility lookup failed for policy "
3296 "version %d", p->policyvers);
3297 return -EINVAL;
3298 }
3299
3300 buf[0] = cpu_to_le32(p->policyvers);
3301 buf[1] = cpu_to_le32(config);
3302 buf[2] = cpu_to_le32(info->sym_num);
3303 buf[3] = cpu_to_le32(info->ocon_num);
3304
3305 rc = put_entry(buf, sizeof(u32), 4, fp);
3306 if (rc)
3307 return rc;
3308
3309 if (p->policyvers >= POLICYDB_VERSION_POLCAP) {
3310 rc = ebitmap_write(&p->policycaps, fp);
3311 if (rc)
3312 return rc;
3313 }
3314
3315 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE) {
3316 rc = ebitmap_write(&p->permissive_map, fp);
3317 if (rc)
3318 return rc;
3319 }
3320
3321 num_syms = info->sym_num;
3322 for (i = 0; i < num_syms; i++) {
3323 struct policy_data pd;
3324
3325 pd.fp = fp;
3326 pd.p = p;
3327
3328 buf[0] = cpu_to_le32(p->symtab[i].nprim);
3329 buf[1] = cpu_to_le32(p->symtab[i].table->nel);
3330
3331 rc = put_entry(buf, sizeof(u32), 2, fp);
3332 if (rc)
3333 return rc;
3334 rc = hashtab_map(p->symtab[i].table, write_f[i], &pd);
3335 if (rc)
3336 return rc;
3337 }
3338
3339 rc = avtab_write(p, &p->te_avtab, fp);
3340 if (rc)
3341 return rc;
3342
3343 rc = cond_write_list(p, p->cond_list, fp);
3344 if (rc)
3345 return rc;
3346
3347 rc = role_trans_write(p, fp);
3348 if (rc)
3349 return rc;
3350
3351 rc = role_allow_write(p->role_allow, fp);
3352 if (rc)
3353 return rc;
3354
3355 rc = filename_trans_write(p, fp);
3356 if (rc)
3357 return rc;
3358
3359 rc = ocontext_write(p, info, fp);
3360 if (rc)
3361 return rc;
3362
3363 rc = genfs_write(p, fp);
3364 if (rc)
3365 return rc;
3366
3367 rc = range_write(p, fp);
3368 if (rc)
3369 return rc;
3370
3371 for (i = 0; i < p->p_types.nprim; i++) {
3372 struct ebitmap *e = flex_array_get(p->type_attr_map_array, i);
3373
3374 BUG_ON(!e);
3375 rc = ebitmap_write(e, fp);
3376 if (rc)
3377 return rc;
3378 }
3379
3380 return 0;
3381}
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 310e94442cb8..b846c0387180 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -72,11 +72,23 @@ struct role_datum {
72 72
73struct role_trans { 73struct role_trans {
74 u32 role; /* current role */ 74 u32 role; /* current role */
75 u32 type; /* program executable type */ 75 u32 type; /* program executable type, or new object type */
76 u32 tclass; /* process class, or new object class */
76 u32 new_role; /* new role */ 77 u32 new_role; /* new role */
77 struct role_trans *next; 78 struct role_trans *next;
78}; 79};
79 80
81struct filename_trans {
82 u32 stype; /* current process */
83 u32 ttype; /* parent dir context */
84 u16 tclass; /* class of new object */
85 const char *name; /* last path component */
86};
87
88struct filename_trans_datum {
89 u32 otype; /* expected of new object */
90};
91
80struct role_allow { 92struct role_allow {
81 u32 role; /* current role */ 93 u32 role; /* current role */
82 u32 new_role; /* new role */ 94 u32 new_role; /* new role */
@@ -203,21 +215,13 @@ struct policydb {
203#define p_cats symtab[SYM_CATS] 215#define p_cats symtab[SYM_CATS]
204 216
205 /* symbol names indexed by (value - 1) */ 217 /* symbol names indexed by (value - 1) */
206 char **sym_val_to_name[SYM_NUM]; 218 struct flex_array *sym_val_to_name[SYM_NUM];
207#define p_common_val_to_name sym_val_to_name[SYM_COMMONS]
208#define p_class_val_to_name sym_val_to_name[SYM_CLASSES]
209#define p_role_val_to_name sym_val_to_name[SYM_ROLES]
210#define p_type_val_to_name sym_val_to_name[SYM_TYPES]
211#define p_user_val_to_name sym_val_to_name[SYM_USERS]
212#define p_bool_val_to_name sym_val_to_name[SYM_BOOLS]
213#define p_sens_val_to_name sym_val_to_name[SYM_LEVELS]
214#define p_cat_val_to_name sym_val_to_name[SYM_CATS]
215 219
216 /* class, role, and user attributes indexed by (value - 1) */ 220 /* class, role, and user attributes indexed by (value - 1) */
217 struct class_datum **class_val_to_struct; 221 struct class_datum **class_val_to_struct;
218 struct role_datum **role_val_to_struct; 222 struct role_datum **role_val_to_struct;
219 struct user_datum **user_val_to_struct; 223 struct user_datum **user_val_to_struct;
220 struct type_datum **type_val_to_struct; 224 struct flex_array *type_val_to_struct_array;
221 225
222 /* type enforcement access vectors and transitions */ 226 /* type enforcement access vectors and transitions */
223 struct avtab te_avtab; 227 struct avtab te_avtab;
@@ -225,6 +229,12 @@ struct policydb {
225 /* role transitions */ 229 /* role transitions */
226 struct role_trans *role_tr; 230 struct role_trans *role_tr;
227 231
232 /* file transitions with the last path component */
233 /* quickly exclude lookups when parent ttype has no rules */
234 struct ebitmap filename_trans_ttypes;
235 /* actual set of filename_trans rules */
236 struct hashtab *filename_trans;
237
228 /* bools indexed by (value - 1) */ 238 /* bools indexed by (value - 1) */
229 struct cond_bool_datum **bool_val_to_struct; 239 struct cond_bool_datum **bool_val_to_struct;
230 /* type enforcement conditional access vectors and transitions */ 240 /* type enforcement conditional access vectors and transitions */
@@ -254,6 +264,9 @@ struct policydb {
254 264
255 struct ebitmap permissive_map; 265 struct ebitmap permissive_map;
256 266
267 /* length of this policy when it was loaded */
268 size_t len;
269
257 unsigned int policyvers; 270 unsigned int policyvers;
258 271
259 unsigned int reject_unknown : 1; 272 unsigned int reject_unknown : 1;
@@ -270,6 +283,7 @@ extern int policydb_class_isvalid(struct policydb *p, unsigned int class);
270extern int policydb_type_isvalid(struct policydb *p, unsigned int type); 283extern int policydb_type_isvalid(struct policydb *p, unsigned int type);
271extern int policydb_role_isvalid(struct policydb *p, unsigned int role); 284extern int policydb_role_isvalid(struct policydb *p, unsigned int role);
272extern int policydb_read(struct policydb *p, void *fp); 285extern int policydb_read(struct policydb *p, void *fp);
286extern int policydb_write(struct policydb *p, void *fp);
273 287
274#define PERM_SYMTAB_SIZE 32 288#define PERM_SYMTAB_SIZE 32
275 289
@@ -290,6 +304,11 @@ struct policy_file {
290 size_t len; 304 size_t len;
291}; 305};
292 306
307struct policy_data {
308 struct policydb *p;
309 void *fp;
310};
311
293static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes) 312static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes)
294{ 313{
295 if (bytes > fp->len) 314 if (bytes > fp->len)
@@ -301,6 +320,24 @@ static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes)
301 return 0; 320 return 0;
302} 321}
303 322
323static inline int put_entry(const void *buf, size_t bytes, int num, struct policy_file *fp)
324{
325 size_t len = bytes * num;
326
327 memcpy(fp->data, buf, len);
328 fp->data += len;
329 fp->len -= len;
330
331 return 0;
332}
333
334static inline char *sym_name(struct policydb *p, unsigned int sym_num, unsigned int element_nr)
335{
336 struct flex_array *fa = p->sym_val_to_name[sym_num];
337
338 return flex_array_get_ptr(fa, element_nr);
339}
340
304extern u16 string_to_security_class(struct policydb *p, const char *name); 341extern u16 string_to_security_class(struct policydb *p, const char *name);
305extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name); 342extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name);
306 343
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 9ea2feca3cd4..973e00e34fa9 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -51,6 +51,7 @@
51#include <linux/mutex.h> 51#include <linux/mutex.h>
52#include <linux/selinux.h> 52#include <linux/selinux.h>
53#include <linux/flex_array.h> 53#include <linux/flex_array.h>
54#include <linux/vmalloc.h>
54#include <net/netlabel.h> 55#include <net/netlabel.h>
55 56
56#include "flask.h" 57#include "flask.h"
@@ -200,6 +201,21 @@ static u16 unmap_class(u16 tclass)
200 return tclass; 201 return tclass;
201} 202}
202 203
204/*
205 * Get kernel value for class from its policy value
206 */
207static u16 map_class(u16 pol_value)
208{
209 u16 i;
210
211 for (i = 1; i < current_mapping_size; i++) {
212 if (current_mapping[i].value == pol_value)
213 return i;
214 }
215
216 return SECCLASS_NULL;
217}
218
203static void map_decision(u16 tclass, struct av_decision *avd, 219static void map_decision(u16 tclass, struct av_decision *avd,
204 int allow_unknown) 220 int allow_unknown)
205{ 221{
@@ -463,7 +479,7 @@ static void security_dump_masked_av(struct context *scontext,
463 if (!permissions) 479 if (!permissions)
464 return; 480 return;
465 481
466 tclass_name = policydb.p_class_val_to_name[tclass - 1]; 482 tclass_name = sym_name(&policydb, SYM_CLASSES, tclass - 1);
467 tclass_dat = policydb.class_val_to_struct[tclass - 1]; 483 tclass_dat = policydb.class_val_to_struct[tclass - 1];
468 common_dat = tclass_dat->comdatum; 484 common_dat = tclass_dat->comdatum;
469 485
@@ -529,12 +545,18 @@ static void type_attribute_bounds_av(struct context *scontext,
529 struct context lo_scontext; 545 struct context lo_scontext;
530 struct context lo_tcontext; 546 struct context lo_tcontext;
531 struct av_decision lo_avd; 547 struct av_decision lo_avd;
532 struct type_datum *source 548 struct type_datum *source;
533 = policydb.type_val_to_struct[scontext->type - 1]; 549 struct type_datum *target;
534 struct type_datum *target
535 = policydb.type_val_to_struct[tcontext->type - 1];
536 u32 masked = 0; 550 u32 masked = 0;
537 551
552 source = flex_array_get_ptr(policydb.type_val_to_struct_array,
553 scontext->type - 1);
554 BUG_ON(!source);
555
556 target = flex_array_get_ptr(policydb.type_val_to_struct_array,
557 tcontext->type - 1);
558 BUG_ON(!target);
559
538 if (source->bounds) { 560 if (source->bounds) {
539 memset(&lo_avd, 0, sizeof(lo_avd)); 561 memset(&lo_avd, 0, sizeof(lo_avd));
540 562
@@ -700,16 +722,16 @@ static int security_validtrans_handle_fail(struct context *ocontext,
700 char *o = NULL, *n = NULL, *t = NULL; 722 char *o = NULL, *n = NULL, *t = NULL;
701 u32 olen, nlen, tlen; 723 u32 olen, nlen, tlen;
702 724
703 if (context_struct_to_string(ocontext, &o, &olen) < 0) 725 if (context_struct_to_string(ocontext, &o, &olen))
704 goto out; 726 goto out;
705 if (context_struct_to_string(ncontext, &n, &nlen) < 0) 727 if (context_struct_to_string(ncontext, &n, &nlen))
706 goto out; 728 goto out;
707 if (context_struct_to_string(tcontext, &t, &tlen) < 0) 729 if (context_struct_to_string(tcontext, &t, &tlen))
708 goto out; 730 goto out;
709 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, 731 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
710 "security_validate_transition: denied for" 732 "security_validate_transition: denied for"
711 " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s", 733 " oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
712 o, n, t, policydb.p_class_val_to_name[tclass-1]); 734 o, n, t, sym_name(&policydb, SYM_CLASSES, tclass-1));
713out: 735out:
714 kfree(o); 736 kfree(o);
715 kfree(n); 737 kfree(n);
@@ -800,10 +822,11 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
800 struct context *old_context, *new_context; 822 struct context *old_context, *new_context;
801 struct type_datum *type; 823 struct type_datum *type;
802 int index; 824 int index;
803 int rc = -EINVAL; 825 int rc;
804 826
805 read_lock(&policy_rwlock); 827 read_lock(&policy_rwlock);
806 828
829 rc = -EINVAL;
807 old_context = sidtab_search(&sidtab, old_sid); 830 old_context = sidtab_search(&sidtab, old_sid);
808 if (!old_context) { 831 if (!old_context) {
809 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", 832 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n",
@@ -811,6 +834,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
811 goto out; 834 goto out;
812 } 835 }
813 836
837 rc = -EINVAL;
814 new_context = sidtab_search(&sidtab, new_sid); 838 new_context = sidtab_search(&sidtab, new_sid);
815 if (!new_context) { 839 if (!new_context) {
816 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n", 840 printk(KERN_ERR "SELinux: %s: unrecognized SID %u\n",
@@ -818,28 +842,27 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
818 goto out; 842 goto out;
819 } 843 }
820 844
845 rc = 0;
821 /* type/domain unchanged */ 846 /* type/domain unchanged */
822 if (old_context->type == new_context->type) { 847 if (old_context->type == new_context->type)
823 rc = 0;
824 goto out; 848 goto out;
825 }
826 849
827 index = new_context->type; 850 index = new_context->type;
828 while (true) { 851 while (true) {
829 type = policydb.type_val_to_struct[index - 1]; 852 type = flex_array_get_ptr(policydb.type_val_to_struct_array,
853 index - 1);
830 BUG_ON(!type); 854 BUG_ON(!type);
831 855
832 /* not bounded anymore */ 856 /* not bounded anymore */
833 if (!type->bounds) { 857 rc = -EPERM;
834 rc = -EPERM; 858 if (!type->bounds)
835 break; 859 break;
836 }
837 860
838 /* @newsid is bounded by @oldsid */ 861 /* @newsid is bounded by @oldsid */
839 if (type->bounds == old_context->type) { 862 rc = 0;
840 rc = 0; 863 if (type->bounds == old_context->type)
841 break; 864 break;
842 } 865
843 index = type->bounds; 866 index = type->bounds;
844 } 867 }
845 868
@@ -991,7 +1014,8 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
991{ 1014{
992 char *scontextp; 1015 char *scontextp;
993 1016
994 *scontext = NULL; 1017 if (scontext)
1018 *scontext = NULL;
995 *scontext_len = 0; 1019 *scontext_len = 0;
996 1020
997 if (context->len) { 1021 if (context->len) {
@@ -1003,11 +1027,14 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
1003 } 1027 }
1004 1028
1005 /* Compute the size of the context. */ 1029 /* Compute the size of the context. */
1006 *scontext_len += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1; 1030 *scontext_len += strlen(sym_name(&policydb, SYM_USERS, context->user - 1)) + 1;
1007 *scontext_len += strlen(policydb.p_role_val_to_name[context->role - 1]) + 1; 1031 *scontext_len += strlen(sym_name(&policydb, SYM_ROLES, context->role - 1)) + 1;
1008 *scontext_len += strlen(policydb.p_type_val_to_name[context->type - 1]) + 1; 1032 *scontext_len += strlen(sym_name(&policydb, SYM_TYPES, context->type - 1)) + 1;
1009 *scontext_len += mls_compute_context_len(context); 1033 *scontext_len += mls_compute_context_len(context);
1010 1034
1035 if (!scontext)
1036 return 0;
1037
1011 /* Allocate space for the context; caller must free this space. */ 1038 /* Allocate space for the context; caller must free this space. */
1012 scontextp = kmalloc(*scontext_len, GFP_ATOMIC); 1039 scontextp = kmalloc(*scontext_len, GFP_ATOMIC);
1013 if (!scontextp) 1040 if (!scontextp)
@@ -1018,12 +1045,12 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
1018 * Copy the user name, role name and type name into the context. 1045 * Copy the user name, role name and type name into the context.
1019 */ 1046 */
1020 sprintf(scontextp, "%s:%s:%s", 1047 sprintf(scontextp, "%s:%s:%s",
1021 policydb.p_user_val_to_name[context->user - 1], 1048 sym_name(&policydb, SYM_USERS, context->user - 1),
1022 policydb.p_role_val_to_name[context->role - 1], 1049 sym_name(&policydb, SYM_ROLES, context->role - 1),
1023 policydb.p_type_val_to_name[context->type - 1]); 1050 sym_name(&policydb, SYM_TYPES, context->type - 1));
1024 scontextp += strlen(policydb.p_user_val_to_name[context->user - 1]) + 1051 scontextp += strlen(sym_name(&policydb, SYM_USERS, context->user - 1)) +
1025 1 + strlen(policydb.p_role_val_to_name[context->role - 1]) + 1052 1 + strlen(sym_name(&policydb, SYM_ROLES, context->role - 1)) +
1026 1 + strlen(policydb.p_type_val_to_name[context->type - 1]); 1053 1 + strlen(sym_name(&policydb, SYM_TYPES, context->type - 1));
1027 1054
1028 mls_sid_to_context(context, &scontextp); 1055 mls_sid_to_context(context, &scontextp);
1029 1056
@@ -1047,7 +1074,8 @@ static int security_sid_to_context_core(u32 sid, char **scontext,
1047 struct context *context; 1074 struct context *context;
1048 int rc = 0; 1075 int rc = 0;
1049 1076
1050 *scontext = NULL; 1077 if (scontext)
1078 *scontext = NULL;
1051 *scontext_len = 0; 1079 *scontext_len = 0;
1052 1080
1053 if (!ss_initialized) { 1081 if (!ss_initialized) {
@@ -1055,6 +1083,8 @@ static int security_sid_to_context_core(u32 sid, char **scontext,
1055 char *scontextp; 1083 char *scontextp;
1056 1084
1057 *scontext_len = strlen(initial_sid_to_string[sid]) + 1; 1085 *scontext_len = strlen(initial_sid_to_string[sid]) + 1;
1086 if (!scontext)
1087 goto out;
1058 scontextp = kmalloc(*scontext_len, GFP_ATOMIC); 1088 scontextp = kmalloc(*scontext_len, GFP_ATOMIC);
1059 if (!scontextp) { 1089 if (!scontextp) {
1060 rc = -ENOMEM; 1090 rc = -ENOMEM;
@@ -1179,16 +1209,13 @@ static int string_to_context_struct(struct policydb *pol,
1179 if (rc) 1209 if (rc)
1180 goto out; 1210 goto out;
1181 1211
1182 if ((p - scontext) < scontext_len) { 1212 rc = -EINVAL;
1183 rc = -EINVAL; 1213 if ((p - scontext) < scontext_len)
1184 goto out; 1214 goto out;
1185 }
1186 1215
1187 /* Check the validity of the new context. */ 1216 /* Check the validity of the new context. */
1188 if (!policydb_context_isvalid(pol, ctx)) { 1217 if (!policydb_context_isvalid(pol, ctx))
1189 rc = -EINVAL;
1190 goto out; 1218 goto out;
1191 }
1192 rc = 0; 1219 rc = 0;
1193out: 1220out:
1194 if (rc) 1221 if (rc)
@@ -1227,27 +1254,26 @@ static int security_context_to_sid_core(const char *scontext, u32 scontext_len,
1227 1254
1228 if (force) { 1255 if (force) {
1229 /* Save another copy for storing in uninterpreted form */ 1256 /* Save another copy for storing in uninterpreted form */
1257 rc = -ENOMEM;
1230 str = kstrdup(scontext2, gfp_flags); 1258 str = kstrdup(scontext2, gfp_flags);
1231 if (!str) { 1259 if (!str)
1232 kfree(scontext2); 1260 goto out;
1233 return -ENOMEM;
1234 }
1235 } 1261 }
1236 1262
1237 read_lock(&policy_rwlock); 1263 read_lock(&policy_rwlock);
1238 rc = string_to_context_struct(&policydb, &sidtab, 1264 rc = string_to_context_struct(&policydb, &sidtab, scontext2,
1239 scontext2, scontext_len, 1265 scontext_len, &context, def_sid);
1240 &context, def_sid);
1241 if (rc == -EINVAL && force) { 1266 if (rc == -EINVAL && force) {
1242 context.str = str; 1267 context.str = str;
1243 context.len = scontext_len; 1268 context.len = scontext_len;
1244 str = NULL; 1269 str = NULL;
1245 } else if (rc) 1270 } else if (rc)
1246 goto out; 1271 goto out_unlock;
1247 rc = sidtab_context_to_sid(&sidtab, &context, sid); 1272 rc = sidtab_context_to_sid(&sidtab, &context, sid);
1248 context_destroy(&context); 1273 context_destroy(&context);
1249out: 1274out_unlock:
1250 read_unlock(&policy_rwlock); 1275 read_unlock(&policy_rwlock);
1276out:
1251 kfree(scontext2); 1277 kfree(scontext2);
1252 kfree(str); 1278 kfree(str);
1253 return rc; 1279 return rc;
@@ -1311,18 +1337,18 @@ static int compute_sid_handle_invalid_context(
1311 char *s = NULL, *t = NULL, *n = NULL; 1337 char *s = NULL, *t = NULL, *n = NULL;
1312 u32 slen, tlen, nlen; 1338 u32 slen, tlen, nlen;
1313 1339
1314 if (context_struct_to_string(scontext, &s, &slen) < 0) 1340 if (context_struct_to_string(scontext, &s, &slen))
1315 goto out; 1341 goto out;
1316 if (context_struct_to_string(tcontext, &t, &tlen) < 0) 1342 if (context_struct_to_string(tcontext, &t, &tlen))
1317 goto out; 1343 goto out;
1318 if (context_struct_to_string(newcontext, &n, &nlen) < 0) 1344 if (context_struct_to_string(newcontext, &n, &nlen))
1319 goto out; 1345 goto out;
1320 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR, 1346 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
1321 "security_compute_sid: invalid context %s" 1347 "security_compute_sid: invalid context %s"
1322 " for scontext=%s" 1348 " for scontext=%s"
1323 " tcontext=%s" 1349 " tcontext=%s"
1324 " tclass=%s", 1350 " tclass=%s",
1325 n, s, t, policydb.p_class_val_to_name[tclass-1]); 1351 n, s, t, sym_name(&policydb, SYM_CLASSES, tclass-1));
1326out: 1352out:
1327 kfree(s); 1353 kfree(s);
1328 kfree(t); 1354 kfree(t);
@@ -1332,10 +1358,36 @@ out:
1332 return -EACCES; 1358 return -EACCES;
1333} 1359}
1334 1360
1361static void filename_compute_type(struct policydb *p, struct context *newcontext,
1362 u32 stype, u32 ttype, u16 tclass,
1363 const char *objname)
1364{
1365 struct filename_trans ft;
1366 struct filename_trans_datum *otype;
1367
1368 /*
1369 * Most filename trans rules are going to live in specific directories
1370 * like /dev or /var/run. This bitmap will quickly skip rule searches
1371 * if the ttype does not contain any rules.
1372 */
1373 if (!ebitmap_get_bit(&p->filename_trans_ttypes, ttype))
1374 return;
1375
1376 ft.stype = stype;
1377 ft.ttype = ttype;
1378 ft.tclass = tclass;
1379 ft.name = objname;
1380
1381 otype = hashtab_search(p->filename_trans, &ft);
1382 if (otype)
1383 newcontext->type = otype->otype;
1384}
1385
1335static int security_compute_sid(u32 ssid, 1386static int security_compute_sid(u32 ssid,
1336 u32 tsid, 1387 u32 tsid,
1337 u16 orig_tclass, 1388 u16 orig_tclass,
1338 u32 specified, 1389 u32 specified,
1390 const char *objname,
1339 u32 *out_sid, 1391 u32 *out_sid,
1340 bool kern) 1392 bool kern)
1341{ 1393{
@@ -1346,6 +1398,7 @@ static int security_compute_sid(u32 ssid,
1346 struct avtab_node *node; 1398 struct avtab_node *node;
1347 u16 tclass; 1399 u16 tclass;
1348 int rc = 0; 1400 int rc = 0;
1401 bool sock;
1349 1402
1350 if (!ss_initialized) { 1403 if (!ss_initialized) {
1351 switch (orig_tclass) { 1404 switch (orig_tclass) {
@@ -1363,10 +1416,13 @@ static int security_compute_sid(u32 ssid,
1363 1416
1364 read_lock(&policy_rwlock); 1417 read_lock(&policy_rwlock);
1365 1418
1366 if (kern) 1419 if (kern) {
1367 tclass = unmap_class(orig_tclass); 1420 tclass = unmap_class(orig_tclass);
1368 else 1421 sock = security_is_socket_class(orig_tclass);
1422 } else {
1369 tclass = orig_tclass; 1423 tclass = orig_tclass;
1424 sock = security_is_socket_class(map_class(tclass));
1425 }
1370 1426
1371 scontext = sidtab_search(&sidtab, ssid); 1427 scontext = sidtab_search(&sidtab, ssid);
1372 if (!scontext) { 1428 if (!scontext) {
@@ -1397,7 +1453,7 @@ static int security_compute_sid(u32 ssid,
1397 } 1453 }
1398 1454
1399 /* Set the role and type to default values. */ 1455 /* Set the role and type to default values. */
1400 if (tclass == policydb.process_class) { 1456 if ((tclass == policydb.process_class) || (sock == true)) {
1401 /* Use the current role and type of process. */ 1457 /* Use the current role and type of process. */
1402 newcontext.role = scontext->role; 1458 newcontext.role = scontext->role;
1403 newcontext.type = scontext->type; 1459 newcontext.type = scontext->type;
@@ -1431,25 +1487,29 @@ static int security_compute_sid(u32 ssid,
1431 newcontext.type = avdatum->data; 1487 newcontext.type = avdatum->data;
1432 } 1488 }
1433 1489
1490 /* if we have a objname this is a file trans check so check those rules */
1491 if (objname)
1492 filename_compute_type(&policydb, &newcontext, scontext->type,
1493 tcontext->type, tclass, objname);
1494
1434 /* Check for class-specific changes. */ 1495 /* Check for class-specific changes. */
1435 if (tclass == policydb.process_class) { 1496 if (specified & AVTAB_TRANSITION) {
1436 if (specified & AVTAB_TRANSITION) { 1497 /* Look for a role transition rule. */
1437 /* Look for a role transition rule. */ 1498 for (roletr = policydb.role_tr; roletr; roletr = roletr->next) {
1438 for (roletr = policydb.role_tr; roletr; 1499 if ((roletr->role == scontext->role) &&
1439 roletr = roletr->next) { 1500 (roletr->type == tcontext->type) &&
1440 if (roletr->role == scontext->role && 1501 (roletr->tclass == tclass)) {
1441 roletr->type == tcontext->type) { 1502 /* Use the role transition rule. */
1442 /* Use the role transition rule. */ 1503 newcontext.role = roletr->new_role;
1443 newcontext.role = roletr->new_role; 1504 break;
1444 break;
1445 }
1446 } 1505 }
1447 } 1506 }
1448 } 1507 }
1449 1508
1450 /* Set the MLS attributes. 1509 /* Set the MLS attributes.
1451 This is done last because it may allocate memory. */ 1510 This is done last because it may allocate memory. */
1452 rc = mls_compute_sid(scontext, tcontext, tclass, specified, &newcontext); 1511 rc = mls_compute_sid(scontext, tcontext, tclass, specified,
1512 &newcontext, sock);
1453 if (rc) 1513 if (rc)
1454 goto out_unlock; 1514 goto out_unlock;
1455 1515
@@ -1484,22 +1544,18 @@ out:
1484 * if insufficient memory is available, or %0 if the new SID was 1544 * if insufficient memory is available, or %0 if the new SID was
1485 * computed successfully. 1545 * computed successfully.
1486 */ 1546 */
1487int security_transition_sid(u32 ssid, 1547int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
1488 u32 tsid, 1548 const struct qstr *qstr, u32 *out_sid)
1489 u16 tclass,
1490 u32 *out_sid)
1491{ 1549{
1492 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, 1550 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1493 out_sid, true); 1551 qstr ? qstr->name : NULL, out_sid, true);
1494} 1552}
1495 1553
1496int security_transition_sid_user(u32 ssid, 1554int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
1497 u32 tsid, 1555 const char *objname, u32 *out_sid)
1498 u16 tclass,
1499 u32 *out_sid)
1500{ 1556{
1501 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, 1557 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1502 out_sid, false); 1558 objname, out_sid, false);
1503} 1559}
1504 1560
1505/** 1561/**
@@ -1520,8 +1576,8 @@ int security_member_sid(u32 ssid,
1520 u16 tclass, 1576 u16 tclass,
1521 u32 *out_sid) 1577 u32 *out_sid)
1522{ 1578{
1523 return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid, 1579 return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, NULL,
1524 false); 1580 out_sid, false);
1525} 1581}
1526 1582
1527/** 1583/**
@@ -1542,8 +1598,8 @@ int security_change_sid(u32 ssid,
1542 u16 tclass, 1598 u16 tclass,
1543 u32 *out_sid) 1599 u32 *out_sid)
1544{ 1600{
1545 return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid, 1601 return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, NULL,
1546 false); 1602 out_sid, false);
1547} 1603}
1548 1604
1549/* Clone the SID into the new SID table. */ 1605/* Clone the SID into the new SID table. */
@@ -1561,22 +1617,17 @@ static int clone_sid(u32 sid,
1561 1617
1562static inline int convert_context_handle_invalid_context(struct context *context) 1618static inline int convert_context_handle_invalid_context(struct context *context)
1563{ 1619{
1564 int rc = 0; 1620 char *s;
1621 u32 len;
1565 1622
1566 if (selinux_enforcing) { 1623 if (selinux_enforcing)
1567 rc = -EINVAL; 1624 return -EINVAL;
1568 } else { 1625
1569 char *s; 1626 if (!context_struct_to_string(context, &s, &len)) {
1570 u32 len; 1627 printk(KERN_WARNING "SELinux: Context %s would be invalid if enforcing\n", s);
1571 1628 kfree(s);
1572 if (!context_struct_to_string(context, &s, &len)) {
1573 printk(KERN_WARNING
1574 "SELinux: Context %s would be invalid if enforcing\n",
1575 s);
1576 kfree(s);
1577 }
1578 } 1629 }
1579 return rc; 1630 return 0;
1580} 1631}
1581 1632
1582struct convert_context_args { 1633struct convert_context_args {
@@ -1613,17 +1664,17 @@ static int convert_context(u32 key,
1613 1664
1614 if (c->str) { 1665 if (c->str) {
1615 struct context ctx; 1666 struct context ctx;
1667
1668 rc = -ENOMEM;
1616 s = kstrdup(c->str, GFP_KERNEL); 1669 s = kstrdup(c->str, GFP_KERNEL);
1617 if (!s) { 1670 if (!s)
1618 rc = -ENOMEM;
1619 goto out; 1671 goto out;
1620 } 1672
1621 rc = string_to_context_struct(args->newp, NULL, s, 1673 rc = string_to_context_struct(args->newp, NULL, s,
1622 c->len, &ctx, SECSID_NULL); 1674 c->len, &ctx, SECSID_NULL);
1623 kfree(s); 1675 kfree(s);
1624 if (!rc) { 1676 if (!rc) {
1625 printk(KERN_INFO 1677 printk(KERN_INFO "SELinux: Context %s became valid (mapped).\n",
1626 "SELinux: Context %s became valid (mapped).\n",
1627 c->str); 1678 c->str);
1628 /* Replace string with mapped representation. */ 1679 /* Replace string with mapped representation. */
1629 kfree(c->str); 1680 kfree(c->str);
@@ -1635,8 +1686,7 @@ static int convert_context(u32 key,
1635 goto out; 1686 goto out;
1636 } else { 1687 } else {
1637 /* Other error condition, e.g. ENOMEM. */ 1688 /* Other error condition, e.g. ENOMEM. */
1638 printk(KERN_ERR 1689 printk(KERN_ERR "SELinux: Unable to map context %s, rc = %d.\n",
1639 "SELinux: Unable to map context %s, rc = %d.\n",
1640 c->str, -rc); 1690 c->str, -rc);
1641 goto out; 1691 goto out;
1642 } 1692 }
@@ -1646,25 +1696,26 @@ static int convert_context(u32 key,
1646 if (rc) 1696 if (rc)
1647 goto out; 1697 goto out;
1648 1698
1649 rc = -EINVAL;
1650
1651 /* Convert the user. */ 1699 /* Convert the user. */
1700 rc = -EINVAL;
1652 usrdatum = hashtab_search(args->newp->p_users.table, 1701 usrdatum = hashtab_search(args->newp->p_users.table,
1653 args->oldp->p_user_val_to_name[c->user - 1]); 1702 sym_name(args->oldp, SYM_USERS, c->user - 1));
1654 if (!usrdatum) 1703 if (!usrdatum)
1655 goto bad; 1704 goto bad;
1656 c->user = usrdatum->value; 1705 c->user = usrdatum->value;
1657 1706
1658 /* Convert the role. */ 1707 /* Convert the role. */
1708 rc = -EINVAL;
1659 role = hashtab_search(args->newp->p_roles.table, 1709 role = hashtab_search(args->newp->p_roles.table,
1660 args->oldp->p_role_val_to_name[c->role - 1]); 1710 sym_name(args->oldp, SYM_ROLES, c->role - 1));
1661 if (!role) 1711 if (!role)
1662 goto bad; 1712 goto bad;
1663 c->role = role->value; 1713 c->role = role->value;
1664 1714
1665 /* Convert the type. */ 1715 /* Convert the type. */
1716 rc = -EINVAL;
1666 typdatum = hashtab_search(args->newp->p_types.table, 1717 typdatum = hashtab_search(args->newp->p_types.table,
1667 args->oldp->p_type_val_to_name[c->type - 1]); 1718 sym_name(args->oldp, SYM_TYPES, c->type - 1));
1668 if (!typdatum) 1719 if (!typdatum)
1669 goto bad; 1720 goto bad;
1670 c->type = typdatum->value; 1721 c->type = typdatum->value;
@@ -1692,6 +1743,7 @@ static int convert_context(u32 key,
1692 oc = args->newp->ocontexts[OCON_ISID]; 1743 oc = args->newp->ocontexts[OCON_ISID];
1693 while (oc && oc->sid[0] != SECINITSID_UNLABELED) 1744 while (oc && oc->sid[0] != SECINITSID_UNLABELED)
1694 oc = oc->next; 1745 oc = oc->next;
1746 rc = -EINVAL;
1695 if (!oc) { 1747 if (!oc) {
1696 printk(KERN_ERR "SELinux: unable to look up" 1748 printk(KERN_ERR "SELinux: unable to look up"
1697 " the initial SIDs list\n"); 1749 " the initial SIDs list\n");
@@ -1711,19 +1763,20 @@ static int convert_context(u32 key,
1711 } 1763 }
1712 1764
1713 context_destroy(&oldc); 1765 context_destroy(&oldc);
1766
1714 rc = 0; 1767 rc = 0;
1715out: 1768out:
1716 return rc; 1769 return rc;
1717bad: 1770bad:
1718 /* Map old representation to string and save it. */ 1771 /* Map old representation to string and save it. */
1719 if (context_struct_to_string(&oldc, &s, &len)) 1772 rc = context_struct_to_string(&oldc, &s, &len);
1720 return -ENOMEM; 1773 if (rc)
1774 return rc;
1721 context_destroy(&oldc); 1775 context_destroy(&oldc);
1722 context_destroy(c); 1776 context_destroy(c);
1723 c->str = s; 1777 c->str = s;
1724 c->len = len; 1778 c->len = len;
1725 printk(KERN_INFO 1779 printk(KERN_INFO "SELinux: Context %s became invalid (unmapped).\n",
1726 "SELinux: Context %s became invalid (unmapped).\n",
1727 c->str); 1780 c->str);
1728 rc = 0; 1781 rc = 0;
1729 goto out; 1782 goto out;
@@ -1769,6 +1822,7 @@ int security_load_policy(void *data, size_t len)
1769 return rc; 1822 return rc;
1770 } 1823 }
1771 1824
1825 policydb.len = len;
1772 rc = selinux_set_mapping(&policydb, secclass_map, 1826 rc = selinux_set_mapping(&policydb, secclass_map,
1773 &current_mapping, 1827 &current_mapping,
1774 &current_mapping_size); 1828 &current_mapping_size);
@@ -1791,6 +1845,7 @@ int security_load_policy(void *data, size_t len)
1791 selinux_complete_init(); 1845 selinux_complete_init();
1792 avc_ss_reset(seqno); 1846 avc_ss_reset(seqno);
1793 selnl_notify_policyload(seqno); 1847 selnl_notify_policyload(seqno);
1848 selinux_status_update_policyload(seqno);
1794 selinux_netlbl_cache_invalidate(); 1849 selinux_netlbl_cache_invalidate();
1795 selinux_xfrm_notify_policyload(); 1850 selinux_xfrm_notify_policyload();
1796 return 0; 1851 return 0;
@@ -1804,6 +1859,7 @@ int security_load_policy(void *data, size_t len)
1804 if (rc) 1859 if (rc)
1805 return rc; 1860 return rc;
1806 1861
1862 newpolicydb.len = len;
1807 /* If switching between different policy types, log MLS status */ 1863 /* If switching between different policy types, log MLS status */
1808 if (policydb.mls_enabled && !newpolicydb.mls_enabled) 1864 if (policydb.mls_enabled && !newpolicydb.mls_enabled)
1809 printk(KERN_INFO "SELinux: Disabling MLS support...\n"); 1865 printk(KERN_INFO "SELinux: Disabling MLS support...\n");
@@ -1870,6 +1926,7 @@ int security_load_policy(void *data, size_t len)
1870 1926
1871 avc_ss_reset(seqno); 1927 avc_ss_reset(seqno);
1872 selnl_notify_policyload(seqno); 1928 selnl_notify_policyload(seqno);
1929 selinux_status_update_policyload(seqno);
1873 selinux_netlbl_cache_invalidate(); 1930 selinux_netlbl_cache_invalidate();
1874 selinux_xfrm_notify_policyload(); 1931 selinux_xfrm_notify_policyload();
1875 1932
@@ -1883,6 +1940,17 @@ err:
1883 1940
1884} 1941}
1885 1942
1943size_t security_policydb_len(void)
1944{
1945 size_t len;
1946
1947 read_lock(&policy_rwlock);
1948 len = policydb.len;
1949 read_unlock(&policy_rwlock);
1950
1951 return len;
1952}
1953
1886/** 1954/**
1887 * security_port_sid - Obtain the SID for a port. 1955 * security_port_sid - Obtain the SID for a port.
1888 * @protocol: protocol number 1956 * @protocol: protocol number
@@ -1989,7 +2057,7 @@ int security_node_sid(u16 domain,
1989 u32 addrlen, 2057 u32 addrlen,
1990 u32 *out_sid) 2058 u32 *out_sid)
1991{ 2059{
1992 int rc = 0; 2060 int rc;
1993 struct ocontext *c; 2061 struct ocontext *c;
1994 2062
1995 read_lock(&policy_rwlock); 2063 read_lock(&policy_rwlock);
@@ -1998,10 +2066,9 @@ int security_node_sid(u16 domain,
1998 case AF_INET: { 2066 case AF_INET: {
1999 u32 addr; 2067 u32 addr;
2000 2068
2001 if (addrlen != sizeof(u32)) { 2069 rc = -EINVAL;
2002 rc = -EINVAL; 2070 if (addrlen != sizeof(u32))
2003 goto out; 2071 goto out;
2004 }
2005 2072
2006 addr = *((u32 *)addrp); 2073 addr = *((u32 *)addrp);
2007 2074
@@ -2015,10 +2082,9 @@ int security_node_sid(u16 domain,
2015 } 2082 }
2016 2083
2017 case AF_INET6: 2084 case AF_INET6:
2018 if (addrlen != sizeof(u64) * 2) { 2085 rc = -EINVAL;
2019 rc = -EINVAL; 2086 if (addrlen != sizeof(u64) * 2)
2020 goto out; 2087 goto out;
2021 }
2022 c = policydb.ocontexts[OCON_NODE6]; 2088 c = policydb.ocontexts[OCON_NODE6];
2023 while (c) { 2089 while (c) {
2024 if (match_ipv6_addrmask(addrp, c->u.node6.addr, 2090 if (match_ipv6_addrmask(addrp, c->u.node6.addr,
@@ -2029,6 +2095,7 @@ int security_node_sid(u16 domain,
2029 break; 2095 break;
2030 2096
2031 default: 2097 default:
2098 rc = 0;
2032 *out_sid = SECINITSID_NODE; 2099 *out_sid = SECINITSID_NODE;
2033 goto out; 2100 goto out;
2034 } 2101 }
@@ -2046,6 +2113,7 @@ int security_node_sid(u16 domain,
2046 *out_sid = SECINITSID_NODE; 2113 *out_sid = SECINITSID_NODE;
2047 } 2114 }
2048 2115
2116 rc = 0;
2049out: 2117out:
2050 read_unlock(&policy_rwlock); 2118 read_unlock(&policy_rwlock);
2051 return rc; 2119 return rc;
@@ -2090,24 +2158,22 @@ int security_get_user_sids(u32 fromsid,
2090 2158
2091 context_init(&usercon); 2159 context_init(&usercon);
2092 2160
2161 rc = -EINVAL;
2093 fromcon = sidtab_search(&sidtab, fromsid); 2162 fromcon = sidtab_search(&sidtab, fromsid);
2094 if (!fromcon) { 2163 if (!fromcon)
2095 rc = -EINVAL;
2096 goto out_unlock; 2164 goto out_unlock;
2097 }
2098 2165
2166 rc = -EINVAL;
2099 user = hashtab_search(policydb.p_users.table, username); 2167 user = hashtab_search(policydb.p_users.table, username);
2100 if (!user) { 2168 if (!user)
2101 rc = -EINVAL;
2102 goto out_unlock; 2169 goto out_unlock;
2103 } 2170
2104 usercon.user = user->value; 2171 usercon.user = user->value;
2105 2172
2173 rc = -ENOMEM;
2106 mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC); 2174 mysids = kcalloc(maxnel, sizeof(*mysids), GFP_ATOMIC);
2107 if (!mysids) { 2175 if (!mysids)
2108 rc = -ENOMEM;
2109 goto out_unlock; 2176 goto out_unlock;
2110 }
2111 2177
2112 ebitmap_for_each_positive_bit(&user->roles, rnode, i) { 2178 ebitmap_for_each_positive_bit(&user->roles, rnode, i) {
2113 role = policydb.role_val_to_struct[i]; 2179 role = policydb.role_val_to_struct[i];
@@ -2124,12 +2190,11 @@ int security_get_user_sids(u32 fromsid,
2124 if (mynel < maxnel) { 2190 if (mynel < maxnel) {
2125 mysids[mynel++] = sid; 2191 mysids[mynel++] = sid;
2126 } else { 2192 } else {
2193 rc = -ENOMEM;
2127 maxnel += SIDS_NEL; 2194 maxnel += SIDS_NEL;
2128 mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC); 2195 mysids2 = kcalloc(maxnel, sizeof(*mysids2), GFP_ATOMIC);
2129 if (!mysids2) { 2196 if (!mysids2)
2130 rc = -ENOMEM;
2131 goto out_unlock; 2197 goto out_unlock;
2132 }
2133 memcpy(mysids2, mysids, mynel * sizeof(*mysids2)); 2198 memcpy(mysids2, mysids, mynel * sizeof(*mysids2));
2134 kfree(mysids); 2199 kfree(mysids);
2135 mysids = mysids2; 2200 mysids = mysids2;
@@ -2137,7 +2202,7 @@ int security_get_user_sids(u32 fromsid,
2137 } 2202 }
2138 } 2203 }
2139 } 2204 }
2140 2205 rc = 0;
2141out_unlock: 2206out_unlock:
2142 read_unlock(&policy_rwlock); 2207 read_unlock(&policy_rwlock);
2143 if (rc || !mynel) { 2208 if (rc || !mynel) {
@@ -2145,17 +2210,18 @@ out_unlock:
2145 goto out; 2210 goto out;
2146 } 2211 }
2147 2212
2213 rc = -ENOMEM;
2148 mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL); 2214 mysids2 = kcalloc(mynel, sizeof(*mysids2), GFP_KERNEL);
2149 if (!mysids2) { 2215 if (!mysids2) {
2150 rc = -ENOMEM;
2151 kfree(mysids); 2216 kfree(mysids);
2152 goto out; 2217 goto out;
2153 } 2218 }
2154 for (i = 0, j = 0; i < mynel; i++) { 2219 for (i = 0, j = 0; i < mynel; i++) {
2220 struct av_decision dummy_avd;
2155 rc = avc_has_perm_noaudit(fromsid, mysids[i], 2221 rc = avc_has_perm_noaudit(fromsid, mysids[i],
2156 SECCLASS_PROCESS, /* kernel value */ 2222 SECCLASS_PROCESS, /* kernel value */
2157 PROCESS__TRANSITION, AVC_STRICT, 2223 PROCESS__TRANSITION, AVC_STRICT,
2158 NULL); 2224 &dummy_avd);
2159 if (!rc) 2225 if (!rc)
2160 mysids2[j++] = mysids[i]; 2226 mysids2[j++] = mysids[i];
2161 cond_resched(); 2227 cond_resched();
@@ -2188,7 +2254,7 @@ int security_genfs_sid(const char *fstype,
2188 u16 sclass; 2254 u16 sclass;
2189 struct genfs *genfs; 2255 struct genfs *genfs;
2190 struct ocontext *c; 2256 struct ocontext *c;
2191 int rc = 0, cmp = 0; 2257 int rc, cmp = 0;
2192 2258
2193 while (path[0] == '/' && path[1] == '/') 2259 while (path[0] == '/' && path[1] == '/')
2194 path++; 2260 path++;
@@ -2196,6 +2262,7 @@ int security_genfs_sid(const char *fstype,
2196 read_lock(&policy_rwlock); 2262 read_lock(&policy_rwlock);
2197 2263
2198 sclass = unmap_class(orig_sclass); 2264 sclass = unmap_class(orig_sclass);
2265 *sid = SECINITSID_UNLABELED;
2199 2266
2200 for (genfs = policydb.genfs; genfs; genfs = genfs->next) { 2267 for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
2201 cmp = strcmp(fstype, genfs->fstype); 2268 cmp = strcmp(fstype, genfs->fstype);
@@ -2203,11 +2270,9 @@ int security_genfs_sid(const char *fstype,
2203 break; 2270 break;
2204 } 2271 }
2205 2272
2206 if (!genfs || cmp) { 2273 rc = -ENOENT;
2207 *sid = SECINITSID_UNLABELED; 2274 if (!genfs || cmp)
2208 rc = -ENOENT;
2209 goto out; 2275 goto out;
2210 }
2211 2276
2212 for (c = genfs->head; c; c = c->next) { 2277 for (c = genfs->head; c; c = c->next) {
2213 len = strlen(c->u.name); 2278 len = strlen(c->u.name);
@@ -2216,21 +2281,18 @@ int security_genfs_sid(const char *fstype,
2216 break; 2281 break;
2217 } 2282 }
2218 2283
2219 if (!c) { 2284 rc = -ENOENT;
2220 *sid = SECINITSID_UNLABELED; 2285 if (!c)
2221 rc = -ENOENT;
2222 goto out; 2286 goto out;
2223 }
2224 2287
2225 if (!c->sid[0]) { 2288 if (!c->sid[0]) {
2226 rc = sidtab_context_to_sid(&sidtab, 2289 rc = sidtab_context_to_sid(&sidtab, &c->context[0], &c->sid[0]);
2227 &c->context[0],
2228 &c->sid[0]);
2229 if (rc) 2290 if (rc)
2230 goto out; 2291 goto out;
2231 } 2292 }
2232 2293
2233 *sid = c->sid[0]; 2294 *sid = c->sid[0];
2295 rc = 0;
2234out: 2296out:
2235 read_unlock(&policy_rwlock); 2297 read_unlock(&policy_rwlock);
2236 return rc; 2298 return rc;
@@ -2262,8 +2324,7 @@ int security_fs_use(
2262 if (c) { 2324 if (c) {
2263 *behavior = c->v.behavior; 2325 *behavior = c->v.behavior;
2264 if (!c->sid[0]) { 2326 if (!c->sid[0]) {
2265 rc = sidtab_context_to_sid(&sidtab, 2327 rc = sidtab_context_to_sid(&sidtab, &c->context[0],
2266 &c->context[0],
2267 &c->sid[0]); 2328 &c->sid[0]);
2268 if (rc) 2329 if (rc)
2269 goto out; 2330 goto out;
@@ -2286,34 +2347,39 @@ out:
2286 2347
2287int security_get_bools(int *len, char ***names, int **values) 2348int security_get_bools(int *len, char ***names, int **values)
2288{ 2349{
2289 int i, rc = -ENOMEM; 2350 int i, rc;
2290 2351
2291 read_lock(&policy_rwlock); 2352 read_lock(&policy_rwlock);
2292 *names = NULL; 2353 *names = NULL;
2293 *values = NULL; 2354 *values = NULL;
2294 2355
2356 rc = 0;
2295 *len = policydb.p_bools.nprim; 2357 *len = policydb.p_bools.nprim;
2296 if (!*len) { 2358 if (!*len)
2297 rc = 0;
2298 goto out; 2359 goto out;
2299 }
2300 2360
2301 *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC); 2361 rc = -ENOMEM;
2362 *names = kcalloc(*len, sizeof(char *), GFP_ATOMIC);
2302 if (!*names) 2363 if (!*names)
2303 goto err; 2364 goto err;
2304 2365
2305 *values = kcalloc(*len, sizeof(int), GFP_ATOMIC); 2366 rc = -ENOMEM;
2367 *values = kcalloc(*len, sizeof(int), GFP_ATOMIC);
2306 if (!*values) 2368 if (!*values)
2307 goto err; 2369 goto err;
2308 2370
2309 for (i = 0; i < *len; i++) { 2371 for (i = 0; i < *len; i++) {
2310 size_t name_len; 2372 size_t name_len;
2373
2311 (*values)[i] = policydb.bool_val_to_struct[i]->state; 2374 (*values)[i] = policydb.bool_val_to_struct[i]->state;
2312 name_len = strlen(policydb.p_bool_val_to_name[i]) + 1; 2375 name_len = strlen(sym_name(&policydb, SYM_BOOLS, i)) + 1;
2313 (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); 2376
2377 rc = -ENOMEM;
2378 (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC);
2314 if (!(*names)[i]) 2379 if (!(*names)[i])
2315 goto err; 2380 goto err;
2316 strncpy((*names)[i], policydb.p_bool_val_to_name[i], name_len); 2381
2382 strncpy((*names)[i], sym_name(&policydb, SYM_BOOLS, i), name_len);
2317 (*names)[i][name_len - 1] = 0; 2383 (*names)[i][name_len - 1] = 0;
2318 } 2384 }
2319 rc = 0; 2385 rc = 0;
@@ -2332,24 +2398,23 @@ err:
2332 2398
2333int security_set_bools(int len, int *values) 2399int security_set_bools(int len, int *values)
2334{ 2400{
2335 int i, rc = 0; 2401 int i, rc;
2336 int lenp, seqno = 0; 2402 int lenp, seqno = 0;
2337 struct cond_node *cur; 2403 struct cond_node *cur;
2338 2404
2339 write_lock_irq(&policy_rwlock); 2405 write_lock_irq(&policy_rwlock);
2340 2406
2407 rc = -EFAULT;
2341 lenp = policydb.p_bools.nprim; 2408 lenp = policydb.p_bools.nprim;
2342 if (len != lenp) { 2409 if (len != lenp)
2343 rc = -EFAULT;
2344 goto out; 2410 goto out;
2345 }
2346 2411
2347 for (i = 0; i < len; i++) { 2412 for (i = 0; i < len; i++) {
2348 if (!!values[i] != policydb.bool_val_to_struct[i]->state) { 2413 if (!!values[i] != policydb.bool_val_to_struct[i]->state) {
2349 audit_log(current->audit_context, GFP_ATOMIC, 2414 audit_log(current->audit_context, GFP_ATOMIC,
2350 AUDIT_MAC_CONFIG_CHANGE, 2415 AUDIT_MAC_CONFIG_CHANGE,
2351 "bool=%s val=%d old_val=%d auid=%u ses=%u", 2416 "bool=%s val=%d old_val=%d auid=%u ses=%u",
2352 policydb.p_bool_val_to_name[i], 2417 sym_name(&policydb, SYM_BOOLS, i),
2353 !!values[i], 2418 !!values[i],
2354 policydb.bool_val_to_struct[i]->state, 2419 policydb.bool_val_to_struct[i]->state,
2355 audit_get_loginuid(current), 2420 audit_get_loginuid(current),
@@ -2368,12 +2433,13 @@ int security_set_bools(int len, int *values)
2368 } 2433 }
2369 2434
2370 seqno = ++latest_granting; 2435 seqno = ++latest_granting;
2371 2436 rc = 0;
2372out: 2437out:
2373 write_unlock_irq(&policy_rwlock); 2438 write_unlock_irq(&policy_rwlock);
2374 if (!rc) { 2439 if (!rc) {
2375 avc_ss_reset(seqno); 2440 avc_ss_reset(seqno);
2376 selnl_notify_policyload(seqno); 2441 selnl_notify_policyload(seqno);
2442 selinux_status_update_policyload(seqno);
2377 selinux_xfrm_notify_policyload(); 2443 selinux_xfrm_notify_policyload();
2378 } 2444 }
2379 return rc; 2445 return rc;
@@ -2381,16 +2447,15 @@ out:
2381 2447
2382int security_get_bool_value(int bool) 2448int security_get_bool_value(int bool)
2383{ 2449{
2384 int rc = 0; 2450 int rc;
2385 int len; 2451 int len;
2386 2452
2387 read_lock(&policy_rwlock); 2453 read_lock(&policy_rwlock);
2388 2454
2455 rc = -EFAULT;
2389 len = policydb.p_bools.nprim; 2456 len = policydb.p_bools.nprim;
2390 if (bool >= len) { 2457 if (bool >= len)
2391 rc = -EFAULT;
2392 goto out; 2458 goto out;
2393 }
2394 2459
2395 rc = policydb.bool_val_to_struct[bool]->state; 2460 rc = policydb.bool_val_to_struct[bool]->state;
2396out: 2461out:
@@ -2440,8 +2505,9 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2440 struct context newcon; 2505 struct context newcon;
2441 char *s; 2506 char *s;
2442 u32 len; 2507 u32 len;
2443 int rc = 0; 2508 int rc;
2444 2509
2510 rc = 0;
2445 if (!ss_initialized || !policydb.mls_enabled) { 2511 if (!ss_initialized || !policydb.mls_enabled) {
2446 *new_sid = sid; 2512 *new_sid = sid;
2447 goto out; 2513 goto out;
@@ -2450,19 +2516,20 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2450 context_init(&newcon); 2516 context_init(&newcon);
2451 2517
2452 read_lock(&policy_rwlock); 2518 read_lock(&policy_rwlock);
2519
2520 rc = -EINVAL;
2453 context1 = sidtab_search(&sidtab, sid); 2521 context1 = sidtab_search(&sidtab, sid);
2454 if (!context1) { 2522 if (!context1) {
2455 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2523 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2456 __func__, sid); 2524 __func__, sid);
2457 rc = -EINVAL;
2458 goto out_unlock; 2525 goto out_unlock;
2459 } 2526 }
2460 2527
2528 rc = -EINVAL;
2461 context2 = sidtab_search(&sidtab, mls_sid); 2529 context2 = sidtab_search(&sidtab, mls_sid);
2462 if (!context2) { 2530 if (!context2) {
2463 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2531 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2464 __func__, mls_sid); 2532 __func__, mls_sid);
2465 rc = -EINVAL;
2466 goto out_unlock; 2533 goto out_unlock;
2467 } 2534 }
2468 2535
@@ -2476,20 +2543,17 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2476 /* Check the validity of the new context. */ 2543 /* Check the validity of the new context. */
2477 if (!policydb_context_isvalid(&policydb, &newcon)) { 2544 if (!policydb_context_isvalid(&policydb, &newcon)) {
2478 rc = convert_context_handle_invalid_context(&newcon); 2545 rc = convert_context_handle_invalid_context(&newcon);
2479 if (rc) 2546 if (rc) {
2480 goto bad; 2547 if (!context_struct_to_string(&newcon, &s, &len)) {
2548 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2549 "security_sid_mls_copy: invalid context %s", s);
2550 kfree(s);
2551 }
2552 goto out_unlock;
2553 }
2481 } 2554 }
2482 2555
2483 rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid); 2556 rc = sidtab_context_to_sid(&sidtab, &newcon, new_sid);
2484 goto out_unlock;
2485
2486bad:
2487 if (!context_struct_to_string(&newcon, &s, &len)) {
2488 audit_log(current->audit_context, GFP_ATOMIC, AUDIT_SELINUX_ERR,
2489 "security_sid_mls_copy: invalid context %s", s);
2490 kfree(s);
2491 }
2492
2493out_unlock: 2557out_unlock:
2494 read_unlock(&policy_rwlock); 2558 read_unlock(&policy_rwlock);
2495 context_destroy(&newcon); 2559 context_destroy(&newcon);
@@ -2525,6 +2589,8 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2525 struct context *nlbl_ctx; 2589 struct context *nlbl_ctx;
2526 struct context *xfrm_ctx; 2590 struct context *xfrm_ctx;
2527 2591
2592 *peer_sid = SECSID_NULL;
2593
2528 /* handle the common (which also happens to be the set of easy) cases 2594 /* handle the common (which also happens to be the set of easy) cases
2529 * right away, these two if statements catch everything involving a 2595 * right away, these two if statements catch everything involving a
2530 * single or absent peer SID/label */ 2596 * single or absent peer SID/label */
@@ -2543,40 +2609,37 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2543 /* we don't need to check ss_initialized here since the only way both 2609 /* we don't need to check ss_initialized here since the only way both
2544 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the 2610 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
2545 * security server was initialized and ss_initialized was true */ 2611 * security server was initialized and ss_initialized was true */
2546 if (!policydb.mls_enabled) { 2612 if (!policydb.mls_enabled)
2547 *peer_sid = SECSID_NULL;
2548 return 0; 2613 return 0;
2549 }
2550 2614
2551 read_lock(&policy_rwlock); 2615 read_lock(&policy_rwlock);
2552 2616
2617 rc = -EINVAL;
2553 nlbl_ctx = sidtab_search(&sidtab, nlbl_sid); 2618 nlbl_ctx = sidtab_search(&sidtab, nlbl_sid);
2554 if (!nlbl_ctx) { 2619 if (!nlbl_ctx) {
2555 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2620 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2556 __func__, nlbl_sid); 2621 __func__, nlbl_sid);
2557 rc = -EINVAL; 2622 goto out;
2558 goto out_slowpath;
2559 } 2623 }
2624 rc = -EINVAL;
2560 xfrm_ctx = sidtab_search(&sidtab, xfrm_sid); 2625 xfrm_ctx = sidtab_search(&sidtab, xfrm_sid);
2561 if (!xfrm_ctx) { 2626 if (!xfrm_ctx) {
2562 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 2627 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
2563 __func__, xfrm_sid); 2628 __func__, xfrm_sid);
2564 rc = -EINVAL; 2629 goto out;
2565 goto out_slowpath;
2566 } 2630 }
2567 rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES); 2631 rc = (mls_context_cmp(nlbl_ctx, xfrm_ctx) ? 0 : -EACCES);
2632 if (rc)
2633 goto out;
2568 2634
2569out_slowpath: 2635 /* at present NetLabel SIDs/labels really only carry MLS
2636 * information so if the MLS portion of the NetLabel SID
2637 * matches the MLS portion of the labeled XFRM SID/label
2638 * then pass along the XFRM SID as it is the most
2639 * expressive */
2640 *peer_sid = xfrm_sid;
2641out:
2570 read_unlock(&policy_rwlock); 2642 read_unlock(&policy_rwlock);
2571 if (rc == 0)
2572 /* at present NetLabel SIDs/labels really only carry MLS
2573 * information so if the MLS portion of the NetLabel SID
2574 * matches the MLS portion of the labeled XFRM SID/label
2575 * then pass along the XFRM SID as it is the most
2576 * expressive */
2577 *peer_sid = xfrm_sid;
2578 else
2579 *peer_sid = SECSID_NULL;
2580 return rc; 2643 return rc;
2581} 2644}
2582 2645
@@ -2595,10 +2658,11 @@ static int get_classes_callback(void *k, void *d, void *args)
2595 2658
2596int security_get_classes(char ***classes, int *nclasses) 2659int security_get_classes(char ***classes, int *nclasses)
2597{ 2660{
2598 int rc = -ENOMEM; 2661 int rc;
2599 2662
2600 read_lock(&policy_rwlock); 2663 read_lock(&policy_rwlock);
2601 2664
2665 rc = -ENOMEM;
2602 *nclasses = policydb.p_classes.nprim; 2666 *nclasses = policydb.p_classes.nprim;
2603 *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC); 2667 *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC);
2604 if (!*classes) 2668 if (!*classes)
@@ -2606,7 +2670,7 @@ int security_get_classes(char ***classes, int *nclasses)
2606 2670
2607 rc = hashtab_map(policydb.p_classes.table, get_classes_callback, 2671 rc = hashtab_map(policydb.p_classes.table, get_classes_callback,
2608 *classes); 2672 *classes);
2609 if (rc < 0) { 2673 if (rc) {
2610 int i; 2674 int i;
2611 for (i = 0; i < *nclasses; i++) 2675 for (i = 0; i < *nclasses; i++)
2612 kfree((*classes)[i]); 2676 kfree((*classes)[i]);
@@ -2633,19 +2697,20 @@ static int get_permissions_callback(void *k, void *d, void *args)
2633 2697
2634int security_get_permissions(char *class, char ***perms, int *nperms) 2698int security_get_permissions(char *class, char ***perms, int *nperms)
2635{ 2699{
2636 int rc = -ENOMEM, i; 2700 int rc, i;
2637 struct class_datum *match; 2701 struct class_datum *match;
2638 2702
2639 read_lock(&policy_rwlock); 2703 read_lock(&policy_rwlock);
2640 2704
2705 rc = -EINVAL;
2641 match = hashtab_search(policydb.p_classes.table, class); 2706 match = hashtab_search(policydb.p_classes.table, class);
2642 if (!match) { 2707 if (!match) {
2643 printk(KERN_ERR "SELinux: %s: unrecognized class %s\n", 2708 printk(KERN_ERR "SELinux: %s: unrecognized class %s\n",
2644 __func__, class); 2709 __func__, class);
2645 rc = -EINVAL;
2646 goto out; 2710 goto out;
2647 } 2711 }
2648 2712
2713 rc = -ENOMEM;
2649 *nperms = match->permissions.nprim; 2714 *nperms = match->permissions.nprim;
2650 *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC); 2715 *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC);
2651 if (!*perms) 2716 if (!*perms)
@@ -2654,13 +2719,13 @@ int security_get_permissions(char *class, char ***perms, int *nperms)
2654 if (match->comdatum) { 2719 if (match->comdatum) {
2655 rc = hashtab_map(match->comdatum->permissions.table, 2720 rc = hashtab_map(match->comdatum->permissions.table,
2656 get_permissions_callback, *perms); 2721 get_permissions_callback, *perms);
2657 if (rc < 0) 2722 if (rc)
2658 goto err; 2723 goto err;
2659 } 2724 }
2660 2725
2661 rc = hashtab_map(match->permissions.table, get_permissions_callback, 2726 rc = hashtab_map(match->permissions.table, get_permissions_callback,
2662 *perms); 2727 *perms);
2663 if (rc < 0) 2728 if (rc)
2664 goto err; 2729 goto err;
2665 2730
2666out: 2731out:
@@ -2750,7 +2815,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
2750 case AUDIT_SUBJ_CLR: 2815 case AUDIT_SUBJ_CLR:
2751 case AUDIT_OBJ_LEV_LOW: 2816 case AUDIT_OBJ_LEV_LOW:
2752 case AUDIT_OBJ_LEV_HIGH: 2817 case AUDIT_OBJ_LEV_HIGH:
2753 /* we do not allow a range, indicated by the presense of '-' */ 2818 /* we do not allow a range, indicated by the presence of '-' */
2754 if (strchr(rulestr, '-')) 2819 if (strchr(rulestr, '-'))
2755 return -EINVAL; 2820 return -EINVAL;
2756 break; 2821 break;
@@ -2772,36 +2837,39 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
2772 switch (field) { 2837 switch (field) {
2773 case AUDIT_SUBJ_USER: 2838 case AUDIT_SUBJ_USER:
2774 case AUDIT_OBJ_USER: 2839 case AUDIT_OBJ_USER:
2840 rc = -EINVAL;
2775 userdatum = hashtab_search(policydb.p_users.table, rulestr); 2841 userdatum = hashtab_search(policydb.p_users.table, rulestr);
2776 if (!userdatum) 2842 if (!userdatum)
2777 rc = -EINVAL; 2843 goto out;
2778 else 2844 tmprule->au_ctxt.user = userdatum->value;
2779 tmprule->au_ctxt.user = userdatum->value;
2780 break; 2845 break;
2781 case AUDIT_SUBJ_ROLE: 2846 case AUDIT_SUBJ_ROLE:
2782 case AUDIT_OBJ_ROLE: 2847 case AUDIT_OBJ_ROLE:
2848 rc = -EINVAL;
2783 roledatum = hashtab_search(policydb.p_roles.table, rulestr); 2849 roledatum = hashtab_search(policydb.p_roles.table, rulestr);
2784 if (!roledatum) 2850 if (!roledatum)
2785 rc = -EINVAL; 2851 goto out;
2786 else 2852 tmprule->au_ctxt.role = roledatum->value;
2787 tmprule->au_ctxt.role = roledatum->value;
2788 break; 2853 break;
2789 case AUDIT_SUBJ_TYPE: 2854 case AUDIT_SUBJ_TYPE:
2790 case AUDIT_OBJ_TYPE: 2855 case AUDIT_OBJ_TYPE:
2856 rc = -EINVAL;
2791 typedatum = hashtab_search(policydb.p_types.table, rulestr); 2857 typedatum = hashtab_search(policydb.p_types.table, rulestr);
2792 if (!typedatum) 2858 if (!typedatum)
2793 rc = -EINVAL; 2859 goto out;
2794 else 2860 tmprule->au_ctxt.type = typedatum->value;
2795 tmprule->au_ctxt.type = typedatum->value;
2796 break; 2861 break;
2797 case AUDIT_SUBJ_SEN: 2862 case AUDIT_SUBJ_SEN:
2798 case AUDIT_SUBJ_CLR: 2863 case AUDIT_SUBJ_CLR:
2799 case AUDIT_OBJ_LEV_LOW: 2864 case AUDIT_OBJ_LEV_LOW:
2800 case AUDIT_OBJ_LEV_HIGH: 2865 case AUDIT_OBJ_LEV_HIGH:
2801 rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC); 2866 rc = mls_from_string(rulestr, &tmprule->au_ctxt, GFP_ATOMIC);
2867 if (rc)
2868 goto out;
2802 break; 2869 break;
2803 } 2870 }
2804 2871 rc = 0;
2872out:
2805 read_unlock(&policy_rwlock); 2873 read_unlock(&policy_rwlock);
2806 2874
2807 if (rc) { 2875 if (rc) {
@@ -3016,7 +3084,7 @@ static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr,
3016 * Description: 3084 * Description:
3017 * Convert the given NetLabel security attributes in @secattr into a 3085 * Convert the given NetLabel security attributes in @secattr into a
3018 * SELinux SID. If the @secattr field does not contain a full SELinux 3086 * SELinux SID. If the @secattr field does not contain a full SELinux
3019 * SID/context then use SECINITSID_NETMSG as the foundation. If possibile the 3087 * SID/context then use SECINITSID_NETMSG as the foundation. If possible the
3020 * 'cache' field of @secattr is set and the CACHE flag is set; this is to 3088 * 'cache' field of @secattr is set and the CACHE flag is set; this is to
3021 * allow the @secattr to be used by NetLabel to cache the secattr to SID 3089 * allow the @secattr to be used by NetLabel to cache the secattr to SID
3022 * conversion for future lookups. Returns zero on success, negative values on 3090 * conversion for future lookups. Returns zero on success, negative values on
@@ -3026,7 +3094,7 @@ static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr,
3026int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, 3094int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3027 u32 *sid) 3095 u32 *sid)
3028{ 3096{
3029 int rc = -EIDRM; 3097 int rc;
3030 struct context *ctx; 3098 struct context *ctx;
3031 struct context ctx_new; 3099 struct context ctx_new;
3032 3100
@@ -3037,16 +3105,15 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3037 3105
3038 read_lock(&policy_rwlock); 3106 read_lock(&policy_rwlock);
3039 3107
3040 if (secattr->flags & NETLBL_SECATTR_CACHE) { 3108 if (secattr->flags & NETLBL_SECATTR_CACHE)
3041 *sid = *(u32 *)secattr->cache->data; 3109 *sid = *(u32 *)secattr->cache->data;
3042 rc = 0; 3110 else if (secattr->flags & NETLBL_SECATTR_SECID)
3043 } else if (secattr->flags & NETLBL_SECATTR_SECID) {
3044 *sid = secattr->attr.secid; 3111 *sid = secattr->attr.secid;
3045 rc = 0; 3112 else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) {
3046 } else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { 3113 rc = -EIDRM;
3047 ctx = sidtab_search(&sidtab, SECINITSID_NETMSG); 3114 ctx = sidtab_search(&sidtab, SECINITSID_NETMSG);
3048 if (ctx == NULL) 3115 if (ctx == NULL)
3049 goto netlbl_secattr_to_sid_return; 3116 goto out;
3050 3117
3051 context_init(&ctx_new); 3118 context_init(&ctx_new);
3052 ctx_new.user = ctx->user; 3119 ctx_new.user = ctx->user;
@@ -3054,34 +3121,35 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
3054 ctx_new.type = ctx->type; 3121 ctx_new.type = ctx->type;
3055 mls_import_netlbl_lvl(&ctx_new, secattr); 3122 mls_import_netlbl_lvl(&ctx_new, secattr);
3056 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { 3123 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
3057 if (ebitmap_netlbl_import(&ctx_new.range.level[0].cat, 3124 rc = ebitmap_netlbl_import(&ctx_new.range.level[0].cat,
3058 secattr->attr.mls.cat) != 0) 3125 secattr->attr.mls.cat);
3059 goto netlbl_secattr_to_sid_return; 3126 if (rc)
3127 goto out;
3060 memcpy(&ctx_new.range.level[1].cat, 3128 memcpy(&ctx_new.range.level[1].cat,
3061 &ctx_new.range.level[0].cat, 3129 &ctx_new.range.level[0].cat,
3062 sizeof(ctx_new.range.level[0].cat)); 3130 sizeof(ctx_new.range.level[0].cat));
3063 } 3131 }
3064 if (mls_context_isvalid(&policydb, &ctx_new) != 1) 3132 rc = -EIDRM;
3065 goto netlbl_secattr_to_sid_return_cleanup; 3133 if (!mls_context_isvalid(&policydb, &ctx_new))
3134 goto out_free;
3066 3135
3067 rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid); 3136 rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid);
3068 if (rc != 0) 3137 if (rc)
3069 goto netlbl_secattr_to_sid_return_cleanup; 3138 goto out_free;
3070 3139
3071 security_netlbl_cache_add(secattr, *sid); 3140 security_netlbl_cache_add(secattr, *sid);
3072 3141
3073 ebitmap_destroy(&ctx_new.range.level[0].cat); 3142 ebitmap_destroy(&ctx_new.range.level[0].cat);
3074 } else { 3143 } else
3075 *sid = SECSID_NULL; 3144 *sid = SECSID_NULL;
3076 rc = 0;
3077 }
3078 3145
3079netlbl_secattr_to_sid_return:
3080 read_unlock(&policy_rwlock); 3146 read_unlock(&policy_rwlock);
3081 return rc; 3147 return 0;
3082netlbl_secattr_to_sid_return_cleanup: 3148out_free:
3083 ebitmap_destroy(&ctx_new.range.level[0].cat); 3149 ebitmap_destroy(&ctx_new.range.level[0].cat);
3084 goto netlbl_secattr_to_sid_return; 3150out:
3151 read_unlock(&policy_rwlock);
3152 return rc;
3085} 3153}
3086 3154
3087/** 3155/**
@@ -3103,29 +3171,59 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)
3103 return 0; 3171 return 0;
3104 3172
3105 read_lock(&policy_rwlock); 3173 read_lock(&policy_rwlock);
3174
3175 rc = -ENOENT;
3106 ctx = sidtab_search(&sidtab, sid); 3176 ctx = sidtab_search(&sidtab, sid);
3107 if (ctx == NULL) { 3177 if (ctx == NULL)
3108 rc = -ENOENT; 3178 goto out;
3109 goto netlbl_sid_to_secattr_failure; 3179
3110 } 3180 rc = -ENOMEM;
3111 secattr->domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], 3181 secattr->domain = kstrdup(sym_name(&policydb, SYM_TYPES, ctx->type - 1),
3112 GFP_ATOMIC); 3182 GFP_ATOMIC);
3113 if (secattr->domain == NULL) { 3183 if (secattr->domain == NULL)
3114 rc = -ENOMEM; 3184 goto out;
3115 goto netlbl_sid_to_secattr_failure; 3185
3116 }
3117 secattr->attr.secid = sid; 3186 secattr->attr.secid = sid;
3118 secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID; 3187 secattr->flags |= NETLBL_SECATTR_DOMAIN_CPY | NETLBL_SECATTR_SECID;
3119 mls_export_netlbl_lvl(ctx, secattr); 3188 mls_export_netlbl_lvl(ctx, secattr);
3120 rc = mls_export_netlbl_cat(ctx, secattr); 3189 rc = mls_export_netlbl_cat(ctx, secattr);
3121 if (rc != 0) 3190out:
3122 goto netlbl_sid_to_secattr_failure;
3123 read_unlock(&policy_rwlock); 3191 read_unlock(&policy_rwlock);
3192 return rc;
3193}
3194#endif /* CONFIG_NETLABEL */
3124 3195
3125 return 0; 3196/**
3197 * security_read_policy - read the policy.
3198 * @data: binary policy data
3199 * @len: length of data in bytes
3200 *
3201 */
3202int security_read_policy(void **data, size_t *len)
3203{
3204 int rc;
3205 struct policy_file fp;
3126 3206
3127netlbl_sid_to_secattr_failure: 3207 if (!ss_initialized)
3208 return -EINVAL;
3209
3210 *len = security_policydb_len();
3211
3212 *data = vmalloc_user(*len);
3213 if (!*data)
3214 return -ENOMEM;
3215
3216 fp.data = *data;
3217 fp.len = *len;
3218
3219 read_lock(&policy_rwlock);
3220 rc = policydb_write(&policydb, &fp);
3128 read_unlock(&policy_rwlock); 3221 read_unlock(&policy_rwlock);
3129 return rc; 3222
3223 if (rc)
3224 return rc;
3225
3226 *len = (unsigned long)fp.data - (unsigned long)*data;
3227 return 0;
3228
3130} 3229}
3131#endif /* CONFIG_NETLABEL */
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
index e817989764cd..5840a35155fc 100644
--- a/security/selinux/ss/sidtab.c
+++ b/security/selinux/ss/sidtab.c
@@ -147,6 +147,17 @@ out:
147 return rc; 147 return rc;
148} 148}
149 149
150static void sidtab_update_cache(struct sidtab *s, struct sidtab_node *n, int loc)
151{
152 BUG_ON(loc >= SIDTAB_CACHE_LEN);
153
154 while (loc > 0) {
155 s->cache[loc] = s->cache[loc - 1];
156 loc--;
157 }
158 s->cache[0] = n;
159}
160
150static inline u32 sidtab_search_context(struct sidtab *s, 161static inline u32 sidtab_search_context(struct sidtab *s,
151 struct context *context) 162 struct context *context)
152{ 163{
@@ -156,14 +167,33 @@ static inline u32 sidtab_search_context(struct sidtab *s,
156 for (i = 0; i < SIDTAB_SIZE; i++) { 167 for (i = 0; i < SIDTAB_SIZE; i++) {
157 cur = s->htable[i]; 168 cur = s->htable[i];
158 while (cur) { 169 while (cur) {
159 if (context_cmp(&cur->context, context)) 170 if (context_cmp(&cur->context, context)) {
171 sidtab_update_cache(s, cur, SIDTAB_CACHE_LEN - 1);
160 return cur->sid; 172 return cur->sid;
173 }
161 cur = cur->next; 174 cur = cur->next;
162 } 175 }
163 } 176 }
164 return 0; 177 return 0;
165} 178}
166 179
180static inline u32 sidtab_search_cache(struct sidtab *s, struct context *context)
181{
182 int i;
183 struct sidtab_node *node;
184
185 for (i = 0; i < SIDTAB_CACHE_LEN; i++) {
186 node = s->cache[i];
187 if (unlikely(!node))
188 return 0;
189 if (context_cmp(&node->context, context)) {
190 sidtab_update_cache(s, node, i);
191 return node->sid;
192 }
193 }
194 return 0;
195}
196
167int sidtab_context_to_sid(struct sidtab *s, 197int sidtab_context_to_sid(struct sidtab *s,
168 struct context *context, 198 struct context *context,
169 u32 *out_sid) 199 u32 *out_sid)
@@ -174,7 +204,9 @@ int sidtab_context_to_sid(struct sidtab *s,
174 204
175 *out_sid = SECSID_NULL; 205 *out_sid = SECSID_NULL;
176 206
177 sid = sidtab_search_context(s, context); 207 sid = sidtab_search_cache(s, context);
208 if (!sid)
209 sid = sidtab_search_context(s, context);
178 if (!sid) { 210 if (!sid) {
179 spin_lock_irqsave(&s->lock, flags); 211 spin_lock_irqsave(&s->lock, flags);
180 /* Rescan now that we hold the lock. */ 212 /* Rescan now that we hold the lock. */
@@ -259,12 +291,15 @@ void sidtab_destroy(struct sidtab *s)
259void sidtab_set(struct sidtab *dst, struct sidtab *src) 291void sidtab_set(struct sidtab *dst, struct sidtab *src)
260{ 292{
261 unsigned long flags; 293 unsigned long flags;
294 int i;
262 295
263 spin_lock_irqsave(&src->lock, flags); 296 spin_lock_irqsave(&src->lock, flags);
264 dst->htable = src->htable; 297 dst->htable = src->htable;
265 dst->nel = src->nel; 298 dst->nel = src->nel;
266 dst->next_sid = src->next_sid; 299 dst->next_sid = src->next_sid;
267 dst->shutdown = 0; 300 dst->shutdown = 0;
301 for (i = 0; i < SIDTAB_CACHE_LEN; i++)
302 dst->cache[i] = NULL;
268 spin_unlock_irqrestore(&src->lock, flags); 303 spin_unlock_irqrestore(&src->lock, flags);
269} 304}
270 305
diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h
index 64ea5b1cdea4..84dc154d9389 100644
--- a/security/selinux/ss/sidtab.h
+++ b/security/selinux/ss/sidtab.h
@@ -26,6 +26,8 @@ struct sidtab {
26 unsigned int nel; /* number of elements */ 26 unsigned int nel; /* number of elements */
27 unsigned int next_sid; /* next SID to allocate */ 27 unsigned int next_sid; /* next SID to allocate */
28 unsigned char shutdown; 28 unsigned char shutdown;
29#define SIDTAB_CACHE_LEN 3
30 struct sidtab_node *cache[SIDTAB_CACHE_LEN];
29 spinlock_t lock; 31 spinlock_t lock;
30}; 32};
31 33
diff --git a/security/selinux/ss/status.c b/security/selinux/ss/status.c
new file mode 100644
index 000000000000..d982365f9d1a
--- /dev/null
+++ b/security/selinux/ss/status.c
@@ -0,0 +1,126 @@
1/*
2 * mmap based event notifications for SELinux
3 *
4 * Author: KaiGai Kohei <kaigai@ak.jp.nec.com>
5 *
6 * Copyright (C) 2010 NEC corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2,
10 * as published by the Free Software Foundation.
11 */
12#include <linux/kernel.h>
13#include <linux/gfp.h>
14#include <linux/mm.h>
15#include <linux/mutex.h>
16#include "avc.h"
17#include "services.h"
18
19/*
20 * The selinux_status_page shall be exposed to userspace applications
21 * using mmap interface on /selinux/status.
22 * It enables to notify applications a few events that will cause reset
23 * of userspace access vector without context switching.
24 *
25 * The selinux_kernel_status structure on the head of status page is
26 * protected from concurrent accesses using seqlock logic, so userspace
27 * application should reference the status page according to the seqlock
28 * logic.
29 *
30 * Typically, application checks status->sequence at the head of access
31 * control routine. If it is odd-number, kernel is updating the status,
32 * so please wait for a moment. If it is changed from the last sequence
33 * number, it means something happen, so application will reset userspace
34 * avc, if needed.
35 * In most cases, application shall confirm the kernel status is not
36 * changed without any system call invocations.
37 */
38static struct page *selinux_status_page;
39static DEFINE_MUTEX(selinux_status_lock);
40
41/*
42 * selinux_kernel_status_page
43 *
44 * 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.
46 */
47struct page *selinux_kernel_status_page(void)
48{
49 struct selinux_kernel_status *status;
50 struct page *result = NULL;
51
52 mutex_lock(&selinux_status_lock);
53 if (!selinux_status_page) {
54 selinux_status_page = alloc_page(GFP_KERNEL|__GFP_ZERO);
55
56 if (selinux_status_page) {
57 status = page_address(selinux_status_page);
58
59 status->version = SELINUX_KERNEL_STATUS_VERSION;
60 status->sequence = 0;
61 status->enforcing = selinux_enforcing;
62 /*
63 * NOTE: the next policyload event shall set
64 * a positive value on the status->policyload,
65 * although it may not be 1, but never zero.
66 * So, application can know it was updated.
67 */
68 status->policyload = 0;
69 status->deny_unknown = !security_get_allow_unknown();
70 }
71 }
72 result = selinux_status_page;
73 mutex_unlock(&selinux_status_lock);
74
75 return result;
76}
77
78/*
79 * selinux_status_update_setenforce
80 *
81 * It updates status of the current enforcing/permissive mode.
82 */
83void selinux_status_update_setenforce(int enforcing)
84{
85 struct selinux_kernel_status *status;
86
87 mutex_lock(&selinux_status_lock);
88 if (selinux_status_page) {
89 status = page_address(selinux_status_page);
90
91 status->sequence++;
92 smp_wmb();
93
94 status->enforcing = enforcing;
95
96 smp_wmb();
97 status->sequence++;
98 }
99 mutex_unlock(&selinux_status_lock);
100}
101
102/*
103 * selinux_status_update_policyload
104 *
105 * It updates status of the times of policy reloaded, and current
106 * setting of deny_unknown.
107 */
108void selinux_status_update_policyload(int seqno)
109{
110 struct selinux_kernel_status *status;
111
112 mutex_lock(&selinux_status_lock);
113 if (selinux_status_page) {
114 status = page_address(selinux_status_page);
115
116 status->sequence++;
117 smp_wmb();
118
119 status->policyload = seqno;
120 status->deny_unknown = !security_get_allow_unknown();
121
122 smp_wmb();
123 status->sequence++;
124 }
125 mutex_unlock(&selinux_status_lock);
126}
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index fff78d3b51a2..68178b76a2b3 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -112,7 +112,7 @@ int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir)
112 */ 112 */
113 113
114int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *xp, 114int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *xp,
115 struct flowi *fl) 115 const struct flowi *fl)
116{ 116{
117 u32 state_sid; 117 u32 state_sid;
118 int rc; 118 int rc;
@@ -135,10 +135,10 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
135 135
136 state_sid = x->security->ctx_sid; 136 state_sid = x->security->ctx_sid;
137 137
138 if (fl->secid != state_sid) 138 if (fl->flowi_secid != state_sid)
139 return 0; 139 return 0;
140 140
141 rc = avc_has_perm(fl->secid, state_sid, SECCLASS_ASSOCIATION, 141 rc = avc_has_perm(fl->flowi_secid, state_sid, SECCLASS_ASSOCIATION,
142 ASSOCIATION__SENDTO, 142 ASSOCIATION__SENDTO,
143 NULL)? 0:1; 143 NULL)? 0:1;
144 144
@@ -208,7 +208,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
208 if (!uctx) 208 if (!uctx)
209 goto not_from_user; 209 goto not_from_user;
210 210
211 if (uctx->ctx_doi != XFRM_SC_ALG_SELINUX) 211 if (uctx->ctx_alg != XFRM_SC_ALG_SELINUX)
212 return -EINVAL; 212 return -EINVAL;
213 213
214 str_len = uctx->ctx_len; 214 str_len = uctx->ctx_len;