aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /security
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'security')
-rw-r--r--security/Kconfig54
-rw-r--r--security/Makefile4
-rw-r--r--security/capability.c25
-rw-r--r--security/commoncap.c83
-rw-r--r--security/device_cgroup.c1
-rw-r--r--security/inode.c15
-rw-r--r--security/integrity/ima/Kconfig1
-rw-r--r--security/integrity/ima/ima.h6
-rw-r--r--security/integrity/ima/ima_api.c5
-rw-r--r--security/integrity/ima/ima_audit.c1
-rw-r--r--security/integrity/ima/ima_crypto.c1
-rw-r--r--security/integrity/ima/ima_fs.c1
-rw-r--r--security/integrity/ima/ima_iint.c86
-rw-r--r--security/integrity/ima/ima_init.c1
-rw-r--r--security/integrity/ima/ima_main.c310
-rw-r--r--security/integrity/ima/ima_policy.c10
-rw-r--r--security/integrity/ima/ima_queue.c1
-rw-r--r--security/keys/gc.c6
-rw-r--r--security/keys/keyctl.c12
-rw-r--r--security/keys/keyring.c45
-rw-r--r--security/keys/proc.c1
-rw-r--r--security/keys/process_keys.c1
-rw-r--r--security/keys/request_key.c24
-rw-r--r--security/keys/sysctl.c17
-rw-r--r--security/keys/user_defined.c3
-rw-r--r--security/lsm_audit.c17
-rw-r--r--security/min_addr.c5
-rw-r--r--security/root_plug.c90
-rw-r--r--security/security.c108
-rw-r--r--security/selinux/.gitignore2
-rw-r--r--security/selinux/Makefile10
-rw-r--r--security/selinux/avc.c106
-rw-r--r--security/selinux/hooks.c70
-rw-r--r--security/selinux/include/av_inherit.h34
-rw-r--r--security/selinux/include/av_perm_to_string.h183
-rw-r--r--security/selinux/include/av_permissions.h870
-rw-r--r--security/selinux/include/avc_ss.h21
-rw-r--r--security/selinux/include/class_to_string.h80
-rw-r--r--security/selinux/include/classmap.h150
-rw-r--r--security/selinux/include/common_perm_to_string.h58
-rw-r--r--security/selinux/include/flask.h91
-rw-r--r--security/selinux/include/security.h16
-rw-r--r--security/selinux/netif.c1
-rw-r--r--security/selinux/netlabel.c3
-rw-r--r--security/selinux/netlink.c1
-rw-r--r--security/selinux/netnode.c1
-rw-r--r--security/selinux/netport.c1
-rw-r--r--security/selinux/selinuxfs.c14
-rw-r--r--security/selinux/ss/Makefile2
-rw-r--r--security/selinux/ss/avtab.h2
-rw-r--r--security/selinux/ss/context.h12
-rw-r--r--security/selinux/ss/ebitmap.c2
-rw-r--r--security/selinux/ss/mls.c50
-rw-r--r--security/selinux/ss/mls.h2
-rw-r--r--security/selinux/ss/mls_types.h7
-rw-r--r--security/selinux/ss/policydb.c174
-rw-r--r--security/selinux/ss/policydb.h17
-rw-r--r--security/selinux/ss/services.c665
-rw-r--r--security/selinux/ss/symtab.c1
-rw-r--r--security/selinux/xfrm.c1
-rw-r--r--security/smack/smack_access.c1
-rw-r--r--security/smack/smack_lsm.c11
-rw-r--r--security/smack/smackfs.c1
-rw-r--r--security/tomoyo/Makefile2
-rw-r--r--security/tomoyo/common.c576
-rw-r--r--security/tomoyo/common.h534
-rw-r--r--security/tomoyo/domain.c392
-rw-r--r--security/tomoyo/file.c754
-rw-r--r--security/tomoyo/gc.c371
-rw-r--r--security/tomoyo/realpath.c303
-rw-r--r--security/tomoyo/realpath.h66
-rw-r--r--security/tomoyo/tomoyo.c229
-rw-r--r--security/tomoyo/tomoyo.h96
73 files changed, 2920 insertions, 3997 deletions
diff --git a/security/Kconfig b/security/Kconfig
index fb363cd81cf6..226b9556b25f 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -91,28 +91,6 @@ config SECURITY_PATH
91 implement pathname based access controls. 91 implement pathname based access controls.
92 If you are unsure how to answer this question, answer N. 92 If you are unsure how to answer this question, answer N.
93 93
94config SECURITY_FILE_CAPABILITIES
95 bool "File POSIX Capabilities"
96 default n
97 help
98 This enables filesystem capabilities, allowing you to give
99 binaries a subset of root's powers without using setuid 0.
100
101 If in doubt, answer N.
102
103config SECURITY_ROOTPLUG
104 bool "Root Plug Support"
105 depends on USB=y && SECURITY
106 help
107 This is a sample LSM module that should only be used as such.
108 It prevents any programs running with egid == 0 if a specific
109 USB device is not present in the system.
110
111 See <http://www.linuxjournal.com/article.php?sid=6279> for
112 more information about this module.
113
114 If you are unsure how to answer this question, answer N.
115
116config INTEL_TXT 94config INTEL_TXT
117 bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)" 95 bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)"
118 depends on HAVE_INTEL_TXT 96 depends on HAVE_INTEL_TXT
@@ -165,5 +143,37 @@ source security/tomoyo/Kconfig
165 143
166source security/integrity/ima/Kconfig 144source security/integrity/ima/Kconfig
167 145
146choice
147 prompt "Default security module"
148 default DEFAULT_SECURITY_SELINUX if SECURITY_SELINUX
149 default DEFAULT_SECURITY_SMACK if SECURITY_SMACK
150 default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO
151 default DEFAULT_SECURITY_DAC
152
153 help
154 Select the security module that will be used by default if the
155 kernel parameter security= is not specified.
156
157 config DEFAULT_SECURITY_SELINUX
158 bool "SELinux" if SECURITY_SELINUX=y
159
160 config DEFAULT_SECURITY_SMACK
161 bool "Simplified Mandatory Access Control" if SECURITY_SMACK=y
162
163 config DEFAULT_SECURITY_TOMOYO
164 bool "TOMOYO" if SECURITY_TOMOYO=y
165
166 config DEFAULT_SECURITY_DAC
167 bool "Unix Discretionary Access Controls"
168
169endchoice
170
171config DEFAULT_SECURITY
172 string
173 default "selinux" if DEFAULT_SECURITY_SELINUX
174 default "smack" if DEFAULT_SECURITY_SMACK
175 default "tomoyo" if DEFAULT_SECURITY_TOMOYO
176 default "" if DEFAULT_SECURITY_DAC
177
168endmenu 178endmenu
169 179
diff --git a/security/Makefile b/security/Makefile
index 95ecc06392d7..da20a193c8dd 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -8,7 +8,8 @@ subdir-$(CONFIG_SECURITY_SMACK) += smack
8subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo 8subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo
9 9
10# always enable default capabilities 10# always enable default capabilities
11obj-y += commoncap.o min_addr.o 11obj-y += commoncap.o
12obj-$(CONFIG_MMU) += min_addr.o
12 13
13# Object file lists 14# Object file lists
14obj-$(CONFIG_SECURITY) += security.o capability.o 15obj-$(CONFIG_SECURITY) += security.o capability.o
@@ -18,7 +19,6 @@ obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o
18obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o 19obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o
19obj-$(CONFIG_AUDIT) += lsm_audit.o 20obj-$(CONFIG_AUDIT) += lsm_audit.o
20obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o 21obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o
21obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o
22obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o 22obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o
23 23
24# Object integrity file lists 24# Object integrity file lists
diff --git a/security/capability.c b/security/capability.c
index fce07a7bc825..4875142b858d 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -308,6 +308,22 @@ static int cap_path_truncate(struct path *path, loff_t length,
308{ 308{
309 return 0; 309 return 0;
310} 310}
311
312static int cap_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
313 mode_t mode)
314{
315 return 0;
316}
317
318static int cap_path_chown(struct path *path, uid_t uid, gid_t gid)
319{
320 return 0;
321}
322
323static int cap_path_chroot(struct path *root)
324{
325 return 0;
326}
311#endif 327#endif
312 328
313static int cap_file_permission(struct file *file, int mask) 329static int cap_file_permission(struct file *file, int mask)
@@ -405,7 +421,7 @@ static int cap_kernel_create_files_as(struct cred *new, struct inode *inode)
405 return 0; 421 return 0;
406} 422}
407 423
408static int cap_kernel_module_request(void) 424static int cap_kernel_module_request(char *kmod_name)
409{ 425{
410 return 0; 426 return 0;
411} 427}
@@ -890,10 +906,6 @@ static void cap_audit_rule_free(void *lsmrule)
890} 906}
891#endif /* CONFIG_AUDIT */ 907#endif /* CONFIG_AUDIT */
892 908
893struct security_operations default_security_ops = {
894 .name = "default",
895};
896
897#define set_to_cap_if_null(ops, function) \ 909#define set_to_cap_if_null(ops, function) \
898 do { \ 910 do { \
899 if (!ops->function) { \ 911 if (!ops->function) { \
@@ -977,6 +989,9 @@ void security_fixup_ops(struct security_operations *ops)
977 set_to_cap_if_null(ops, path_link); 989 set_to_cap_if_null(ops, path_link);
978 set_to_cap_if_null(ops, path_rename); 990 set_to_cap_if_null(ops, path_rename);
979 set_to_cap_if_null(ops, path_truncate); 991 set_to_cap_if_null(ops, path_truncate);
992 set_to_cap_if_null(ops, path_chmod);
993 set_to_cap_if_null(ops, path_chown);
994 set_to_cap_if_null(ops, path_chroot);
980#endif 995#endif
981 set_to_cap_if_null(ops, file_permission); 996 set_to_cap_if_null(ops, file_permission);
982 set_to_cap_if_null(ops, file_alloc_security); 997 set_to_cap_if_null(ops, file_alloc_security);
diff --git a/security/commoncap.c b/security/commoncap.c
index fe30751a6cd9..61669730da98 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -1,4 +1,4 @@
1/* Common capabilities, needed by capability.o and root_plug.o 1/* Common capabilities, needed by capability.o.
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by 4 * it under the terms of the GNU General Public License as published by
@@ -27,6 +27,7 @@
27#include <linux/sched.h> 27#include <linux/sched.h>
28#include <linux/prctl.h> 28#include <linux/prctl.h>
29#include <linux/securebits.h> 29#include <linux/securebits.h>
30#include <linux/syslog.h>
30 31
31/* 32/*
32 * If a non-root user executes a setuid-root binary in 33 * If a non-root user executes a setuid-root binary in
@@ -173,7 +174,6 @@ int cap_capget(struct task_struct *target, kernel_cap_t *effective,
173 */ 174 */
174static inline int cap_inh_is_capped(void) 175static inline int cap_inh_is_capped(void)
175{ 176{
176#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
177 177
178 /* they are so limited unless the current task has the CAP_SETPCAP 178 /* they are so limited unless the current task has the CAP_SETPCAP
179 * capability 179 * capability
@@ -181,7 +181,6 @@ static inline int cap_inh_is_capped(void)
181 if (cap_capable(current, current_cred(), CAP_SETPCAP, 181 if (cap_capable(current, current_cred(), CAP_SETPCAP,
182 SECURITY_CAP_AUDIT) == 0) 182 SECURITY_CAP_AUDIT) == 0)
183 return 0; 183 return 0;
184#endif
185 return 1; 184 return 1;
186} 185}
187 186
@@ -239,8 +238,6 @@ static inline void bprm_clear_caps(struct linux_binprm *bprm)
239 bprm->cap_effective = false; 238 bprm->cap_effective = false;
240} 239}
241 240
242#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
243
244/** 241/**
245 * cap_inode_need_killpriv - Determine if inode change affects privileges 242 * cap_inode_need_killpriv - Determine if inode change affects privileges
246 * @dentry: The inode/dentry in being changed with change marked ATTR_KILL_PRIV 243 * @dentry: The inode/dentry in being changed with change marked ATTR_KILL_PRIV
@@ -421,49 +418,6 @@ out:
421 return rc; 418 return rc;
422} 419}
423 420
424#else
425int cap_inode_need_killpriv(struct dentry *dentry)
426{
427 return 0;
428}
429
430int cap_inode_killpriv(struct dentry *dentry)
431{
432 return 0;
433}
434
435int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps)
436{
437 memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data));
438 return -ENODATA;
439}
440
441static inline int get_file_caps(struct linux_binprm *bprm, bool *effective)
442{
443 bprm_clear_caps(bprm);
444 return 0;
445}
446#endif
447
448/*
449 * Determine whether a exec'ing process's new permitted capabilities should be
450 * limited to just what it already has.
451 *
452 * This prevents processes that are being ptraced from gaining access to
453 * CAP_SETPCAP, unless the process they're tracing already has it, and the
454 * binary they're executing has filecaps that elevate it.
455 *
456 * Returns 1 if they should be limited, 0 if they are not.
457 */
458static inline int cap_limit_ptraced_target(void)
459{
460#ifndef CONFIG_SECURITY_FILE_CAPABILITIES
461 if (capable(CAP_SETPCAP))
462 return 0;
463#endif
464 return 1;
465}
466
467/** 421/**
468 * cap_bprm_set_creds - Set up the proposed credentials for execve(). 422 * cap_bprm_set_creds - Set up the proposed credentials for execve().
469 * @bprm: The execution parameters, including the proposed creds 423 * @bprm: The execution parameters, including the proposed creds
@@ -523,9 +477,8 @@ skip:
523 new->euid = new->uid; 477 new->euid = new->uid;
524 new->egid = new->gid; 478 new->egid = new->gid;
525 } 479 }
526 if (cap_limit_ptraced_target()) 480 new->cap_permitted = cap_intersect(new->cap_permitted,
527 new->cap_permitted = cap_intersect(new->cap_permitted, 481 old->cap_permitted);
528 old->cap_permitted);
529 } 482 }
530 483
531 new->suid = new->fsuid = new->euid; 484 new->suid = new->fsuid = new->euid;
@@ -739,7 +692,6 @@ int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags)
739 return 0; 692 return 0;
740} 693}
741 694
742#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
743/* 695/*
744 * Rationale: code calling task_setscheduler, task_setioprio, and 696 * Rationale: code calling task_setscheduler, task_setioprio, and
745 * task_setnice, assumes that 697 * task_setnice, assumes that
@@ -820,22 +772,6 @@ static long cap_prctl_drop(struct cred *new, unsigned long cap)
820 return 0; 772 return 0;
821} 773}
822 774
823#else
824int cap_task_setscheduler (struct task_struct *p, int policy,
825 struct sched_param *lp)
826{
827 return 0;
828}
829int cap_task_setioprio (struct task_struct *p, int ioprio)
830{
831 return 0;
832}
833int cap_task_setnice (struct task_struct *p, int nice)
834{
835 return 0;
836}
837#endif
838
839/** 775/**
840 * cap_task_prctl - Implement process control functions for this security module 776 * cap_task_prctl - Implement process control functions for this security module
841 * @option: The process control function requested 777 * @option: The process control function requested
@@ -866,7 +802,6 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
866 error = !!cap_raised(new->cap_bset, arg2); 802 error = !!cap_raised(new->cap_bset, arg2);
867 goto no_change; 803 goto no_change;
868 804
869#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
870 case PR_CAPBSET_DROP: 805 case PR_CAPBSET_DROP:
871 error = cap_prctl_drop(new, arg2); 806 error = cap_prctl_drop(new, arg2);
872 if (error < 0) 807 if (error < 0)
@@ -917,8 +852,6 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
917 error = new->securebits; 852 error = new->securebits;
918 goto no_change; 853 goto no_change;
919 854
920#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */
921
922 case PR_GET_KEEPCAPS: 855 case PR_GET_KEEPCAPS:
923 if (issecure(SECURE_KEEP_CAPS)) 856 if (issecure(SECURE_KEEP_CAPS))
924 error = 1; 857 error = 1;
@@ -956,13 +889,17 @@ error:
956/** 889/**
957 * cap_syslog - Determine whether syslog function is permitted 890 * cap_syslog - Determine whether syslog function is permitted
958 * @type: Function requested 891 * @type: Function requested
892 * @from_file: Whether this request came from an open file (i.e. /proc)
959 * 893 *
960 * Determine whether the current process is permitted to use a particular 894 * Determine whether the current process is permitted to use a particular
961 * syslog function, returning 0 if permission is granted, -ve if not. 895 * syslog function, returning 0 if permission is granted, -ve if not.
962 */ 896 */
963int cap_syslog(int type) 897int cap_syslog(int type, bool from_file)
964{ 898{
965 if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN)) 899 if (type != SYSLOG_ACTION_OPEN && from_file)
900 return 0;
901 if ((type != SYSLOG_ACTION_READ_ALL &&
902 type != SYSLOG_ACTION_SIZE_BUFFER) && !capable(CAP_SYS_ADMIN))
966 return -EPERM; 903 return -EPERM;
967 return 0; 904 return 0;
968} 905}
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 6cf8fd2b79e8..f77c60423992 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -10,6 +10,7 @@
10#include <linux/list.h> 10#include <linux/list.h>
11#include <linux/uaccess.h> 11#include <linux/uaccess.h>
12#include <linux/seq_file.h> 12#include <linux/seq_file.h>
13#include <linux/slab.h>
13#include <linux/rcupdate.h> 14#include <linux/rcupdate.h>
14#include <linux/mutex.h> 15#include <linux/mutex.h>
15 16
diff --git a/security/inode.c b/security/inode.c
index f7496c6a022b..1c812e874504 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -156,25 +156,18 @@ static int create_by_name(const char *name, mode_t mode,
156 * block. A pointer to that is in the struct vfsmount that we 156 * block. A pointer to that is in the struct vfsmount that we
157 * have around. 157 * have around.
158 */ 158 */
159 if (!parent ) { 159 if (!parent)
160 if (mount && mount->mnt_sb) { 160 parent = mount->mnt_sb->s_root;
161 parent = mount->mnt_sb->s_root;
162 }
163 }
164 if (!parent) {
165 pr_debug("securityfs: Ah! can not find a parent!\n");
166 return -EFAULT;
167 }
168 161
169 mutex_lock(&parent->d_inode->i_mutex); 162 mutex_lock(&parent->d_inode->i_mutex);
170 *dentry = lookup_one_len(name, parent, strlen(name)); 163 *dentry = lookup_one_len(name, parent, strlen(name));
171 if (!IS_ERR(dentry)) { 164 if (!IS_ERR(*dentry)) {
172 if ((mode & S_IFMT) == S_IFDIR) 165 if ((mode & S_IFMT) == S_IFDIR)
173 error = mkdir(parent->d_inode, *dentry, mode); 166 error = mkdir(parent->d_inode, *dentry, mode);
174 else 167 else
175 error = create(parent->d_inode, *dentry, mode); 168 error = create(parent->d_inode, *dentry, mode);
176 } else 169 } else
177 error = PTR_ERR(dentry); 170 error = PTR_ERR(*dentry);
178 mutex_unlock(&parent->d_inode->i_mutex); 171 mutex_unlock(&parent->d_inode->i_mutex);
179 172
180 return error; 173 return error;
diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig
index 53d9764e8f09..3d7846de8069 100644
--- a/security/integrity/ima/Kconfig
+++ b/security/integrity/ima/Kconfig
@@ -3,6 +3,7 @@
3config IMA 3config IMA
4 bool "Integrity Measurement Architecture(IMA)" 4 bool "Integrity Measurement Architecture(IMA)"
5 depends on ACPI 5 depends on ACPI
6 depends on SECURITY
6 select SECURITYFS 7 select SECURITYFS
7 select CRYPTO 8 select CRYPTO
8 select CRYPTO_HMAC 9 select CRYPTO_HMAC
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 165eb5397ea5..47fb65d1fcbd 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -65,7 +65,6 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
65 const char *cause, int result, int info); 65 const char *cause, int result, int info);
66 66
67/* Internal IMA function definitions */ 67/* Internal IMA function definitions */
68void ima_iintcache_init(void);
69int ima_init(void); 68int ima_init(void);
70void ima_cleanup(void); 69void ima_cleanup(void);
71int ima_fs_init(void); 70int ima_fs_init(void);
@@ -97,7 +96,6 @@ static inline unsigned long ima_hash_key(u8 *digest)
97 96
98/* iint cache flags */ 97/* iint cache flags */
99#define IMA_MEASURED 1 98#define IMA_MEASURED 1
100#define IMA_IINT_DUMP_STACK 512
101 99
102/* integrity data associated with an inode */ 100/* integrity data associated with an inode */
103struct ima_iint_cache { 101struct ima_iint_cache {
@@ -128,13 +126,11 @@ void ima_template_show(struct seq_file *m, void *e,
128 */ 126 */
129struct ima_iint_cache *ima_iint_insert(struct inode *inode); 127struct ima_iint_cache *ima_iint_insert(struct inode *inode);
130struct ima_iint_cache *ima_iint_find_get(struct inode *inode); 128struct ima_iint_cache *ima_iint_find_get(struct inode *inode);
131struct ima_iint_cache *ima_iint_find_insert_get(struct inode *inode);
132void ima_iint_delete(struct inode *inode);
133void iint_free(struct kref *kref); 129void iint_free(struct kref *kref);
134void iint_rcu_free(struct rcu_head *rcu); 130void iint_rcu_free(struct rcu_head *rcu);
135 131
136/* IMA policy related functions */ 132/* IMA policy related functions */
137enum ima_hooks { PATH_CHECK = 1, FILE_MMAP, BPRM_CHECK }; 133enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK };
138 134
139int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask); 135int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask);
140void ima_init_policy(void); 136void ima_init_policy(void);
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c
index 3cd58b60afd2..52015d098fdf 100644
--- a/security/integrity/ima/ima_api.c
+++ b/security/integrity/ima/ima_api.c
@@ -13,6 +13,7 @@
13 * and store_template. 13 * and store_template.
14 */ 14 */
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/slab.h>
16 17
17#include "ima.h" 18#include "ima.h"
18static const char *IMA_TEMPLATE_NAME = "ima"; 19static const char *IMA_TEMPLATE_NAME = "ima";
@@ -95,12 +96,12 @@ err_out:
95 * ima_must_measure - measure decision based on policy. 96 * ima_must_measure - measure decision based on policy.
96 * @inode: pointer to inode to measure 97 * @inode: pointer to inode to measure
97 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE) 98 * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE)
98 * @function: calling function (PATH_CHECK, BPRM_CHECK, FILE_MMAP) 99 * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP)
99 * 100 *
100 * The policy is defined in terms of keypairs: 101 * The policy is defined in terms of keypairs:
101 * subj=, obj=, type=, func=, mask=, fsmagic= 102 * subj=, obj=, type=, func=, mask=, fsmagic=
102 * subj,obj, and type: are LSM specific. 103 * subj,obj, and type: are LSM specific.
103 * func: PATH_CHECK | BPRM_CHECK | FILE_MMAP 104 * func: FILE_CHECK | BPRM_CHECK | FILE_MMAP
104 * mask: contains the permission mask 105 * mask: contains the permission mask
105 * fsmagic: hex value 106 * fsmagic: hex value
106 * 107 *
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/ima/ima_audit.c
index ff513ff737f5..5af76340470c 100644
--- a/security/integrity/ima/ima_audit.c
+++ b/security/integrity/ima/ima_audit.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/fs.h> 13#include <linux/fs.h>
14#include <linux/gfp.h>
14#include <linux/audit.h> 15#include <linux/audit.h>
15#include "ima.h" 16#include "ima.h"
16 17
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c
index 46642a19bc78..952e51373f58 100644
--- a/security/integrity/ima/ima_crypto.c
+++ b/security/integrity/ima/ima_crypto.c
@@ -18,6 +18,7 @@
18#include <linux/crypto.h> 18#include <linux/crypto.h>
19#include <linux/scatterlist.h> 19#include <linux/scatterlist.h>
20#include <linux/err.h> 20#include <linux/err.h>
21#include <linux/slab.h>
21#include "ima.h" 22#include "ima.h"
22 23
23static int init_desc(struct hash_desc *desc) 24static int init_desc(struct hash_desc *desc)
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
index 0c72c9c38956..07cb9c338cc4 100644
--- a/security/integrity/ima/ima_fs.c
+++ b/security/integrity/ima/ima_fs.c
@@ -16,6 +16,7 @@
16 * current measurement list and IMA statistics 16 * current measurement list and IMA statistics
17 */ 17 */
18#include <linux/fcntl.h> 18#include <linux/fcntl.h>
19#include <linux/slab.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/seq_file.h> 21#include <linux/seq_file.h>
21#include <linux/rculist.h> 22#include <linux/rculist.h>
diff --git a/security/integrity/ima/ima_iint.c b/security/integrity/ima/ima_iint.c
index a4e2b1dac943..2c744d488014 100644
--- a/security/integrity/ima/ima_iint.c
+++ b/security/integrity/ima/ima_iint.c
@@ -14,13 +14,12 @@
14 * - cache integrity information associated with an inode 14 * - cache integrity information associated with an inode
15 * using a radix tree. 15 * using a radix tree.
16 */ 16 */
17#include <linux/slab.h>
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/spinlock.h> 19#include <linux/spinlock.h>
19#include <linux/radix-tree.h> 20#include <linux/radix-tree.h>
20#include "ima.h" 21#include "ima.h"
21 22
22#define ima_iint_delete ima_inode_free
23
24RADIX_TREE(ima_iint_store, GFP_ATOMIC); 23RADIX_TREE(ima_iint_store, GFP_ATOMIC);
25DEFINE_SPINLOCK(ima_iint_lock); 24DEFINE_SPINLOCK(ima_iint_lock);
26 25
@@ -45,22 +44,18 @@ out:
45 return iint; 44 return iint;
46} 45}
47 46
48/* Allocate memory for the iint associated with the inode 47/**
49 * from the iint_cache slab, initialize the iint, and 48 * ima_inode_alloc - allocate an iint associated with an inode
50 * insert it into the radix tree. 49 * @inode: pointer to the inode
51 *
52 * On success return a pointer to the iint; on failure return NULL.
53 */ 50 */
54struct ima_iint_cache *ima_iint_insert(struct inode *inode) 51int ima_inode_alloc(struct inode *inode)
55{ 52{
56 struct ima_iint_cache *iint = NULL; 53 struct ima_iint_cache *iint = NULL;
57 int rc = 0; 54 int rc = 0;
58 55
59 if (!ima_initialized)
60 return iint;
61 iint = kmem_cache_alloc(iint_cache, GFP_NOFS); 56 iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
62 if (!iint) 57 if (!iint)
63 return iint; 58 return -ENOMEM;
64 59
65 rc = radix_tree_preload(GFP_NOFS); 60 rc = radix_tree_preload(GFP_NOFS);
66 if (rc < 0) 61 if (rc < 0)
@@ -69,67 +64,14 @@ struct ima_iint_cache *ima_iint_insert(struct inode *inode)
69 spin_lock(&ima_iint_lock); 64 spin_lock(&ima_iint_lock);
70 rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint); 65 rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint);
71 spin_unlock(&ima_iint_lock); 66 spin_unlock(&ima_iint_lock);
67 radix_tree_preload_end();
72out: 68out:
73 if (rc < 0) { 69 if (rc < 0)
74 kmem_cache_free(iint_cache, iint); 70 kmem_cache_free(iint_cache, iint);
75 if (rc == -EEXIST) {
76 spin_lock(&ima_iint_lock);
77 iint = radix_tree_lookup(&ima_iint_store,
78 (unsigned long)inode);
79 spin_unlock(&ima_iint_lock);
80 } else
81 iint = NULL;
82 }
83 radix_tree_preload_end();
84 return iint;
85}
86 71
87/** 72 return rc;
88 * ima_inode_alloc - allocate an iint associated with an inode
89 * @inode: pointer to the inode
90 *
91 * Return 0 on success, 1 on failure.
92 */
93int ima_inode_alloc(struct inode *inode)
94{
95 struct ima_iint_cache *iint;
96
97 if (!ima_initialized)
98 return 0;
99
100 iint = ima_iint_insert(inode);
101 if (!iint)
102 return 1;
103 return 0;
104} 73}
105 74
106/* ima_iint_find_insert_get - get the iint associated with an inode
107 *
108 * Most insertions are done at inode_alloc, except those allocated
109 * before late_initcall. When the iint does not exist, allocate it,
110 * initialize and insert it, and increment the iint refcount.
111 *
112 * (Can't initialize at security_initcall before any inodes are
113 * allocated, got to wait at least until proc_init.)
114 *
115 * Return the iint.
116 */
117struct ima_iint_cache *ima_iint_find_insert_get(struct inode *inode)
118{
119 struct ima_iint_cache *iint = NULL;
120
121 iint = ima_iint_find_get(inode);
122 if (iint)
123 return iint;
124
125 iint = ima_iint_insert(inode);
126 if (iint)
127 kref_get(&iint->refcount);
128
129 return iint;
130}
131EXPORT_SYMBOL_GPL(ima_iint_find_insert_get);
132
133/* iint_free - called when the iint refcount goes to zero */ 75/* iint_free - called when the iint refcount goes to zero */
134void iint_free(struct kref *kref) 76void iint_free(struct kref *kref)
135{ 77{
@@ -164,17 +106,15 @@ void iint_rcu_free(struct rcu_head *rcu_head)
164} 106}
165 107
166/** 108/**
167 * ima_iint_delete - called on integrity_inode_free 109 * ima_inode_free - called on security_inode_free
168 * @inode: pointer to the inode 110 * @inode: pointer to the inode
169 * 111 *
170 * Free the integrity information(iint) associated with an inode. 112 * Free the integrity information(iint) associated with an inode.
171 */ 113 */
172void ima_iint_delete(struct inode *inode) 114void ima_inode_free(struct inode *inode)
173{ 115{
174 struct ima_iint_cache *iint; 116 struct ima_iint_cache *iint;
175 117
176 if (!ima_initialized)
177 return;
178 spin_lock(&ima_iint_lock); 118 spin_lock(&ima_iint_lock);
179 iint = radix_tree_delete(&ima_iint_store, (unsigned long)inode); 119 iint = radix_tree_delete(&ima_iint_store, (unsigned long)inode);
180 spin_unlock(&ima_iint_lock); 120 spin_unlock(&ima_iint_lock);
@@ -196,9 +136,11 @@ static void init_once(void *foo)
196 kref_set(&iint->refcount, 1); 136 kref_set(&iint->refcount, 1);
197} 137}
198 138
199void __init ima_iintcache_init(void) 139static int __init ima_iintcache_init(void)
200{ 140{
201 iint_cache = 141 iint_cache =
202 kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0, 142 kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0,
203 SLAB_PANIC, init_once); 143 SLAB_PANIC, init_once);
144 return 0;
204} 145}
146security_initcall(ima_iintcache_init);
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index a40da7ae5900..b1bcb702a27c 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -16,6 +16,7 @@
16 */ 16 */
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/scatterlist.h> 18#include <linux/scatterlist.h>
19#include <linux/slab.h>
19#include <linux/err.h> 20#include <linux/err.h>
20#include "ima.h" 21#include "ima.h"
21 22
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index b85e61bcf246..b2c89d9de2a4 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -13,14 +13,15 @@
13 * License. 13 * License.
14 * 14 *
15 * File: ima_main.c 15 * File: ima_main.c
16 * implements the IMA hooks: ima_bprm_check, ima_file_mmap, 16 * implements the IMA hooks: ima_bprm_check, ima_file_mmap,
17 * and ima_path_check. 17 * and ima_file_check.
18 */ 18 */
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/file.h> 20#include <linux/file.h>
21#include <linux/binfmts.h> 21#include <linux/binfmts.h>
22#include <linux/mount.h> 22#include <linux/mount.h>
23#include <linux/mman.h> 23#include <linux/mman.h>
24#include <linux/slab.h>
24 25
25#include "ima.h" 26#include "ima.h"
26 27
@@ -35,50 +36,53 @@ static int __init hash_setup(char *str)
35} 36}
36__setup("ima_hash=", hash_setup); 37__setup("ima_hash=", hash_setup);
37 38
38/** 39struct ima_imbalance {
39 * ima_file_free - called on __fput() 40 struct hlist_node node;
40 * @file: pointer to file structure being freed 41 unsigned long fsmagic;
42};
43
44/*
45 * ima_limit_imbalance - emit one imbalance message per filesystem type
41 * 46 *
42 * Flag files that changed, based on i_version; 47 * Maintain list of filesystem types that do not measure files properly.
43 * and decrement the iint readcount/writecount. 48 * Return false if unknown, true if known.
44 */ 49 */
45void ima_file_free(struct file *file) 50static bool ima_limit_imbalance(struct file *file)
46{ 51{
47 struct inode *inode = file->f_dentry->d_inode; 52 static DEFINE_SPINLOCK(ima_imbalance_lock);
48 struct ima_iint_cache *iint; 53 static HLIST_HEAD(ima_imbalance_list);
49 54
50 if (!ima_initialized || !S_ISREG(inode->i_mode)) 55 struct super_block *sb = file->f_dentry->d_sb;
51 return; 56 struct ima_imbalance *entry;
52 iint = ima_iint_find_get(inode); 57 struct hlist_node *node;
53 if (!iint) 58 bool found = false;
54 return; 59
55 60 rcu_read_lock();
56 mutex_lock(&iint->mutex); 61 hlist_for_each_entry_rcu(entry, node, &ima_imbalance_list, node) {
57 if (iint->opencount <= 0) { 62 if (entry->fsmagic == sb->s_magic) {
58 printk(KERN_INFO 63 found = true;
59 "%s: %s open/free imbalance (r:%ld w:%ld o:%ld f:%ld)\n", 64 break;
60 __FUNCTION__, file->f_dentry->d_name.name,
61 iint->readcount, iint->writecount,
62 iint->opencount, atomic_long_read(&file->f_count));
63 if (!(iint->flags & IMA_IINT_DUMP_STACK)) {
64 dump_stack();
65 iint->flags |= IMA_IINT_DUMP_STACK;
66 } 65 }
67 } 66 }
68 iint->opencount--; 67 rcu_read_unlock();
69 68 if (found)
70 if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) 69 goto out;
71 iint->readcount--;
72 70
73 if (file->f_mode & FMODE_WRITE) { 71 entry = kmalloc(sizeof(*entry), GFP_NOFS);
74 iint->writecount--; 72 if (!entry)
75 if (iint->writecount == 0) { 73 goto out;
76 if (iint->version != inode->i_version) 74 entry->fsmagic = sb->s_magic;
77 iint->flags &= ~IMA_MEASURED; 75 spin_lock(&ima_imbalance_lock);
78 } 76 /*
79 } 77 * we could have raced and something else might have added this fs
80 mutex_unlock(&iint->mutex); 78 * to the list, but we don't really care
81 kref_put(&iint->refcount, iint_free); 79 */
80 hlist_add_head_rcu(&entry->node, &ima_imbalance_list);
81 spin_unlock(&ima_imbalance_lock);
82 printk(KERN_INFO "IMA: unmeasured files on fsmagic: %lX\n",
83 entry->fsmagic);
84out:
85 return found;
82} 86}
83 87
84/* ima_read_write_check - reflect possible reading/writing errors in the PCR. 88/* ima_read_write_check - reflect possible reading/writing errors in the PCR.
@@ -111,196 +115,142 @@ static void ima_read_write_check(enum iint_pcr_error error,
111 } 115 }
112} 116}
113 117
114static int get_path_measurement(struct ima_iint_cache *iint, struct file *file, 118/*
115 const unsigned char *filename) 119 * Update the counts given an fmode_t
120 */
121static void ima_inc_counts(struct ima_iint_cache *iint, fmode_t mode)
116{ 122{
117 int rc = 0; 123 BUG_ON(!mutex_is_locked(&iint->mutex));
118
119 iint->opencount++;
120 iint->readcount++;
121
122 rc = ima_collect_measurement(iint, file);
123 if (!rc)
124 ima_store_measurement(iint, file, filename);
125 return rc;
126}
127 124
128static void ima_update_counts(struct ima_iint_cache *iint, int mask)
129{
130 iint->opencount++; 125 iint->opencount++;
131 if ((mask & MAY_WRITE) || (mask == 0)) 126 if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
132 iint->writecount++;
133 else if (mask & (MAY_READ | MAY_EXEC))
134 iint->readcount++; 127 iint->readcount++;
128 if (mode & FMODE_WRITE)
129 iint->writecount++;
135} 130}
136 131
137/** 132/*
138 * ima_path_check - based on policy, collect/store measurement. 133 * ima_counts_get - increment file counts
139 * @path: contains a pointer to the path to be measured
140 * @mask: contains MAY_READ, MAY_WRITE or MAY_EXECUTE
141 *
142 * Measure the file being open for readonly, based on the
143 * ima_must_measure() policy decision.
144 * 134 *
145 * Keep read/write counters for all files, but only 135 * Maintain read/write counters for all files, but only
146 * invalidate the PCR for measured files: 136 * invalidate the PCR for measured files:
147 * - Opening a file for write when already open for read, 137 * - Opening a file for write when already open for read,
148 * results in a time of measure, time of use (ToMToU) error. 138 * results in a time of measure, time of use (ToMToU) error.
149 * - Opening a file for read when already open for write, 139 * - Opening a file for read when already open for write,
150 * could result in a file measurement error. 140 * could result in a file measurement error.
151 * 141 *
152 * Always return 0 and audit dentry_open failures.
153 * (Return code will be based upon measurement appraisal.)
154 */ 142 */
155int ima_path_check(struct path *path, int mask, int update_counts) 143void ima_counts_get(struct file *file)
156{ 144{
157 struct inode *inode = path->dentry->d_inode; 145 struct dentry *dentry = file->f_path.dentry;
146 struct inode *inode = dentry->d_inode;
147 fmode_t mode = file->f_mode;
158 struct ima_iint_cache *iint; 148 struct ima_iint_cache *iint;
159 struct file *file = NULL;
160 int rc; 149 int rc;
161 150
162 if (!ima_initialized || !S_ISREG(inode->i_mode)) 151 if (!ima_initialized || !S_ISREG(inode->i_mode))
163 return 0; 152 return;
164 iint = ima_iint_find_insert_get(inode); 153 iint = ima_iint_find_get(inode);
165 if (!iint) 154 if (!iint)
166 return 0; 155 return;
167
168 mutex_lock(&iint->mutex); 156 mutex_lock(&iint->mutex);
169 if (update_counts) 157 rc = ima_must_measure(iint, inode, MAY_READ, FILE_CHECK);
170 ima_update_counts(iint, mask);
171
172 rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK);
173 if (rc < 0) 158 if (rc < 0)
174 goto out; 159 goto out;
175 160
176 if ((mask & MAY_WRITE) || (mask == 0)) 161 if (mode & FMODE_WRITE) {
177 ima_read_write_check(TOMTOU, iint, inode, 162 ima_read_write_check(TOMTOU, iint, inode, dentry->d_name.name);
178 path->dentry->d_name.name);
179
180 if ((mask & (MAY_WRITE | MAY_READ | MAY_EXEC)) != MAY_READ)
181 goto out; 163 goto out;
182
183 ima_read_write_check(OPEN_WRITERS, iint, inode,
184 path->dentry->d_name.name);
185 if (!(iint->flags & IMA_MEASURED)) {
186 struct dentry *dentry = dget(path->dentry);
187 struct vfsmount *mnt = mntget(path->mnt);
188
189 file = dentry_open(dentry, mnt, O_RDONLY | O_LARGEFILE,
190 current_cred());
191 if (IS_ERR(file)) {
192 int audit_info = 0;
193
194 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
195 dentry->d_name.name,
196 "add_measurement",
197 "dentry_open failed",
198 1, audit_info);
199 file = NULL;
200 goto out;
201 }
202 rc = get_path_measurement(iint, file, dentry->d_name.name);
203 } 164 }
165 ima_read_write_check(OPEN_WRITERS, iint, inode, dentry->d_name.name);
204out: 166out:
167 ima_inc_counts(iint, file->f_mode);
205 mutex_unlock(&iint->mutex); 168 mutex_unlock(&iint->mutex);
206 if (file) 169
207 fput(file);
208 kref_put(&iint->refcount, iint_free); 170 kref_put(&iint->refcount, iint_free);
209 return 0;
210} 171}
211EXPORT_SYMBOL_GPL(ima_path_check);
212 172
213static int process_measurement(struct file *file, const unsigned char *filename, 173/*
214 int mask, int function) 174 * Decrement ima counts
175 */
176static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode,
177 struct file *file)
215{ 178{
216 struct inode *inode = file->f_dentry->d_inode; 179 mode_t mode = file->f_mode;
217 struct ima_iint_cache *iint; 180 BUG_ON(!mutex_is_locked(&iint->mutex));
218 int rc;
219 181
220 if (!ima_initialized || !S_ISREG(inode->i_mode)) 182 iint->opencount--;
221 return 0; 183 if ((mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
222 iint = ima_iint_find_insert_get(inode); 184 iint->readcount--;
223 if (!iint) 185 if (mode & FMODE_WRITE) {
224 return -ENOMEM; 186 iint->writecount--;
225 187 if (iint->writecount == 0) {
226 mutex_lock(&iint->mutex); 188 if (iint->version != inode->i_version)
227 rc = ima_must_measure(iint, inode, mask, function); 189 iint->flags &= ~IMA_MEASURED;
228 if (rc != 0) 190 }
229 goto out; 191 }
230 192
231 rc = ima_collect_measurement(iint, file); 193 if (((iint->opencount < 0) ||
232 if (!rc) 194 (iint->readcount < 0) ||
233 ima_store_measurement(iint, file, filename); 195 (iint->writecount < 0)) &&
234out: 196 !ima_limit_imbalance(file)) {
235 mutex_unlock(&iint->mutex); 197 printk(KERN_INFO "%s: open/free imbalance (r:%ld w:%ld o:%ld)\n",
236 kref_put(&iint->refcount, iint_free); 198 __FUNCTION__, iint->readcount, iint->writecount,
237 return rc; 199 iint->opencount);
200 dump_stack();
201 }
238} 202}
239 203
240/* 204/**
241 * ima_counts_put - decrement file counts 205 * ima_file_free - called on __fput()
206 * @file: pointer to file structure being freed
242 * 207 *
243 * File counts are incremented in ima_path_check. On file open 208 * Flag files that changed, based on i_version;
244 * error, such as ETXTBSY, decrement the counts to prevent 209 * and decrement the iint readcount/writecount.
245 * unnecessary imbalance messages.
246 */ 210 */
247void ima_counts_put(struct path *path, int mask) 211void ima_file_free(struct file *file)
248{ 212{
249 struct inode *inode = path->dentry->d_inode; 213 struct inode *inode = file->f_dentry->d_inode;
250 struct ima_iint_cache *iint; 214 struct ima_iint_cache *iint;
251 215
252 /* The inode may already have been freed, freeing the iint 216 if (!ima_initialized || !S_ISREG(inode->i_mode))
253 * with it. Verify the inode is not NULL before dereferencing
254 * it.
255 */
256 if (!ima_initialized || !inode || !S_ISREG(inode->i_mode))
257 return; 217 return;
258 iint = ima_iint_find_insert_get(inode); 218 iint = ima_iint_find_get(inode);
259 if (!iint) 219 if (!iint)
260 return; 220 return;
261 221
262 mutex_lock(&iint->mutex); 222 mutex_lock(&iint->mutex);
263 iint->opencount--; 223 ima_dec_counts(iint, inode, file);
264 if ((mask & MAY_WRITE) || (mask == 0))
265 iint->writecount--;
266 else if (mask & (MAY_READ | MAY_EXEC))
267 iint->readcount--;
268 mutex_unlock(&iint->mutex); 224 mutex_unlock(&iint->mutex);
269
270 kref_put(&iint->refcount, iint_free); 225 kref_put(&iint->refcount, iint_free);
271} 226}
272 227
273/* 228static int process_measurement(struct file *file, const unsigned char *filename,
274 * ima_counts_get - increment file counts 229 int mask, int function)
275 *
276 * - for IPC shm and shmat file.
277 * - for nfsd exported files.
278 *
279 * Increment the counts for these files to prevent unnecessary
280 * imbalance messages.
281 */
282void ima_counts_get(struct file *file)
283{ 230{
284 struct inode *inode = file->f_dentry->d_inode; 231 struct inode *inode = file->f_dentry->d_inode;
285 struct ima_iint_cache *iint; 232 struct ima_iint_cache *iint;
233 int rc;
286 234
287 if (!ima_initialized || !S_ISREG(inode->i_mode)) 235 if (!ima_initialized || !S_ISREG(inode->i_mode))
288 return; 236 return 0;
289 iint = ima_iint_find_insert_get(inode); 237 iint = ima_iint_find_get(inode);
290 if (!iint) 238 if (!iint)
291 return; 239 return -ENOMEM;
240
292 mutex_lock(&iint->mutex); 241 mutex_lock(&iint->mutex);
293 iint->opencount++; 242 rc = ima_must_measure(iint, inode, mask, function);
294 if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) 243 if (rc != 0)
295 iint->readcount++; 244 goto out;
296 245
297 if (file->f_mode & FMODE_WRITE) 246 rc = ima_collect_measurement(iint, file);
298 iint->writecount++; 247 if (!rc)
248 ima_store_measurement(iint, file, filename);
249out:
299 mutex_unlock(&iint->mutex); 250 mutex_unlock(&iint->mutex);
300
301 kref_put(&iint->refcount, iint_free); 251 kref_put(&iint->refcount, iint_free);
252 return rc;
302} 253}
303EXPORT_SYMBOL_GPL(ima_counts_get);
304 254
305/** 255/**
306 * ima_file_mmap - based on policy, collect/store measurement. 256 * ima_file_mmap - based on policy, collect/store measurement.
@@ -347,11 +297,31 @@ int ima_bprm_check(struct linux_binprm *bprm)
347 return 0; 297 return 0;
348} 298}
349 299
300/**
301 * ima_path_check - based on policy, collect/store measurement.
302 * @file: pointer to the file to be measured
303 * @mask: contains MAY_READ, MAY_WRITE or MAY_EXECUTE
304 *
305 * Measure files based on the ima_must_measure() policy decision.
306 *
307 * Always return 0 and audit dentry_open failures.
308 * (Return code will be based upon measurement appraisal.)
309 */
310int ima_file_check(struct file *file, int mask)
311{
312 int rc;
313
314 rc = process_measurement(file, file->f_dentry->d_name.name,
315 mask & (MAY_READ | MAY_WRITE | MAY_EXEC),
316 FILE_CHECK);
317 return 0;
318}
319EXPORT_SYMBOL_GPL(ima_file_check);
320
350static int __init init_ima(void) 321static int __init init_ima(void)
351{ 322{
352 int error; 323 int error;
353 324
354 ima_iintcache_init();
355 error = ima_init(); 325 error = ima_init();
356 ima_initialized = 1; 326 ima_initialized = 1;
357 return error; 327 return error;
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index e1278399b345..8643a93c5963 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -15,6 +15,7 @@
15#include <linux/security.h> 15#include <linux/security.h>
16#include <linux/magic.h> 16#include <linux/magic.h>
17#include <linux/parser.h> 17#include <linux/parser.h>
18#include <linux/slab.h>
18 19
19#include "ima.h" 20#include "ima.h"
20 21
@@ -67,7 +68,7 @@ static struct ima_measure_rule_entry default_rules[] = {
67 .flags = IMA_FUNC | IMA_MASK}, 68 .flags = IMA_FUNC | IMA_MASK},
68 {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC, 69 {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC,
69 .flags = IMA_FUNC | IMA_MASK}, 70 .flags = IMA_FUNC | IMA_MASK},
70 {.action = MEASURE,.func = PATH_CHECK,.mask = MAY_READ,.uid = 0, 71 {.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = 0,
71 .flags = IMA_FUNC | IMA_MASK | IMA_UID}, 72 .flags = IMA_FUNC | IMA_MASK | IMA_UID},
72}; 73};
73 74
@@ -282,8 +283,11 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
282 break; 283 break;
283 case Opt_func: 284 case Opt_func:
284 audit_log_format(ab, "func=%s ", args[0].from); 285 audit_log_format(ab, "func=%s ", args[0].from);
285 if (strcmp(args[0].from, "PATH_CHECK") == 0) 286 if (strcmp(args[0].from, "FILE_CHECK") == 0)
286 entry->func = PATH_CHECK; 287 entry->func = FILE_CHECK;
288 /* PATH_CHECK is for backwards compat */
289 else if (strcmp(args[0].from, "PATH_CHECK") == 0)
290 entry->func = FILE_CHECK;
287 else if (strcmp(args[0].from, "FILE_MMAP") == 0) 291 else if (strcmp(args[0].from, "FILE_MMAP") == 0)
288 entry->func = FILE_MMAP; 292 entry->func = FILE_MMAP;
289 else if (strcmp(args[0].from, "BPRM_CHECK") == 0) 293 else if (strcmp(args[0].from, "BPRM_CHECK") == 0)
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index a0880e9c8e05..46ba62b1adf5 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -20,6 +20,7 @@
20 */ 20 */
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/rculist.h> 22#include <linux/rculist.h>
23#include <linux/slab.h>
23#include "ima.h" 24#include "ima.h"
24 25
25LIST_HEAD(ima_measurements); /* list of all measurements */ 26LIST_HEAD(ima_measurements); /* list of all measurements */
diff --git a/security/keys/gc.c b/security/keys/gc.c
index 4770be375ffe..a46e825cbf02 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -77,9 +77,10 @@ static bool key_gc_keyring(struct key *keyring, time_t limit)
77 goto dont_gc; 77 goto dont_gc;
78 78
79 /* scan the keyring looking for dead keys */ 79 /* scan the keyring looking for dead keys */
80 rcu_read_lock();
80 klist = rcu_dereference(keyring->payload.subscriptions); 81 klist = rcu_dereference(keyring->payload.subscriptions);
81 if (!klist) 82 if (!klist)
82 goto dont_gc; 83 goto unlock_dont_gc;
83 84
84 for (loop = klist->nkeys - 1; loop >= 0; loop--) { 85 for (loop = klist->nkeys - 1; loop >= 0; loop--) {
85 key = klist->keys[loop]; 86 key = klist->keys[loop];
@@ -88,11 +89,14 @@ static bool key_gc_keyring(struct key *keyring, time_t limit)
88 goto do_gc; 89 goto do_gc;
89 } 90 }
90 91
92unlock_dont_gc:
93 rcu_read_unlock();
91dont_gc: 94dont_gc:
92 kleave(" = false"); 95 kleave(" = false");
93 return false; 96 return false;
94 97
95do_gc: 98do_gc:
99 rcu_read_unlock();
96 key_gc_cursor = keyring->serial; 100 key_gc_cursor = keyring->serial;
97 key_get(keyring); 101 key_get(keyring);
98 spin_unlock(&key_serial_lock); 102 spin_unlock(&key_serial_lock);
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 06ec722897be..e9c2e7c584d9 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -1194,7 +1194,7 @@ long keyctl_get_security(key_serial_t keyid,
1194 * have the authorisation token handy */ 1194 * have the authorisation token handy */
1195 instkey = key_get_instantiation_authkey(keyid); 1195 instkey = key_get_instantiation_authkey(keyid);
1196 if (IS_ERR(instkey)) 1196 if (IS_ERR(instkey))
1197 return PTR_ERR(key_ref); 1197 return PTR_ERR(instkey);
1198 key_put(instkey); 1198 key_put(instkey);
1199 1199
1200 key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, 0); 1200 key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, 0);
@@ -1236,6 +1236,7 @@ long keyctl_get_security(key_serial_t keyid,
1236 */ 1236 */
1237long keyctl_session_to_parent(void) 1237long keyctl_session_to_parent(void)
1238{ 1238{
1239#ifdef TIF_NOTIFY_RESUME
1239 struct task_struct *me, *parent; 1240 struct task_struct *me, *parent;
1240 const struct cred *mycred, *pcred; 1241 const struct cred *mycred, *pcred;
1241 struct cred *cred, *oldcred; 1242 struct cred *cred, *oldcred;
@@ -1326,6 +1327,15 @@ not_permitted:
1326error_keyring: 1327error_keyring:
1327 key_ref_put(keyring_r); 1328 key_ref_put(keyring_r);
1328 return ret; 1329 return ret;
1330
1331#else /* !TIF_NOTIFY_RESUME */
1332 /*
1333 * To be removed when TIF_NOTIFY_RESUME has been implemented on
1334 * m68k/xtensa
1335 */
1336#warning TIF_NOTIFY_RESUME not implemented
1337 return -EOPNOTSUPP;
1338#endif /* !TIF_NOTIFY_RESUME */
1329} 1339}
1330 1340
1331/*****************************************************************************/ 1341/*****************************************************************************/
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 8ec02746ca99..1e4b0037935c 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -20,6 +20,11 @@
20#include <asm/uaccess.h> 20#include <asm/uaccess.h>
21#include "internal.h" 21#include "internal.h"
22 22
23#define rcu_dereference_locked_keyring(keyring) \
24 (rcu_dereference_protected( \
25 (keyring)->payload.subscriptions, \
26 rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem)))
27
23/* 28/*
24 * when plumbing the depths of the key tree, this sets a hard limit set on how 29 * when plumbing the depths of the key tree, this sets a hard limit set on how
25 * deep we're willing to go 30 * deep we're willing to go
@@ -151,7 +156,9 @@ static void keyring_destroy(struct key *keyring)
151 write_unlock(&keyring_name_lock); 156 write_unlock(&keyring_name_lock);
152 } 157 }
153 158
154 klist = rcu_dereference(keyring->payload.subscriptions); 159 klist = rcu_dereference_check(keyring->payload.subscriptions,
160 rcu_read_lock_held() ||
161 atomic_read(&keyring->usage) == 0);
155 if (klist) { 162 if (klist) {
156 for (loop = klist->nkeys - 1; loop >= 0; loop--) 163 for (loop = klist->nkeys - 1; loop >= 0; loop--)
157 key_put(klist->keys[loop]); 164 key_put(klist->keys[loop]);
@@ -199,8 +206,7 @@ static long keyring_read(const struct key *keyring,
199 int loop, ret; 206 int loop, ret;
200 207
201 ret = 0; 208 ret = 0;
202 klist = rcu_dereference(keyring->payload.subscriptions); 209 klist = rcu_dereference_locked_keyring(keyring);
203
204 if (klist) { 210 if (klist) {
205 /* calculate how much data we could return */ 211 /* calculate how much data we could return */
206 qty = klist->nkeys * sizeof(key_serial_t); 212 qty = klist->nkeys * sizeof(key_serial_t);
@@ -524,9 +530,8 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
524 struct key *keyring; 530 struct key *keyring;
525 int bucket; 531 int bucket;
526 532
527 keyring = ERR_PTR(-EINVAL);
528 if (!name) 533 if (!name)
529 goto error; 534 return ERR_PTR(-EINVAL);
530 535
531 bucket = keyring_hash(name); 536 bucket = keyring_hash(name);
532 537
@@ -553,17 +558,18 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
553 KEY_SEARCH) < 0) 558 KEY_SEARCH) < 0)
554 continue; 559 continue;
555 560
556 /* we've got a match */ 561 /* we've got a match but we might end up racing with
557 atomic_inc(&keyring->usage); 562 * key_cleanup() if the keyring is currently 'dead'
558 read_unlock(&keyring_name_lock); 563 * (ie. it has a zero usage count) */
559 goto error; 564 if (!atomic_inc_not_zero(&keyring->usage))
565 continue;
566 goto out;
560 } 567 }
561 } 568 }
562 569
563 read_unlock(&keyring_name_lock);
564 keyring = ERR_PTR(-ENOKEY); 570 keyring = ERR_PTR(-ENOKEY);
565 571out:
566 error: 572 read_unlock(&keyring_name_lock);
567 return keyring; 573 return keyring;
568 574
569} /* end find_keyring_by_name() */ 575} /* end find_keyring_by_name() */
@@ -718,8 +724,7 @@ int __key_link(struct key *keyring, struct key *key)
718 } 724 }
719 725
720 /* see if there's a matching key we can displace */ 726 /* see if there's a matching key we can displace */
721 klist = keyring->payload.subscriptions; 727 klist = rcu_dereference_locked_keyring(keyring);
722
723 if (klist && klist->nkeys > 0) { 728 if (klist && klist->nkeys > 0) {
724 struct key_type *type = key->type; 729 struct key_type *type = key->type;
725 730
@@ -763,8 +768,6 @@ int __key_link(struct key *keyring, struct key *key)
763 if (ret < 0) 768 if (ret < 0)
764 goto error2; 769 goto error2;
765 770
766 klist = keyring->payload.subscriptions;
767
768 if (klist && klist->nkeys < klist->maxkeys) { 771 if (klist && klist->nkeys < klist->maxkeys) {
769 /* there's sufficient slack space to add directly */ 772 /* there's sufficient slack space to add directly */
770 atomic_inc(&key->usage); 773 atomic_inc(&key->usage);
@@ -866,7 +869,7 @@ int key_unlink(struct key *keyring, struct key *key)
866 869
867 down_write(&keyring->sem); 870 down_write(&keyring->sem);
868 871
869 klist = keyring->payload.subscriptions; 872 klist = rcu_dereference_locked_keyring(keyring);
870 if (klist) { 873 if (klist) {
871 /* search the keyring for the key */ 874 /* search the keyring for the key */
872 for (loop = 0; loop < klist->nkeys; loop++) 875 for (loop = 0; loop < klist->nkeys; loop++)
@@ -957,7 +960,7 @@ int keyring_clear(struct key *keyring)
957 /* detach the pointer block with the locks held */ 960 /* detach the pointer block with the locks held */
958 down_write(&keyring->sem); 961 down_write(&keyring->sem);
959 962
960 klist = keyring->payload.subscriptions; 963 klist = rcu_dereference_locked_keyring(keyring);
961 if (klist) { 964 if (klist) {
962 /* adjust the quota */ 965 /* adjust the quota */
963 key_payload_reserve(keyring, 966 key_payload_reserve(keyring,
@@ -989,7 +992,9 @@ EXPORT_SYMBOL(keyring_clear);
989 */ 992 */
990static void keyring_revoke(struct key *keyring) 993static void keyring_revoke(struct key *keyring)
991{ 994{
992 struct keyring_list *klist = keyring->payload.subscriptions; 995 struct keyring_list *klist;
996
997 klist = rcu_dereference_locked_keyring(keyring);
993 998
994 /* adjust the quota */ 999 /* adjust the quota */
995 key_payload_reserve(keyring, 0); 1000 key_payload_reserve(keyring, 0);
@@ -1023,7 +1028,7 @@ void keyring_gc(struct key *keyring, time_t limit)
1023 1028
1024 down_write(&keyring->sem); 1029 down_write(&keyring->sem);
1025 1030
1026 klist = keyring->payload.subscriptions; 1031 klist = rcu_dereference_locked_keyring(keyring);
1027 if (!klist) 1032 if (!klist)
1028 goto no_klist; 1033 goto no_klist;
1029 1034
diff --git a/security/keys/proc.c b/security/keys/proc.c
index 9d01021ca0c8..706d63f4f185 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -12,7 +12,6 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/slab.h>
16#include <linux/fs.h> 15#include <linux/fs.h>
17#include <linux/proc_fs.h> 16#include <linux/proc_fs.h>
18#include <linux/seq_file.h> 17#include <linux/seq_file.h>
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 5c23afb31ece..06c2ccf26ed3 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -12,7 +12,6 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/slab.h>
16#include <linux/keyctl.h> 15#include <linux/keyctl.h>
17#include <linux/fs.h> 16#include <linux/fs.h>
18#include <linux/err.h> 17#include <linux/err.h>
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 03fe63ed55bd..d8c1a6a0fb08 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -68,7 +68,8 @@ static int call_sbin_request_key(struct key_construction *cons,
68{ 68{
69 const struct cred *cred = current_cred(); 69 const struct cred *cred = current_cred();
70 key_serial_t prkey, sskey; 70 key_serial_t prkey, sskey;
71 struct key *key = cons->key, *authkey = cons->authkey, *keyring; 71 struct key *key = cons->key, *authkey = cons->authkey, *keyring,
72 *session;
72 char *argv[9], *envp[3], uid_str[12], gid_str[12]; 73 char *argv[9], *envp[3], uid_str[12], gid_str[12];
73 char key_str[12], keyring_str[3][12]; 74 char key_str[12], keyring_str[3][12];
74 char desc[20]; 75 char desc[20];
@@ -93,7 +94,7 @@ static int call_sbin_request_key(struct key_construction *cons,
93 } 94 }
94 95
95 /* attach the auth key to the session keyring */ 96 /* attach the auth key to the session keyring */
96 ret = __key_link(keyring, authkey); 97 ret = key_link(keyring, authkey);
97 if (ret < 0) 98 if (ret < 0)
98 goto error_link; 99 goto error_link;
99 100
@@ -112,10 +113,12 @@ static int call_sbin_request_key(struct key_construction *cons,
112 if (cred->tgcred->process_keyring) 113 if (cred->tgcred->process_keyring)
113 prkey = cred->tgcred->process_keyring->serial; 114 prkey = cred->tgcred->process_keyring->serial;
114 115
115 if (cred->tgcred->session_keyring) 116 rcu_read_lock();
116 sskey = rcu_dereference(cred->tgcred->session_keyring)->serial; 117 session = rcu_dereference(cred->tgcred->session_keyring);
117 else 118 if (!session)
118 sskey = cred->user->session_keyring->serial; 119 session = cred->user->session_keyring;
120 sskey = session->serial;
121 rcu_read_unlock();
119 122
120 sprintf(keyring_str[2], "%d", sskey); 123 sprintf(keyring_str[2], "%d", sskey);
121 124
@@ -336,8 +339,10 @@ static int construct_alloc_key(struct key_type *type,
336 339
337key_already_present: 340key_already_present:
338 mutex_unlock(&key_construction_mutex); 341 mutex_unlock(&key_construction_mutex);
339 if (dest_keyring) 342 if (dest_keyring) {
343 __key_link(dest_keyring, key_ref_to_ptr(key_ref));
340 up_write(&dest_keyring->sem); 344 up_write(&dest_keyring->sem);
345 }
341 mutex_unlock(&user->cons_lock); 346 mutex_unlock(&user->cons_lock);
342 key_put(key); 347 key_put(key);
343 *_key = key = key_ref_to_ptr(key_ref); 348 *_key = key = key_ref_to_ptr(key_ref);
@@ -428,6 +433,11 @@ struct key *request_key_and_link(struct key_type *type,
428 433
429 if (!IS_ERR(key_ref)) { 434 if (!IS_ERR(key_ref)) {
430 key = key_ref_to_ptr(key_ref); 435 key = key_ref_to_ptr(key_ref);
436 if (dest_keyring) {
437 construct_get_dest_keyring(&dest_keyring);
438 key_link(dest_keyring, key);
439 key_put(dest_keyring);
440 }
431 } else if (PTR_ERR(key_ref) != -EAGAIN) { 441 } else if (PTR_ERR(key_ref) != -EAGAIN) {
432 key = ERR_CAST(key_ref); 442 key = ERR_CAST(key_ref);
433 } else { 443 } else {
diff --git a/security/keys/sysctl.c b/security/keys/sysctl.c
index 5e05dc09e2db..ee32d181764a 100644
--- a/security/keys/sysctl.c
+++ b/security/keys/sysctl.c
@@ -17,54 +17,49 @@ static const int zero, one = 1, max = INT_MAX;
17 17
18ctl_table key_sysctls[] = { 18ctl_table key_sysctls[] = {
19 { 19 {
20 .ctl_name = CTL_UNNUMBERED,
21 .procname = "maxkeys", 20 .procname = "maxkeys",
22 .data = &key_quota_maxkeys, 21 .data = &key_quota_maxkeys,
23 .maxlen = sizeof(unsigned), 22 .maxlen = sizeof(unsigned),
24 .mode = 0644, 23 .mode = 0644,
25 .proc_handler = &proc_dointvec_minmax, 24 .proc_handler = proc_dointvec_minmax,
26 .extra1 = (void *) &one, 25 .extra1 = (void *) &one,
27 .extra2 = (void *) &max, 26 .extra2 = (void *) &max,
28 }, 27 },
29 { 28 {
30 .ctl_name = CTL_UNNUMBERED,
31 .procname = "maxbytes", 29 .procname = "maxbytes",
32 .data = &key_quota_maxbytes, 30 .data = &key_quota_maxbytes,
33 .maxlen = sizeof(unsigned), 31 .maxlen = sizeof(unsigned),
34 .mode = 0644, 32 .mode = 0644,
35 .proc_handler = &proc_dointvec_minmax, 33 .proc_handler = proc_dointvec_minmax,
36 .extra1 = (void *) &one, 34 .extra1 = (void *) &one,
37 .extra2 = (void *) &max, 35 .extra2 = (void *) &max,
38 }, 36 },
39 { 37 {
40 .ctl_name = CTL_UNNUMBERED,
41 .procname = "root_maxkeys", 38 .procname = "root_maxkeys",
42 .data = &key_quota_root_maxkeys, 39 .data = &key_quota_root_maxkeys,
43 .maxlen = sizeof(unsigned), 40 .maxlen = sizeof(unsigned),
44 .mode = 0644, 41 .mode = 0644,
45 .proc_handler = &proc_dointvec_minmax, 42 .proc_handler = proc_dointvec_minmax,
46 .extra1 = (void *) &one, 43 .extra1 = (void *) &one,
47 .extra2 = (void *) &max, 44 .extra2 = (void *) &max,
48 }, 45 },
49 { 46 {
50 .ctl_name = CTL_UNNUMBERED,
51 .procname = "root_maxbytes", 47 .procname = "root_maxbytes",
52 .data = &key_quota_root_maxbytes, 48 .data = &key_quota_root_maxbytes,
53 .maxlen = sizeof(unsigned), 49 .maxlen = sizeof(unsigned),
54 .mode = 0644, 50 .mode = 0644,
55 .proc_handler = &proc_dointvec_minmax, 51 .proc_handler = proc_dointvec_minmax,
56 .extra1 = (void *) &one, 52 .extra1 = (void *) &one,
57 .extra2 = (void *) &max, 53 .extra2 = (void *) &max,
58 }, 54 },
59 { 55 {
60 .ctl_name = CTL_UNNUMBERED,
61 .procname = "gc_delay", 56 .procname = "gc_delay",
62 .data = &key_gc_delay, 57 .data = &key_gc_delay,
63 .maxlen = sizeof(unsigned), 58 .maxlen = sizeof(unsigned),
64 .mode = 0644, 59 .mode = 0644,
65 .proc_handler = &proc_dointvec_minmax, 60 .proc_handler = proc_dointvec_minmax,
66 .extra1 = (void *) &zero, 61 .extra1 = (void *) &zero,
67 .extra2 = (void *) &max, 62 .extra2 = (void *) &max,
68 }, 63 },
69 { .ctl_name = 0 } 64 { }
70}; 65};
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 7c687d568221..e9aa07929656 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -199,7 +199,8 @@ long user_read(const struct key *key, char __user *buffer, size_t buflen)
199 struct user_key_payload *upayload; 199 struct user_key_payload *upayload;
200 long ret; 200 long ret;
201 201
202 upayload = rcu_dereference(key->payload.data); 202 upayload = rcu_dereference_protected(
203 key->payload.data, rwsem_is_locked(&((struct key *)key)->sem));
203 ret = upayload->datalen; 204 ret = upayload->datalen;
204 205
205 /* we can return the data as is */ 206 /* we can return the data as is */
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 3bb90b6f1dd3..893365b79a29 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -14,6 +14,7 @@
14#include <linux/types.h> 14#include <linux/types.h>
15#include <linux/stddef.h> 15#include <linux/stddef.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/gfp.h>
17#include <linux/fs.h> 18#include <linux/fs.h>
18#include <linux/init.h> 19#include <linux/init.h>
19#include <net/sock.h> 20#include <net/sock.h>
@@ -273,11 +274,11 @@ static void dump_common_audit_data(struct audit_buffer *ab,
273 case AF_INET: { 274 case AF_INET: {
274 struct inet_sock *inet = inet_sk(sk); 275 struct inet_sock *inet = inet_sk(sk);
275 276
276 print_ipv4_addr(ab, inet->rcv_saddr, 277 print_ipv4_addr(ab, inet->inet_rcv_saddr,
277 inet->sport, 278 inet->inet_sport,
278 "laddr", "lport"); 279 "laddr", "lport");
279 print_ipv4_addr(ab, inet->daddr, 280 print_ipv4_addr(ab, inet->inet_daddr,
280 inet->dport, 281 inet->inet_dport,
281 "faddr", "fport"); 282 "faddr", "fport");
282 break; 283 break;
283 } 284 }
@@ -286,10 +287,10 @@ static void dump_common_audit_data(struct audit_buffer *ab,
286 struct ipv6_pinfo *inet6 = inet6_sk(sk); 287 struct ipv6_pinfo *inet6 = inet6_sk(sk);
287 288
288 print_ipv6_addr(ab, &inet6->rcv_saddr, 289 print_ipv6_addr(ab, &inet6->rcv_saddr,
289 inet->sport, 290 inet->inet_sport,
290 "laddr", "lport"); 291 "laddr", "lport");
291 print_ipv6_addr(ab, &inet6->daddr, 292 print_ipv6_addr(ab, &inet6->daddr,
292 inet->dport, 293 inet->inet_dport,
293 "faddr", "fport"); 294 "faddr", "fport");
294 break; 295 break;
295 } 296 }
@@ -354,6 +355,10 @@ static void dump_common_audit_data(struct audit_buffer *ab,
354 } 355 }
355 break; 356 break;
356#endif 357#endif
358 case LSM_AUDIT_DATA_KMOD:
359 audit_log_format(ab, " kmod=");
360 audit_log_untrustedstring(ab, a->u.kmod_name);
361 break;
357 } /* switch (a->type) */ 362 } /* switch (a->type) */
358} 363}
359 364
diff --git a/security/min_addr.c b/security/min_addr.c
index c844eed7915d..f728728f193b 100644
--- a/security/min_addr.c
+++ b/security/min_addr.c
@@ -33,6 +33,9 @@ int mmap_min_addr_handler(struct ctl_table *table, int write,
33{ 33{
34 int ret; 34 int ret;
35 35
36 if (write && !capable(CAP_SYS_RAWIO))
37 return -EPERM;
38
36 ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos); 39 ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
37 40
38 update_mmap_min_addr(); 41 update_mmap_min_addr();
@@ -40,7 +43,7 @@ int mmap_min_addr_handler(struct ctl_table *table, int write,
40 return ret; 43 return ret;
41} 44}
42 45
43int __init init_mmap_min_addr(void) 46static int __init init_mmap_min_addr(void)
44{ 47{
45 update_mmap_min_addr(); 48 update_mmap_min_addr();
46 49
diff --git a/security/root_plug.c b/security/root_plug.c
deleted file mode 100644
index 2f7ffa67c4d2..000000000000
--- a/security/root_plug.c
+++ /dev/null
@@ -1,90 +0,0 @@
1/*
2 * Root Plug sample LSM module
3 *
4 * Originally written for a Linux Journal.
5 *
6 * Copyright (C) 2002 Greg Kroah-Hartman <greg@kroah.com>
7 *
8 * Prevents any programs running with egid == 0 if a specific USB device
9 * is not present in the system. Yes, it can be gotten around, but is a
10 * nice starting point for people to play with, and learn the LSM
11 * interface.
12 *
13 * If you want to turn this into something with a semblance of security,
14 * you need to hook the task_* functions also.
15 *
16 * See http://www.linuxjournal.com/article.php?sid=6279 for more information
17 * about this code.
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License as
21 * published by the Free Software Foundation, version 2 of the
22 * License.
23 */
24
25#include <linux/kernel.h>
26#include <linux/init.h>
27#include <linux/security.h>
28#include <linux/usb.h>
29#include <linux/moduleparam.h>
30
31/* default is a generic type of usb to serial converter */
32static int vendor_id = 0x0557;
33static int product_id = 0x2008;
34
35module_param(vendor_id, uint, 0400);
36module_param(product_id, uint, 0400);
37
38/* should we print out debug messages */
39static int debug = 0;
40
41module_param(debug, bool, 0600);
42
43#define MY_NAME "root_plug"
44
45#define root_dbg(fmt, arg...) \
46 do { \
47 if (debug) \
48 printk(KERN_DEBUG "%s: %s: " fmt , \
49 MY_NAME , __func__ , \
50 ## arg); \
51 } while (0)
52
53static int rootplug_bprm_check_security (struct linux_binprm *bprm)
54{
55 struct usb_device *dev;
56
57 root_dbg("file %s, e_uid = %d, e_gid = %d\n",
58 bprm->filename, bprm->cred->euid, bprm->cred->egid);
59
60 if (bprm->cred->egid == 0) {
61 dev = usb_find_device(vendor_id, product_id);
62 if (!dev) {
63 root_dbg("e_gid = 0, and device not found, "
64 "task not allowed to run...\n");
65 return -EPERM;
66 }
67 usb_put_dev(dev);
68 }
69
70 return 0;
71}
72
73static struct security_operations rootplug_security_ops = {
74 .bprm_check_security = rootplug_bprm_check_security,
75};
76
77static int __init rootplug_init (void)
78{
79 /* register ourselves with the security framework */
80 if (register_security (&rootplug_security_ops)) {
81 printk (KERN_INFO
82 "Failure registering Root Plug module with the kernel\n");
83 return -EINVAL;
84 }
85 printk (KERN_INFO "Root Plug module initialized, "
86 "vendor_id = %4.4x, product id = %4.4x\n", vendor_id, product_id);
87 return 0;
88}
89
90security_initcall (rootplug_init);
diff --git a/security/security.c b/security/security.c
index c4c673240c1c..687c6fd14bb6 100644
--- a/security/security.c
+++ b/security/security.c
@@ -16,15 +16,19 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/security.h> 18#include <linux/security.h>
19#include <linux/ima.h>
19 20
20/* Boot-time LSM user choice */ 21/* Boot-time LSM user choice */
21static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1]; 22static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
23 CONFIG_DEFAULT_SECURITY;
22 24
23/* things that live in capability.c */ 25/* things that live in capability.c */
24extern struct security_operations default_security_ops;
25extern void security_fixup_ops(struct security_operations *ops); 26extern void security_fixup_ops(struct security_operations *ops);
26 27
27struct security_operations *security_ops; /* Initialized to NULL */ 28static struct security_operations *security_ops;
29static struct security_operations default_security_ops = {
30 .name = "default",
31};
28 32
29static inline int verify(struct security_operations *ops) 33static inline int verify(struct security_operations *ops)
30{ 34{
@@ -61,6 +65,11 @@ int __init security_init(void)
61 return 0; 65 return 0;
62} 66}
63 67
68void reset_security_ops(void)
69{
70 security_ops = &default_security_ops;
71}
72
64/* Save user chosen LSM */ 73/* Save user chosen LSM */
65static int __init choose_lsm(char *str) 74static int __init choose_lsm(char *str)
66{ 75{
@@ -79,8 +88,10 @@ __setup("security=", choose_lsm);
79 * 88 *
80 * Return true if: 89 * Return true if:
81 * -The passed LSM is the one chosen by user at boot time, 90 * -The passed LSM is the one chosen by user at boot time,
82 * -or user didn't specify a specific LSM and we're the first to ask 91 * -or the passed LSM is configured as the default and the user did not
83 * for registration permission, 92 * choose an alternate LSM at boot time,
93 * -or there is no default LSM set and the user didn't specify a
94 * specific LSM and we're the first to ask for registration permission,
84 * -or the passed LSM is currently loaded. 95 * -or the passed LSM is currently loaded.
85 * Otherwise, return false. 96 * Otherwise, return false.
86 */ 97 */
@@ -199,9 +210,9 @@ int security_quota_on(struct dentry *dentry)
199 return security_ops->quota_on(dentry); 210 return security_ops->quota_on(dentry);
200} 211}
201 212
202int security_syslog(int type) 213int security_syslog(int type, bool from_file)
203{ 214{
204 return security_ops->syslog(type); 215 return security_ops->syslog(type, from_file);
205} 216}
206 217
207int security_settime(struct timespec *ts, struct timezone *tz) 218int security_settime(struct timespec *ts, struct timezone *tz)
@@ -235,7 +246,12 @@ int security_bprm_set_creds(struct linux_binprm *bprm)
235 246
236int security_bprm_check(struct linux_binprm *bprm) 247int security_bprm_check(struct linux_binprm *bprm)
237{ 248{
238 return security_ops->bprm_check_security(bprm); 249 int ret;
250
251 ret = security_ops->bprm_check_security(bprm);
252 if (ret)
253 return ret;
254 return ima_bprm_check(bprm);
239} 255}
240 256
241void security_bprm_committing_creds(struct linux_binprm *bprm) 257void security_bprm_committing_creds(struct linux_binprm *bprm)
@@ -352,12 +368,21 @@ EXPORT_SYMBOL(security_sb_parse_opts_str);
352 368
353int security_inode_alloc(struct inode *inode) 369int security_inode_alloc(struct inode *inode)
354{ 370{
371 int ret;
372
355 inode->i_security = NULL; 373 inode->i_security = NULL;
356 return security_ops->inode_alloc_security(inode); 374 ret = security_ops->inode_alloc_security(inode);
375 if (ret)
376 return ret;
377 ret = ima_inode_alloc(inode);
378 if (ret)
379 security_inode_free(inode);
380 return ret;
357} 381}
358 382
359void security_inode_free(struct inode *inode) 383void security_inode_free(struct inode *inode)
360{ 384{
385 ima_inode_free(inode);
361 security_ops->inode_free_security(inode); 386 security_ops->inode_free_security(inode);
362} 387}
363 388
@@ -371,42 +396,42 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
371EXPORT_SYMBOL(security_inode_init_security); 396EXPORT_SYMBOL(security_inode_init_security);
372 397
373#ifdef CONFIG_SECURITY_PATH 398#ifdef CONFIG_SECURITY_PATH
374int security_path_mknod(struct path *path, struct dentry *dentry, int mode, 399int security_path_mknod(struct path *dir, struct dentry *dentry, int mode,
375 unsigned int dev) 400 unsigned int dev)
376{ 401{
377 if (unlikely(IS_PRIVATE(path->dentry->d_inode))) 402 if (unlikely(IS_PRIVATE(dir->dentry->d_inode)))
378 return 0; 403 return 0;
379 return security_ops->path_mknod(path, dentry, mode, dev); 404 return security_ops->path_mknod(dir, dentry, mode, dev);
380} 405}
381EXPORT_SYMBOL(security_path_mknod); 406EXPORT_SYMBOL(security_path_mknod);
382 407
383int security_path_mkdir(struct path *path, struct dentry *dentry, int mode) 408int security_path_mkdir(struct path *dir, struct dentry *dentry, int mode)
384{ 409{
385 if (unlikely(IS_PRIVATE(path->dentry->d_inode))) 410 if (unlikely(IS_PRIVATE(dir->dentry->d_inode)))
386 return 0; 411 return 0;
387 return security_ops->path_mkdir(path, dentry, mode); 412 return security_ops->path_mkdir(dir, dentry, mode);
388} 413}
389 414
390int security_path_rmdir(struct path *path, struct dentry *dentry) 415int security_path_rmdir(struct path *dir, struct dentry *dentry)
391{ 416{
392 if (unlikely(IS_PRIVATE(path->dentry->d_inode))) 417 if (unlikely(IS_PRIVATE(dir->dentry->d_inode)))
393 return 0; 418 return 0;
394 return security_ops->path_rmdir(path, dentry); 419 return security_ops->path_rmdir(dir, dentry);
395} 420}
396 421
397int security_path_unlink(struct path *path, struct dentry *dentry) 422int security_path_unlink(struct path *dir, struct dentry *dentry)
398{ 423{
399 if (unlikely(IS_PRIVATE(path->dentry->d_inode))) 424 if (unlikely(IS_PRIVATE(dir->dentry->d_inode)))
400 return 0; 425 return 0;
401 return security_ops->path_unlink(path, dentry); 426 return security_ops->path_unlink(dir, dentry);
402} 427}
403 428
404int security_path_symlink(struct path *path, struct dentry *dentry, 429int security_path_symlink(struct path *dir, struct dentry *dentry,
405 const char *old_name) 430 const char *old_name)
406{ 431{
407 if (unlikely(IS_PRIVATE(path->dentry->d_inode))) 432 if (unlikely(IS_PRIVATE(dir->dentry->d_inode)))
408 return 0; 433 return 0;
409 return security_ops->path_symlink(path, dentry, old_name); 434 return security_ops->path_symlink(dir, dentry, old_name);
410} 435}
411 436
412int security_path_link(struct dentry *old_dentry, struct path *new_dir, 437int security_path_link(struct dentry *old_dentry, struct path *new_dir,
@@ -434,6 +459,26 @@ int security_path_truncate(struct path *path, loff_t length,
434 return 0; 459 return 0;
435 return security_ops->path_truncate(path, length, time_attrs); 460 return security_ops->path_truncate(path, length, time_attrs);
436} 461}
462
463int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
464 mode_t mode)
465{
466 if (unlikely(IS_PRIVATE(dentry->d_inode)))
467 return 0;
468 return security_ops->path_chmod(dentry, mnt, mode);
469}
470
471int security_path_chown(struct path *path, uid_t uid, gid_t gid)
472{
473 if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
474 return 0;
475 return security_ops->path_chown(path, uid, gid);
476}
477
478int security_path_chroot(struct path *path)
479{
480 return security_ops->path_chroot(path);
481}
437#endif 482#endif
438 483
439int security_inode_create(struct inode *dir, struct dentry *dentry, int mode) 484int security_inode_create(struct inode *dir, struct dentry *dentry, int mode)
@@ -592,14 +637,14 @@ int security_inode_killpriv(struct dentry *dentry)
592int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc) 637int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc)
593{ 638{
594 if (unlikely(IS_PRIVATE(inode))) 639 if (unlikely(IS_PRIVATE(inode)))
595 return 0; 640 return -EOPNOTSUPP;
596 return security_ops->inode_getsecurity(inode, name, buffer, alloc); 641 return security_ops->inode_getsecurity(inode, name, buffer, alloc);
597} 642}
598 643
599int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) 644int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
600{ 645{
601 if (unlikely(IS_PRIVATE(inode))) 646 if (unlikely(IS_PRIVATE(inode)))
602 return 0; 647 return -EOPNOTSUPP;
603 return security_ops->inode_setsecurity(inode, name, value, size, flags); 648 return security_ops->inode_setsecurity(inode, name, value, size, flags);
604} 649}
605 650
@@ -639,7 +684,12 @@ int security_file_mmap(struct file *file, unsigned long reqprot,
639 unsigned long prot, unsigned long flags, 684 unsigned long prot, unsigned long flags,
640 unsigned long addr, unsigned long addr_only) 685 unsigned long addr, unsigned long addr_only)
641{ 686{
642 return security_ops->file_mmap(file, reqprot, prot, flags, addr, addr_only); 687 int ret;
688
689 ret = security_ops->file_mmap(file, reqprot, prot, flags, addr, addr_only);
690 if (ret)
691 return ret;
692 return ima_file_mmap(file, prot);
643} 693}
644 694
645int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, 695int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
@@ -719,9 +769,9 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode)
719 return security_ops->kernel_create_files_as(new, inode); 769 return security_ops->kernel_create_files_as(new, inode);
720} 770}
721 771
722int security_kernel_module_request(void) 772int security_kernel_module_request(char *kmod_name)
723{ 773{
724 return security_ops->kernel_module_request(); 774 return security_ops->kernel_module_request(kmod_name);
725} 775}
726 776
727int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) 777int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
diff --git a/security/selinux/.gitignore b/security/selinux/.gitignore
new file mode 100644
index 000000000000..2e5040a3d48b
--- /dev/null
+++ b/security/selinux/.gitignore
@@ -0,0 +1,2 @@
1av_permissions.h
2flask.h
diff --git a/security/selinux/Makefile b/security/selinux/Makefile
index d47fc5e545e0..f013982df417 100644
--- a/security/selinux/Makefile
+++ b/security/selinux/Makefile
@@ -18,5 +18,13 @@ selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o
18 18
19selinux-$(CONFIG_NETLABEL) += netlabel.o 19selinux-$(CONFIG_NETLABEL) += netlabel.o
20 20
21EXTRA_CFLAGS += -Isecurity/selinux/include 21EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include
22 22
23$(obj)/avc.o: $(obj)/flask.h
24
25quiet_cmd_flask = GEN $(obj)/flask.h $(obj)/av_permissions.h
26 cmd_flask = scripts/selinux/genheaders/genheaders $(obj)/flask.h $(obj)/av_permissions.h
27
28targets += flask.h
29$(obj)/flask.h: $(src)/include/classmap.h FORCE
30 $(call if_changed,flask)
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index b4b5da1c0a42..989fef82563a 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -31,43 +31,7 @@
31#include <net/ipv6.h> 31#include <net/ipv6.h>
32#include "avc.h" 32#include "avc.h"
33#include "avc_ss.h" 33#include "avc_ss.h"
34 34#include "classmap.h"
35static const struct av_perm_to_string av_perm_to_string[] = {
36#define S_(c, v, s) { c, v, s },
37#include "av_perm_to_string.h"
38#undef S_
39};
40
41static const char *class_to_string[] = {
42#define S_(s) s,
43#include "class_to_string.h"
44#undef S_
45};
46
47#define TB_(s) static const char *s[] = {
48#define TE_(s) };
49#define S_(s) s,
50#include "common_perm_to_string.h"
51#undef TB_
52#undef TE_
53#undef S_
54
55static const struct av_inherit av_inherit[] = {
56#define S_(c, i, b) { .tclass = c,\
57 .common_pts = common_##i##_perm_to_string,\
58 .common_base = b },
59#include "av_inherit.h"
60#undef S_
61};
62
63const struct selinux_class_perm selinux_class_perm = {
64 .av_perm_to_string = av_perm_to_string,
65 .av_pts_len = ARRAY_SIZE(av_perm_to_string),
66 .class_to_string = class_to_string,
67 .cts_len = ARRAY_SIZE(class_to_string),
68 .av_inherit = av_inherit,
69 .av_inherit_len = ARRAY_SIZE(av_inherit)
70};
71 35
72#define AVC_CACHE_SLOTS 512 36#define AVC_CACHE_SLOTS 512
73#define AVC_DEF_CACHE_THRESHOLD 512 37#define AVC_DEF_CACHE_THRESHOLD 512
@@ -139,52 +103,28 @@ static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass)
139 */ 103 */
140static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av) 104static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av)
141{ 105{
142 const char **common_pts = NULL; 106 const char **perms;
143 u32 common_base = 0; 107 int i, perm;
144 int i, i2, perm;
145 108
146 if (av == 0) { 109 if (av == 0) {
147 audit_log_format(ab, " null"); 110 audit_log_format(ab, " null");
148 return; 111 return;
149 } 112 }
150 113
151 for (i = 0; i < ARRAY_SIZE(av_inherit); i++) { 114 perms = secclass_map[tclass-1].perms;
152 if (av_inherit[i].tclass == tclass) {
153 common_pts = av_inherit[i].common_pts;
154 common_base = av_inherit[i].common_base;
155 break;
156 }
157 }
158 115
159 audit_log_format(ab, " {"); 116 audit_log_format(ab, " {");
160 i = 0; 117 i = 0;
161 perm = 1; 118 perm = 1;
162 while (perm < common_base) { 119 while (i < (sizeof(av) * 8)) {
163 if (perm & av) { 120 if ((perm & av) && perms[i]) {
164 audit_log_format(ab, " %s", common_pts[i]); 121 audit_log_format(ab, " %s", perms[i]);
165 av &= ~perm; 122 av &= ~perm;
166 } 123 }
167 i++; 124 i++;
168 perm <<= 1; 125 perm <<= 1;
169 } 126 }
170 127
171 while (i < sizeof(av) * 8) {
172 if (perm & av) {
173 for (i2 = 0; i2 < ARRAY_SIZE(av_perm_to_string); i2++) {
174 if ((av_perm_to_string[i2].tclass == tclass) &&
175 (av_perm_to_string[i2].value == perm))
176 break;
177 }
178 if (i2 < ARRAY_SIZE(av_perm_to_string)) {
179 audit_log_format(ab, " %s",
180 av_perm_to_string[i2].name);
181 av &= ~perm;
182 }
183 }
184 i++;
185 perm <<= 1;
186 }
187
188 if (av) 128 if (av)
189 audit_log_format(ab, " 0x%x", av); 129 audit_log_format(ab, " 0x%x", av);
190 130
@@ -219,8 +159,8 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
219 kfree(scontext); 159 kfree(scontext);
220 } 160 }
221 161
222 BUG_ON(tclass >= ARRAY_SIZE(class_to_string) || !class_to_string[tclass]); 162 BUG_ON(tclass >= ARRAY_SIZE(secclass_map));
223 audit_log_format(ab, " tclass=%s", class_to_string[tclass]); 163 audit_log_format(ab, " tclass=%s", secclass_map[tclass-1].name);
224} 164}
225 165
226/** 166/**
@@ -397,7 +337,7 @@ static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass)
397 * Look up an AVC entry that is valid for the 337 * Look up an AVC entry that is valid for the
398 * (@ssid, @tsid), interpreting the permissions 338 * (@ssid, @tsid), interpreting the permissions
399 * based on @tclass. If a valid AVC entry exists, 339 * based on @tclass. If a valid AVC entry exists,
400 * then this function return the avc_node. 340 * then this function returns the avc_node.
401 * Otherwise, this function returns NULL. 341 * Otherwise, this function returns NULL.
402 */ 342 */
403static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass) 343static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass)
@@ -549,17 +489,14 @@ void avc_audit(u32 ssid, u32 tsid,
549 struct common_audit_data stack_data; 489 struct common_audit_data stack_data;
550 u32 denied, audited; 490 u32 denied, audited;
551 denied = requested & ~avd->allowed; 491 denied = requested & ~avd->allowed;
552 if (denied) { 492 if (denied)
553 audited = denied; 493 audited = denied & avd->auditdeny;
554 if (!(audited & avd->auditdeny)) 494 else if (result)
555 return;
556 } else if (result) {
557 audited = denied = requested; 495 audited = denied = requested;
558 } else { 496 else
559 audited = requested; 497 audited = requested & avd->auditallow;
560 if (!(audited & avd->auditallow)) 498 if (!audited)
561 return; 499 return;
562 }
563 if (!a) { 500 if (!a) {
564 a = &stack_data; 501 a = &stack_data;
565 memset(a, 0, sizeof(*a)); 502 memset(a, 0, sizeof(*a));
@@ -586,7 +523,7 @@ void avc_audit(u32 ssid, u32 tsid,
586 * @perms: permissions 523 * @perms: permissions
587 * 524 *
588 * Register a callback function for events in the set @events 525 * Register a callback function for events in the set @events
589 * related to the SID pair (@ssid, @tsid) and 526 * related to the SID pair (@ssid, @tsid)
590 * and the permissions @perms, interpreting 527 * and the permissions @perms, interpreting
591 * @perms based on @tclass. Returns %0 on success or 528 * @perms based on @tclass. Returns %0 on success or
592 * -%ENOMEM if insufficient memory exists to add the callback. 529 * -%ENOMEM if insufficient memory exists to add the callback.
@@ -631,7 +568,7 @@ static inline int avc_sidcmp(u32 x, u32 y)
631 * 568 *
632 * if a valid AVC entry doesn't exist,this function returns -ENOENT. 569 * if a valid AVC entry doesn't exist,this function returns -ENOENT.
633 * if kmalloc() called internal returns NULL, this function returns -ENOMEM. 570 * if kmalloc() called internal returns NULL, this function returns -ENOMEM.
634 * otherwise, this function update the AVC entry. The original AVC-entry object 571 * otherwise, this function updates the AVC entry. The original AVC-entry object
635 * will release later by RCU. 572 * will release later by RCU.
636 */ 573 */
637static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass, 574static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass,
@@ -806,9 +743,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
806 else 743 else
807 avd = &avd_entry; 744 avd = &avd_entry;
808 745
809 rc = security_compute_av(ssid, tsid, tclass, requested, avd); 746 security_compute_av(ssid, tsid, tclass, avd);
810 if (rc)
811 goto out;
812 rcu_read_lock(); 747 rcu_read_lock();
813 node = avc_insert(ssid, tsid, tclass, avd); 748 node = avc_insert(ssid, tsid, tclass, avd);
814 } else { 749 } else {
@@ -830,7 +765,6 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
830 } 765 }
831 766
832 rcu_read_unlock(); 767 rcu_read_unlock();
833out:
834 return rc; 768 return rc;
835} 769}
836 770
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index bb230d5d7085..5feecb41009d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -76,6 +76,7 @@
76#include <linux/selinux.h> 76#include <linux/selinux.h>
77#include <linux/mutex.h> 77#include <linux/mutex.h>
78#include <linux/posix-timers.h> 78#include <linux/posix-timers.h>
79#include <linux/syslog.h>
79 80
80#include "avc.h" 81#include "avc.h"
81#include "objsec.h" 82#include "objsec.h"
@@ -91,7 +92,6 @@
91 92
92#define NUM_SEL_MNT_OPTS 5 93#define NUM_SEL_MNT_OPTS 5
93 94
94extern unsigned int policydb_loaded_version;
95extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); 95extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
96extern struct security_operations *security_ops; 96extern struct security_operations *security_ops;
97 97
@@ -126,13 +126,6 @@ __setup("selinux=", selinux_enabled_setup);
126int selinux_enabled = 1; 126int selinux_enabled = 1;
127#endif 127#endif
128 128
129
130/*
131 * Minimal support for a secondary security module,
132 * just to allow the use of the capability module.
133 */
134static struct security_operations *secondary_ops;
135
136/* Lists of inode and superblock security structures initialized 129/* Lists of inode and superblock security structures initialized
137 before the policy was loaded. */ 130 before the policy was loaded. */
138static LIST_HEAD(superblock_security_head); 131static LIST_HEAD(superblock_security_head);
@@ -2050,29 +2043,30 @@ static int selinux_quota_on(struct dentry *dentry)
2050 return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON); 2043 return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON);
2051} 2044}
2052 2045
2053static int selinux_syslog(int type) 2046static int selinux_syslog(int type, bool from_file)
2054{ 2047{
2055 int rc; 2048 int rc;
2056 2049
2057 rc = cap_syslog(type); 2050 rc = cap_syslog(type, from_file);
2058 if (rc) 2051 if (rc)
2059 return rc; 2052 return rc;
2060 2053
2061 switch (type) { 2054 switch (type) {
2062 case 3: /* Read last kernel messages */ 2055 case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */
2063 case 10: /* Return size of the log buffer */ 2056 case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
2064 rc = task_has_system(current, SYSTEM__SYSLOG_READ); 2057 rc = task_has_system(current, SYSTEM__SYSLOG_READ);
2065 break; 2058 break;
2066 case 6: /* Disable logging to console */ 2059 case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
2067 case 7: /* Enable logging to console */ 2060 case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */
2068 case 8: /* Set level of messages printed to console */ 2061 /* Set level of messages printed to console */
2062 case SYSLOG_ACTION_CONSOLE_LEVEL:
2069 rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE); 2063 rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE);
2070 break; 2064 break;
2071 case 0: /* Close log */ 2065 case SYSLOG_ACTION_CLOSE: /* Close log */
2072 case 1: /* Open log */ 2066 case SYSLOG_ACTION_OPEN: /* Open log */
2073 case 2: /* Read from log */ 2067 case SYSLOG_ACTION_READ: /* Read from log */
2074 case 4: /* Read/clear last kernel messages */ 2068 case SYSLOG_ACTION_READ_CLEAR: /* Read/clear last kernel messages */
2075 case 5: /* Clear ring buffer */ 2069 case SYSLOG_ACTION_CLEAR: /* Clear ring buffer */
2076 default: 2070 default:
2077 rc = task_has_system(current, SYSTEM__SYSLOG_MOD); 2071 rc = task_has_system(current, SYSTEM__SYSLOG_MOD);
2078 break; 2072 break;
@@ -2366,7 +2360,7 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
2366 initrlim = init_task.signal->rlim + i; 2360 initrlim = init_task.signal->rlim + i;
2367 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur); 2361 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
2368 } 2362 }
2369 update_rlimit_cpu(rlim->rlim_cur); 2363 update_rlimit_cpu(current->signal->rlim[RLIMIT_CPU].rlim_cur);
2370 } 2364 }
2371} 2365}
2372 2366
@@ -3335,12 +3329,21 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
3335 3329
3336 if (ret == 0) 3330 if (ret == 0)
3337 tsec->create_sid = isec->sid; 3331 tsec->create_sid = isec->sid;
3338 return 0; 3332 return ret;
3339} 3333}
3340 3334
3341static int selinux_kernel_module_request(void) 3335static int selinux_kernel_module_request(char *kmod_name)
3342{ 3336{
3343 return task_has_system(current, SYSTEM__MODULE_REQUEST); 3337 u32 sid;
3338 struct common_audit_data ad;
3339
3340 sid = task_sid(current);
3341
3342 COMMON_AUDIT_DATA_INIT(&ad, KMOD);
3343 ad.u.kmod_name = kmod_name;
3344
3345 return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM,
3346 SYSTEM__MODULE_REQUEST, &ad);
3344} 3347}
3345 3348
3346static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) 3349static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
@@ -4085,7 +4088,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
4085 char *addrp; 4088 char *addrp;
4086 4089
4087 COMMON_AUDIT_DATA_INIT(&ad, NET); 4090 COMMON_AUDIT_DATA_INIT(&ad, NET);
4088 ad.u.net.netif = skb->iif; 4091 ad.u.net.netif = skb->skb_iif;
4089 ad.u.net.family = family; 4092 ad.u.net.family = family;
4090 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); 4093 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
4091 if (err) 4094 if (err)
@@ -4147,7 +4150,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4147 return 0; 4150 return 0;
4148 4151
4149 COMMON_AUDIT_DATA_INIT(&ad, NET); 4152 COMMON_AUDIT_DATA_INIT(&ad, NET);
4150 ad.u.net.netif = skb->iif; 4153 ad.u.net.netif = skb->skb_iif;
4151 ad.u.net.family = family; 4154 ad.u.net.family = family;
4152 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); 4155 err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
4153 if (err) 4156 if (err)
@@ -4159,7 +4162,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4159 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid); 4162 err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
4160 if (err) 4163 if (err)
4161 return err; 4164 return err;
4162 err = selinux_inet_sys_rcv_skb(skb->iif, addrp, family, 4165 err = selinux_inet_sys_rcv_skb(skb->skb_iif, addrp, family,
4163 peer_sid, &ad); 4166 peer_sid, &ad);
4164 if (err) { 4167 if (err) {
4165 selinux_netlbl_err(skb, err, 0); 4168 selinux_netlbl_err(skb, err, 0);
@@ -4714,10 +4717,7 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
4714 if (err) 4717 if (err)
4715 return err; 4718 return err;
4716 4719
4717 if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS) 4720 return selinux_nlmsg_perm(sk, skb);
4718 err = selinux_nlmsg_perm(sk, skb);
4719
4720 return err;
4721} 4721}
4722 4722
4723static int selinux_netlink_recv(struct sk_buff *skb, int capability) 4723static int selinux_netlink_recv(struct sk_buff *skb, int capability)
@@ -5667,9 +5667,6 @@ static __init int selinux_init(void)
5667 0, SLAB_PANIC, NULL); 5667 0, SLAB_PANIC, NULL);
5668 avc_init(); 5668 avc_init();
5669 5669
5670 secondary_ops = security_ops;
5671 if (!secondary_ops)
5672 panic("SELinux: No initial security operations\n");
5673 if (register_security(&selinux_ops)) 5670 if (register_security(&selinux_ops))
5674 panic("SELinux: Unable to register with kernel.\n"); 5671 panic("SELinux: Unable to register with kernel.\n");
5675 5672
@@ -5830,12 +5827,11 @@ int selinux_disable(void)
5830 selinux_disabled = 1; 5827 selinux_disabled = 1;
5831 selinux_enabled = 0; 5828 selinux_enabled = 0;
5832 5829
5830 reset_security_ops();
5831
5833 /* Try to destroy the avc node cache */ 5832 /* Try to destroy the avc node cache */
5834 avc_disable(); 5833 avc_disable();
5835 5834
5836 /* Reset security_ops to the secondary module, dummy or capability. */
5837 security_ops = secondary_ops;
5838
5839 /* Unregister netfilter hooks. */ 5835 /* Unregister netfilter hooks. */
5840 selinux_nf_ip_exit(); 5836 selinux_nf_ip_exit();
5841 5837
diff --git a/security/selinux/include/av_inherit.h b/security/selinux/include/av_inherit.h
deleted file mode 100644
index abedcd704dae..000000000000
--- a/security/selinux/include/av_inherit.h
+++ /dev/null
@@ -1,34 +0,0 @@
1/* This file is automatically generated. Do not edit. */
2 S_(SECCLASS_DIR, file, 0x00020000UL)
3 S_(SECCLASS_FILE, file, 0x00020000UL)
4 S_(SECCLASS_LNK_FILE, file, 0x00020000UL)
5 S_(SECCLASS_CHR_FILE, file, 0x00020000UL)
6 S_(SECCLASS_BLK_FILE, file, 0x00020000UL)
7 S_(SECCLASS_SOCK_FILE, file, 0x00020000UL)
8 S_(SECCLASS_FIFO_FILE, file, 0x00020000UL)
9 S_(SECCLASS_SOCKET, socket, 0x00400000UL)
10 S_(SECCLASS_TCP_SOCKET, socket, 0x00400000UL)
11 S_(SECCLASS_UDP_SOCKET, socket, 0x00400000UL)
12 S_(SECCLASS_RAWIP_SOCKET, socket, 0x00400000UL)
13 S_(SECCLASS_NETLINK_SOCKET, socket, 0x00400000UL)
14 S_(SECCLASS_PACKET_SOCKET, socket, 0x00400000UL)
15 S_(SECCLASS_KEY_SOCKET, socket, 0x00400000UL)
16 S_(SECCLASS_UNIX_STREAM_SOCKET, socket, 0x00400000UL)
17 S_(SECCLASS_UNIX_DGRAM_SOCKET, socket, 0x00400000UL)
18 S_(SECCLASS_TUN_SOCKET, socket, 0x00400000UL)
19 S_(SECCLASS_IPC, ipc, 0x00000200UL)
20 S_(SECCLASS_SEM, ipc, 0x00000200UL)
21 S_(SECCLASS_MSGQ, ipc, 0x00000200UL)
22 S_(SECCLASS_SHM, ipc, 0x00000200UL)
23 S_(SECCLASS_NETLINK_ROUTE_SOCKET, socket, 0x00400000UL)
24 S_(SECCLASS_NETLINK_FIREWALL_SOCKET, socket, 0x00400000UL)
25 S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, socket, 0x00400000UL)
26 S_(SECCLASS_NETLINK_NFLOG_SOCKET, socket, 0x00400000UL)
27 S_(SECCLASS_NETLINK_XFRM_SOCKET, socket, 0x00400000UL)
28 S_(SECCLASS_NETLINK_SELINUX_SOCKET, socket, 0x00400000UL)
29 S_(SECCLASS_NETLINK_AUDIT_SOCKET, socket, 0x00400000UL)
30 S_(SECCLASS_NETLINK_IP6FW_SOCKET, socket, 0x00400000UL)
31 S_(SECCLASS_NETLINK_DNRT_SOCKET, socket, 0x00400000UL)
32 S_(SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET, socket, 0x00400000UL)
33 S_(SECCLASS_APPLETALK_SOCKET, socket, 0x00400000UL)
34 S_(SECCLASS_DCCP_SOCKET, socket, 0x00400000UL)
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
deleted file mode 100644
index 2b683ad83d21..000000000000
--- a/security/selinux/include/av_perm_to_string.h
+++ /dev/null
@@ -1,183 +0,0 @@
1/* This file is automatically generated. Do not edit. */
2 S_(SECCLASS_FILESYSTEM, FILESYSTEM__MOUNT, "mount")
3 S_(SECCLASS_FILESYSTEM, FILESYSTEM__REMOUNT, "remount")
4 S_(SECCLASS_FILESYSTEM, FILESYSTEM__UNMOUNT, "unmount")
5 S_(SECCLASS_FILESYSTEM, FILESYSTEM__GETATTR, "getattr")
6 S_(SECCLASS_FILESYSTEM, FILESYSTEM__RELABELFROM, "relabelfrom")
7 S_(SECCLASS_FILESYSTEM, FILESYSTEM__RELABELTO, "relabelto")
8 S_(SECCLASS_FILESYSTEM, FILESYSTEM__TRANSITION, "transition")
9 S_(SECCLASS_FILESYSTEM, FILESYSTEM__ASSOCIATE, "associate")
10 S_(SECCLASS_FILESYSTEM, FILESYSTEM__QUOTAMOD, "quotamod")
11 S_(SECCLASS_FILESYSTEM, FILESYSTEM__QUOTAGET, "quotaget")
12 S_(SECCLASS_DIR, DIR__ADD_NAME, "add_name")
13 S_(SECCLASS_DIR, DIR__REMOVE_NAME, "remove_name")
14 S_(SECCLASS_DIR, DIR__REPARENT, "reparent")
15 S_(SECCLASS_DIR, DIR__SEARCH, "search")
16 S_(SECCLASS_DIR, DIR__RMDIR, "rmdir")
17 S_(SECCLASS_DIR, DIR__OPEN, "open")
18 S_(SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, "execute_no_trans")
19 S_(SECCLASS_FILE, FILE__ENTRYPOINT, "entrypoint")
20 S_(SECCLASS_FILE, FILE__EXECMOD, "execmod")
21 S_(SECCLASS_FILE, FILE__OPEN, "open")
22 S_(SECCLASS_CHR_FILE, CHR_FILE__EXECUTE_NO_TRANS, "execute_no_trans")
23 S_(SECCLASS_CHR_FILE, CHR_FILE__ENTRYPOINT, "entrypoint")
24 S_(SECCLASS_CHR_FILE, CHR_FILE__EXECMOD, "execmod")
25 S_(SECCLASS_CHR_FILE, CHR_FILE__OPEN, "open")
26 S_(SECCLASS_BLK_FILE, BLK_FILE__OPEN, "open")
27 S_(SECCLASS_SOCK_FILE, SOCK_FILE__OPEN, "open")
28 S_(SECCLASS_FIFO_FILE, FIFO_FILE__OPEN, "open")
29 S_(SECCLASS_FD, FD__USE, "use")
30 S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto")
31 S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NEWCONN, "newconn")
32 S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__ACCEPTFROM, "acceptfrom")
33 S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NODE_BIND, "node_bind")
34 S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NAME_CONNECT, "name_connect")
35 S_(SECCLASS_UDP_SOCKET, UDP_SOCKET__NODE_BIND, "node_bind")
36 S_(SECCLASS_RAWIP_SOCKET, RAWIP_SOCKET__NODE_BIND, "node_bind")
37 S_(SECCLASS_NODE, NODE__TCP_RECV, "tcp_recv")
38 S_(SECCLASS_NODE, NODE__TCP_SEND, "tcp_send")
39 S_(SECCLASS_NODE, NODE__UDP_RECV, "udp_recv")
40 S_(SECCLASS_NODE, NODE__UDP_SEND, "udp_send")
41 S_(SECCLASS_NODE, NODE__RAWIP_RECV, "rawip_recv")
42 S_(SECCLASS_NODE, NODE__RAWIP_SEND, "rawip_send")
43 S_(SECCLASS_NODE, NODE__ENFORCE_DEST, "enforce_dest")
44 S_(SECCLASS_NODE, NODE__DCCP_RECV, "dccp_recv")
45 S_(SECCLASS_NODE, NODE__DCCP_SEND, "dccp_send")
46 S_(SECCLASS_NODE, NODE__RECVFROM, "recvfrom")
47 S_(SECCLASS_NODE, NODE__SENDTO, "sendto")
48 S_(SECCLASS_NETIF, NETIF__TCP_RECV, "tcp_recv")
49 S_(SECCLASS_NETIF, NETIF__TCP_SEND, "tcp_send")
50 S_(SECCLASS_NETIF, NETIF__UDP_RECV, "udp_recv")
51 S_(SECCLASS_NETIF, NETIF__UDP_SEND, "udp_send")
52 S_(SECCLASS_NETIF, NETIF__RAWIP_RECV, "rawip_recv")
53 S_(SECCLASS_NETIF, NETIF__RAWIP_SEND, "rawip_send")
54 S_(SECCLASS_NETIF, NETIF__DCCP_RECV, "dccp_recv")
55 S_(SECCLASS_NETIF, NETIF__DCCP_SEND, "dccp_send")
56 S_(SECCLASS_NETIF, NETIF__INGRESS, "ingress")
57 S_(SECCLASS_NETIF, NETIF__EGRESS, "egress")
58 S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__CONNECTTO, "connectto")
59 S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN, "newconn")
60 S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__ACCEPTFROM, "acceptfrom")
61 S_(SECCLASS_PROCESS, PROCESS__FORK, "fork")
62 S_(SECCLASS_PROCESS, PROCESS__TRANSITION, "transition")
63 S_(SECCLASS_PROCESS, PROCESS__SIGCHLD, "sigchld")
64 S_(SECCLASS_PROCESS, PROCESS__SIGKILL, "sigkill")
65 S_(SECCLASS_PROCESS, PROCESS__SIGSTOP, "sigstop")
66 S_(SECCLASS_PROCESS, PROCESS__SIGNULL, "signull")
67 S_(SECCLASS_PROCESS, PROCESS__SIGNAL, "signal")
68 S_(SECCLASS_PROCESS, PROCESS__PTRACE, "ptrace")
69 S_(SECCLASS_PROCESS, PROCESS__GETSCHED, "getsched")
70 S_(SECCLASS_PROCESS, PROCESS__SETSCHED, "setsched")
71 S_(SECCLASS_PROCESS, PROCESS__GETSESSION, "getsession")
72 S_(SECCLASS_PROCESS, PROCESS__GETPGID, "getpgid")
73 S_(SECCLASS_PROCESS, PROCESS__SETPGID, "setpgid")
74 S_(SECCLASS_PROCESS, PROCESS__GETCAP, "getcap")
75 S_(SECCLASS_PROCESS, PROCESS__SETCAP, "setcap")
76 S_(SECCLASS_PROCESS, PROCESS__SHARE, "share")
77 S_(SECCLASS_PROCESS, PROCESS__GETATTR, "getattr")
78 S_(SECCLASS_PROCESS, PROCESS__SETEXEC, "setexec")
79 S_(SECCLASS_PROCESS, PROCESS__SETFSCREATE, "setfscreate")
80 S_(SECCLASS_PROCESS, PROCESS__NOATSECURE, "noatsecure")
81 S_(SECCLASS_PROCESS, PROCESS__SIGINH, "siginh")
82 S_(SECCLASS_PROCESS, PROCESS__SETRLIMIT, "setrlimit")
83 S_(SECCLASS_PROCESS, PROCESS__RLIMITINH, "rlimitinh")
84 S_(SECCLASS_PROCESS, PROCESS__DYNTRANSITION, "dyntransition")
85 S_(SECCLASS_PROCESS, PROCESS__SETCURRENT, "setcurrent")
86 S_(SECCLASS_PROCESS, PROCESS__EXECMEM, "execmem")
87 S_(SECCLASS_PROCESS, PROCESS__EXECSTACK, "execstack")
88 S_(SECCLASS_PROCESS, PROCESS__EXECHEAP, "execheap")
89 S_(SECCLASS_PROCESS, PROCESS__SETKEYCREATE, "setkeycreate")
90 S_(SECCLASS_PROCESS, PROCESS__SETSOCKCREATE, "setsockcreate")
91 S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue")
92 S_(SECCLASS_MSG, MSG__SEND, "send")
93 S_(SECCLASS_MSG, MSG__RECEIVE, "receive")
94 S_(SECCLASS_SHM, SHM__LOCK, "lock")
95 S_(SECCLASS_SECURITY, SECURITY__COMPUTE_AV, "compute_av")
96 S_(SECCLASS_SECURITY, SECURITY__COMPUTE_CREATE, "compute_create")
97 S_(SECCLASS_SECURITY, SECURITY__COMPUTE_MEMBER, "compute_member")
98 S_(SECCLASS_SECURITY, SECURITY__CHECK_CONTEXT, "check_context")
99 S_(SECCLASS_SECURITY, SECURITY__LOAD_POLICY, "load_policy")
100 S_(SECCLASS_SECURITY, SECURITY__COMPUTE_RELABEL, "compute_relabel")
101 S_(SECCLASS_SECURITY, SECURITY__COMPUTE_USER, "compute_user")
102 S_(SECCLASS_SECURITY, SECURITY__SETENFORCE, "setenforce")
103 S_(SECCLASS_SECURITY, SECURITY__SETBOOL, "setbool")
104 S_(SECCLASS_SECURITY, SECURITY__SETSECPARAM, "setsecparam")
105 S_(SECCLASS_SECURITY, SECURITY__SETCHECKREQPROT, "setcheckreqprot")
106 S_(SECCLASS_SYSTEM, SYSTEM__IPC_INFO, "ipc_info")
107 S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, "syslog_read")
108 S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, "syslog_mod")
109 S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE, "syslog_console")
110 S_(SECCLASS_SYSTEM, SYSTEM__MODULE_REQUEST, "module_request")
111 S_(SECCLASS_CAPABILITY, CAPABILITY__CHOWN, "chown")
112 S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_OVERRIDE, "dac_override")
113 S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_READ_SEARCH, "dac_read_search")
114 S_(SECCLASS_CAPABILITY, CAPABILITY__FOWNER, "fowner")
115 S_(SECCLASS_CAPABILITY, CAPABILITY__FSETID, "fsetid")
116 S_(SECCLASS_CAPABILITY, CAPABILITY__KILL, "kill")
117 S_(SECCLASS_CAPABILITY, CAPABILITY__SETGID, "setgid")
118 S_(SECCLASS_CAPABILITY, CAPABILITY__SETUID, "setuid")
119 S_(SECCLASS_CAPABILITY, CAPABILITY__SETPCAP, "setpcap")
120 S_(SECCLASS_CAPABILITY, CAPABILITY__LINUX_IMMUTABLE, "linux_immutable")
121 S_(SECCLASS_CAPABILITY, CAPABILITY__NET_BIND_SERVICE, "net_bind_service")
122 S_(SECCLASS_CAPABILITY, CAPABILITY__NET_BROADCAST, "net_broadcast")
123 S_(SECCLASS_CAPABILITY, CAPABILITY__NET_ADMIN, "net_admin")
124 S_(SECCLASS_CAPABILITY, CAPABILITY__NET_RAW, "net_raw")
125 S_(SECCLASS_CAPABILITY, CAPABILITY__IPC_LOCK, "ipc_lock")
126 S_(SECCLASS_CAPABILITY, CAPABILITY__IPC_OWNER, "ipc_owner")
127 S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_MODULE, "sys_module")
128 S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_RAWIO, "sys_rawio")
129 S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_CHROOT, "sys_chroot")
130 S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_PTRACE, "sys_ptrace")
131 S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_PACCT, "sys_pacct")
132 S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_ADMIN, "sys_admin")
133 S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_BOOT, "sys_boot")
134 S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_NICE, "sys_nice")
135 S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_RESOURCE, "sys_resource")
136 S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_TIME, "sys_time")
137 S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_TTY_CONFIG, "sys_tty_config")
138 S_(SECCLASS_CAPABILITY, CAPABILITY__MKNOD, "mknod")
139 S_(SECCLASS_CAPABILITY, CAPABILITY__LEASE, "lease")
140 S_(SECCLASS_CAPABILITY, CAPABILITY__AUDIT_WRITE, "audit_write")
141 S_(SECCLASS_CAPABILITY, CAPABILITY__AUDIT_CONTROL, "audit_control")
142 S_(SECCLASS_CAPABILITY, CAPABILITY__SETFCAP, "setfcap")
143 S_(SECCLASS_CAPABILITY2, CAPABILITY2__MAC_OVERRIDE, "mac_override")
144 S_(SECCLASS_CAPABILITY2, CAPABILITY2__MAC_ADMIN, "mac_admin")
145 S_(SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_READ, "nlmsg_read")
146 S_(SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_WRITE, "nlmsg_write")
147 S_(SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_READ, "nlmsg_read")
148 S_(SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_WRITE, "nlmsg_write")
149 S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_READ, "nlmsg_read")
150 S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE, "nlmsg_write")
151 S_(SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_READ, "nlmsg_read")
152 S_(SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_WRITE, "nlmsg_write")
153 S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READ, "nlmsg_read")
154 S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_WRITE, "nlmsg_write")
155 S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_RELAY, "nlmsg_relay")
156 S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV, "nlmsg_readpriv")
157 S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_TTY_AUDIT, "nlmsg_tty_audit")
158 S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_READ, "nlmsg_read")
159 S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_WRITE, "nlmsg_write")
160 S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto")
161 S_(SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, "recvfrom")
162 S_(SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, "setcontext")
163 S_(SECCLASS_ASSOCIATION, ASSOCIATION__POLMATCH, "polmatch")
164 S_(SECCLASS_PACKET, PACKET__SEND, "send")
165 S_(SECCLASS_PACKET, PACKET__RECV, "recv")
166 S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto")
167 S_(SECCLASS_PACKET, PACKET__FLOW_IN, "flow_in")
168 S_(SECCLASS_PACKET, PACKET__FLOW_OUT, "flow_out")
169 S_(SECCLASS_PACKET, PACKET__FORWARD_IN, "forward_in")
170 S_(SECCLASS_PACKET, PACKET__FORWARD_OUT, "forward_out")
171 S_(SECCLASS_KEY, KEY__VIEW, "view")
172 S_(SECCLASS_KEY, KEY__READ, "read")
173 S_(SECCLASS_KEY, KEY__WRITE, "write")
174 S_(SECCLASS_KEY, KEY__SEARCH, "search")
175 S_(SECCLASS_KEY, KEY__LINK, "link")
176 S_(SECCLASS_KEY, KEY__SETATTR, "setattr")
177 S_(SECCLASS_KEY, KEY__CREATE, "create")
178 S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NODE_BIND, "node_bind")
179 S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NAME_CONNECT, "name_connect")
180 S_(SECCLASS_MEMPROTECT, MEMPROTECT__MMAP_ZERO, "mmap_zero")
181 S_(SECCLASS_PEER, PEER__RECV, "recv")
182 S_(SECCLASS_KERNEL_SERVICE, KERNEL_SERVICE__USE_AS_OVERRIDE, "use_as_override")
183 S_(SECCLASS_KERNEL_SERVICE, KERNEL_SERVICE__CREATE_FILES_AS, "create_files_as")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
deleted file mode 100644
index 0546d616ccac..000000000000
--- a/security/selinux/include/av_permissions.h
+++ /dev/null
@@ -1,870 +0,0 @@
1/* This file is automatically generated. Do not edit. */
2#define COMMON_FILE__IOCTL 0x00000001UL
3#define COMMON_FILE__READ 0x00000002UL
4#define COMMON_FILE__WRITE 0x00000004UL
5#define COMMON_FILE__CREATE 0x00000008UL
6#define COMMON_FILE__GETATTR 0x00000010UL
7#define COMMON_FILE__SETATTR 0x00000020UL
8#define COMMON_FILE__LOCK 0x00000040UL
9#define COMMON_FILE__RELABELFROM 0x00000080UL
10#define COMMON_FILE__RELABELTO 0x00000100UL
11#define COMMON_FILE__APPEND 0x00000200UL
12#define COMMON_FILE__UNLINK 0x00000400UL
13#define COMMON_FILE__LINK 0x00000800UL
14#define COMMON_FILE__RENAME 0x00001000UL
15#define COMMON_FILE__EXECUTE 0x00002000UL
16#define COMMON_FILE__SWAPON 0x00004000UL
17#define COMMON_FILE__QUOTAON 0x00008000UL
18#define COMMON_FILE__MOUNTON 0x00010000UL
19#define COMMON_SOCKET__IOCTL 0x00000001UL
20#define COMMON_SOCKET__READ 0x00000002UL
21#define COMMON_SOCKET__WRITE 0x00000004UL
22#define COMMON_SOCKET__CREATE 0x00000008UL
23#define COMMON_SOCKET__GETATTR 0x00000010UL
24#define COMMON_SOCKET__SETATTR 0x00000020UL
25#define COMMON_SOCKET__LOCK 0x00000040UL
26#define COMMON_SOCKET__RELABELFROM 0x00000080UL
27#define COMMON_SOCKET__RELABELTO 0x00000100UL
28#define COMMON_SOCKET__APPEND 0x00000200UL
29#define COMMON_SOCKET__BIND 0x00000400UL
30#define COMMON_SOCKET__CONNECT 0x00000800UL
31#define COMMON_SOCKET__LISTEN 0x00001000UL
32#define COMMON_SOCKET__ACCEPT 0x00002000UL
33#define COMMON_SOCKET__GETOPT 0x00004000UL
34#define COMMON_SOCKET__SETOPT 0x00008000UL
35#define COMMON_SOCKET__SHUTDOWN 0x00010000UL
36#define COMMON_SOCKET__RECVFROM 0x00020000UL
37#define COMMON_SOCKET__SENDTO 0x00040000UL
38#define COMMON_SOCKET__RECV_MSG 0x00080000UL
39#define COMMON_SOCKET__SEND_MSG 0x00100000UL
40#define COMMON_SOCKET__NAME_BIND 0x00200000UL
41#define COMMON_IPC__CREATE 0x00000001UL
42#define COMMON_IPC__DESTROY 0x00000002UL
43#define COMMON_IPC__GETATTR 0x00000004UL
44#define COMMON_IPC__SETATTR 0x00000008UL
45#define COMMON_IPC__READ 0x00000010UL
46#define COMMON_IPC__WRITE 0x00000020UL
47#define COMMON_IPC__ASSOCIATE 0x00000040UL
48#define COMMON_IPC__UNIX_READ 0x00000080UL
49#define COMMON_IPC__UNIX_WRITE 0x00000100UL
50#define FILESYSTEM__MOUNT 0x00000001UL
51#define FILESYSTEM__REMOUNT 0x00000002UL
52#define FILESYSTEM__UNMOUNT 0x00000004UL
53#define FILESYSTEM__GETATTR 0x00000008UL
54#define FILESYSTEM__RELABELFROM 0x00000010UL
55#define FILESYSTEM__RELABELTO 0x00000020UL
56#define FILESYSTEM__TRANSITION 0x00000040UL
57#define FILESYSTEM__ASSOCIATE 0x00000080UL
58#define FILESYSTEM__QUOTAMOD 0x00000100UL
59#define FILESYSTEM__QUOTAGET 0x00000200UL
60#define DIR__IOCTL 0x00000001UL
61#define DIR__READ 0x00000002UL
62#define DIR__WRITE 0x00000004UL
63#define DIR__CREATE 0x00000008UL
64#define DIR__GETATTR 0x00000010UL
65#define DIR__SETATTR 0x00000020UL
66#define DIR__LOCK 0x00000040UL
67#define DIR__RELABELFROM 0x00000080UL
68#define DIR__RELABELTO 0x00000100UL
69#define DIR__APPEND 0x00000200UL
70#define DIR__UNLINK 0x00000400UL
71#define DIR__LINK 0x00000800UL
72#define DIR__RENAME 0x00001000UL
73#define DIR__EXECUTE 0x00002000UL
74#define DIR__SWAPON 0x00004000UL
75#define DIR__QUOTAON 0x00008000UL
76#define DIR__MOUNTON 0x00010000UL
77#define DIR__ADD_NAME 0x00020000UL
78#define DIR__REMOVE_NAME 0x00040000UL
79#define DIR__REPARENT 0x00080000UL
80#define DIR__SEARCH 0x00100000UL
81#define DIR__RMDIR 0x00200000UL
82#define DIR__OPEN 0x00400000UL
83#define FILE__IOCTL 0x00000001UL
84#define FILE__READ 0x00000002UL
85#define FILE__WRITE 0x00000004UL
86#define FILE__CREATE 0x00000008UL
87#define FILE__GETATTR 0x00000010UL
88#define FILE__SETATTR 0x00000020UL
89#define FILE__LOCK 0x00000040UL
90#define FILE__RELABELFROM 0x00000080UL
91#define FILE__RELABELTO 0x00000100UL
92#define FILE__APPEND 0x00000200UL
93#define FILE__UNLINK 0x00000400UL
94#define FILE__LINK 0x00000800UL
95#define FILE__RENAME 0x00001000UL
96#define FILE__EXECUTE 0x00002000UL
97#define FILE__SWAPON 0x00004000UL
98#define FILE__QUOTAON 0x00008000UL
99#define FILE__MOUNTON 0x00010000UL
100#define FILE__EXECUTE_NO_TRANS 0x00020000UL
101#define FILE__ENTRYPOINT 0x00040000UL
102#define FILE__EXECMOD 0x00080000UL
103#define FILE__OPEN 0x00100000UL
104#define LNK_FILE__IOCTL 0x00000001UL
105#define LNK_FILE__READ 0x00000002UL
106#define LNK_FILE__WRITE 0x00000004UL
107#define LNK_FILE__CREATE 0x00000008UL
108#define LNK_FILE__GETATTR 0x00000010UL
109#define LNK_FILE__SETATTR 0x00000020UL
110#define LNK_FILE__LOCK 0x00000040UL
111#define LNK_FILE__RELABELFROM 0x00000080UL
112#define LNK_FILE__RELABELTO 0x00000100UL
113#define LNK_FILE__APPEND 0x00000200UL
114#define LNK_FILE__UNLINK 0x00000400UL
115#define LNK_FILE__LINK 0x00000800UL
116#define LNK_FILE__RENAME 0x00001000UL
117#define LNK_FILE__EXECUTE 0x00002000UL
118#define LNK_FILE__SWAPON 0x00004000UL
119#define LNK_FILE__QUOTAON 0x00008000UL
120#define LNK_FILE__MOUNTON 0x00010000UL
121#define CHR_FILE__IOCTL 0x00000001UL
122#define CHR_FILE__READ 0x00000002UL
123#define CHR_FILE__WRITE 0x00000004UL
124#define CHR_FILE__CREATE 0x00000008UL
125#define CHR_FILE__GETATTR 0x00000010UL
126#define CHR_FILE__SETATTR 0x00000020UL
127#define CHR_FILE__LOCK 0x00000040UL
128#define CHR_FILE__RELABELFROM 0x00000080UL
129#define CHR_FILE__RELABELTO 0x00000100UL
130#define CHR_FILE__APPEND 0x00000200UL
131#define CHR_FILE__UNLINK 0x00000400UL
132#define CHR_FILE__LINK 0x00000800UL
133#define CHR_FILE__RENAME 0x00001000UL
134#define CHR_FILE__EXECUTE 0x00002000UL
135#define CHR_FILE__SWAPON 0x00004000UL
136#define CHR_FILE__QUOTAON 0x00008000UL
137#define CHR_FILE__MOUNTON 0x00010000UL
138#define CHR_FILE__EXECUTE_NO_TRANS 0x00020000UL
139#define CHR_FILE__ENTRYPOINT 0x00040000UL
140#define CHR_FILE__EXECMOD 0x00080000UL
141#define CHR_FILE__OPEN 0x00100000UL
142#define BLK_FILE__IOCTL 0x00000001UL
143#define BLK_FILE__READ 0x00000002UL
144#define BLK_FILE__WRITE 0x00000004UL
145#define BLK_FILE__CREATE 0x00000008UL
146#define BLK_FILE__GETATTR 0x00000010UL
147#define BLK_FILE__SETATTR 0x00000020UL
148#define BLK_FILE__LOCK 0x00000040UL
149#define BLK_FILE__RELABELFROM 0x00000080UL
150#define BLK_FILE__RELABELTO 0x00000100UL
151#define BLK_FILE__APPEND 0x00000200UL
152#define BLK_FILE__UNLINK 0x00000400UL
153#define BLK_FILE__LINK 0x00000800UL
154#define BLK_FILE__RENAME 0x00001000UL
155#define BLK_FILE__EXECUTE 0x00002000UL
156#define BLK_FILE__SWAPON 0x00004000UL
157#define BLK_FILE__QUOTAON 0x00008000UL
158#define BLK_FILE__MOUNTON 0x00010000UL
159#define BLK_FILE__OPEN 0x00020000UL
160#define SOCK_FILE__IOCTL 0x00000001UL
161#define SOCK_FILE__READ 0x00000002UL
162#define SOCK_FILE__WRITE 0x00000004UL
163#define SOCK_FILE__CREATE 0x00000008UL
164#define SOCK_FILE__GETATTR 0x00000010UL
165#define SOCK_FILE__SETATTR 0x00000020UL
166#define SOCK_FILE__LOCK 0x00000040UL
167#define SOCK_FILE__RELABELFROM 0x00000080UL
168#define SOCK_FILE__RELABELTO 0x00000100UL
169#define SOCK_FILE__APPEND 0x00000200UL
170#define SOCK_FILE__UNLINK 0x00000400UL
171#define SOCK_FILE__LINK 0x00000800UL
172#define SOCK_FILE__RENAME 0x00001000UL
173#define SOCK_FILE__EXECUTE 0x00002000UL
174#define SOCK_FILE__SWAPON 0x00004000UL
175#define SOCK_FILE__QUOTAON 0x00008000UL
176#define SOCK_FILE__MOUNTON 0x00010000UL
177#define SOCK_FILE__OPEN 0x00020000UL
178#define FIFO_FILE__IOCTL 0x00000001UL
179#define FIFO_FILE__READ 0x00000002UL
180#define FIFO_FILE__WRITE 0x00000004UL
181#define FIFO_FILE__CREATE 0x00000008UL
182#define FIFO_FILE__GETATTR 0x00000010UL
183#define FIFO_FILE__SETATTR 0x00000020UL
184#define FIFO_FILE__LOCK 0x00000040UL
185#define FIFO_FILE__RELABELFROM 0x00000080UL
186#define FIFO_FILE__RELABELTO 0x00000100UL
187#define FIFO_FILE__APPEND 0x00000200UL
188#define FIFO_FILE__UNLINK 0x00000400UL
189#define FIFO_FILE__LINK 0x00000800UL
190#define FIFO_FILE__RENAME 0x00001000UL
191#define FIFO_FILE__EXECUTE 0x00002000UL
192#define FIFO_FILE__SWAPON 0x00004000UL
193#define FIFO_FILE__QUOTAON 0x00008000UL
194#define FIFO_FILE__MOUNTON 0x00010000UL
195#define FIFO_FILE__OPEN 0x00020000UL
196#define FD__USE 0x00000001UL
197#define SOCKET__IOCTL 0x00000001UL
198#define SOCKET__READ 0x00000002UL
199#define SOCKET__WRITE 0x00000004UL
200#define SOCKET__CREATE 0x00000008UL
201#define SOCKET__GETATTR 0x00000010UL
202#define SOCKET__SETATTR 0x00000020UL
203#define SOCKET__LOCK 0x00000040UL
204#define SOCKET__RELABELFROM 0x00000080UL
205#define SOCKET__RELABELTO 0x00000100UL
206#define SOCKET__APPEND 0x00000200UL
207#define SOCKET__BIND 0x00000400UL
208#define SOCKET__CONNECT 0x00000800UL
209#define SOCKET__LISTEN 0x00001000UL
210#define SOCKET__ACCEPT 0x00002000UL
211#define SOCKET__GETOPT 0x00004000UL
212#define SOCKET__SETOPT 0x00008000UL
213#define SOCKET__SHUTDOWN 0x00010000UL
214#define SOCKET__RECVFROM 0x00020000UL
215#define SOCKET__SENDTO 0x00040000UL
216#define SOCKET__RECV_MSG 0x00080000UL
217#define SOCKET__SEND_MSG 0x00100000UL
218#define SOCKET__NAME_BIND 0x00200000UL
219#define TCP_SOCKET__IOCTL 0x00000001UL
220#define TCP_SOCKET__READ 0x00000002UL
221#define TCP_SOCKET__WRITE 0x00000004UL
222#define TCP_SOCKET__CREATE 0x00000008UL
223#define TCP_SOCKET__GETATTR 0x00000010UL
224#define TCP_SOCKET__SETATTR 0x00000020UL
225#define TCP_SOCKET__LOCK 0x00000040UL
226#define TCP_SOCKET__RELABELFROM 0x00000080UL
227#define TCP_SOCKET__RELABELTO 0x00000100UL
228#define TCP_SOCKET__APPEND 0x00000200UL
229#define TCP_SOCKET__BIND 0x00000400UL
230#define TCP_SOCKET__CONNECT 0x00000800UL
231#define TCP_SOCKET__LISTEN 0x00001000UL
232#define TCP_SOCKET__ACCEPT 0x00002000UL
233#define TCP_SOCKET__GETOPT 0x00004000UL
234#define TCP_SOCKET__SETOPT 0x00008000UL
235#define TCP_SOCKET__SHUTDOWN 0x00010000UL
236#define TCP_SOCKET__RECVFROM 0x00020000UL
237#define TCP_SOCKET__SENDTO 0x00040000UL
238#define TCP_SOCKET__RECV_MSG 0x00080000UL
239#define TCP_SOCKET__SEND_MSG 0x00100000UL
240#define TCP_SOCKET__NAME_BIND 0x00200000UL
241#define TCP_SOCKET__CONNECTTO 0x00400000UL
242#define TCP_SOCKET__NEWCONN 0x00800000UL
243#define TCP_SOCKET__ACCEPTFROM 0x01000000UL
244#define TCP_SOCKET__NODE_BIND 0x02000000UL
245#define TCP_SOCKET__NAME_CONNECT 0x04000000UL
246#define UDP_SOCKET__IOCTL 0x00000001UL
247#define UDP_SOCKET__READ 0x00000002UL
248#define UDP_SOCKET__WRITE 0x00000004UL
249#define UDP_SOCKET__CREATE 0x00000008UL
250#define UDP_SOCKET__GETATTR 0x00000010UL
251#define UDP_SOCKET__SETATTR 0x00000020UL
252#define UDP_SOCKET__LOCK 0x00000040UL
253#define UDP_SOCKET__RELABELFROM 0x00000080UL
254#define UDP_SOCKET__RELABELTO 0x00000100UL
255#define UDP_SOCKET__APPEND 0x00000200UL
256#define UDP_SOCKET__BIND 0x00000400UL
257#define UDP_SOCKET__CONNECT 0x00000800UL
258#define UDP_SOCKET__LISTEN 0x00001000UL
259#define UDP_SOCKET__ACCEPT 0x00002000UL
260#define UDP_SOCKET__GETOPT 0x00004000UL
261#define UDP_SOCKET__SETOPT 0x00008000UL
262#define UDP_SOCKET__SHUTDOWN 0x00010000UL
263#define UDP_SOCKET__RECVFROM 0x00020000UL
264#define UDP_SOCKET__SENDTO 0x00040000UL
265#define UDP_SOCKET__RECV_MSG 0x00080000UL
266#define UDP_SOCKET__SEND_MSG 0x00100000UL
267#define UDP_SOCKET__NAME_BIND 0x00200000UL
268#define UDP_SOCKET__NODE_BIND 0x00400000UL
269#define RAWIP_SOCKET__IOCTL 0x00000001UL
270#define RAWIP_SOCKET__READ 0x00000002UL
271#define RAWIP_SOCKET__WRITE 0x00000004UL
272#define RAWIP_SOCKET__CREATE 0x00000008UL
273#define RAWIP_SOCKET__GETATTR 0x00000010UL
274#define RAWIP_SOCKET__SETATTR 0x00000020UL
275#define RAWIP_SOCKET__LOCK 0x00000040UL
276#define RAWIP_SOCKET__RELABELFROM 0x00000080UL
277#define RAWIP_SOCKET__RELABELTO 0x00000100UL
278#define RAWIP_SOCKET__APPEND 0x00000200UL
279#define RAWIP_SOCKET__BIND 0x00000400UL
280#define RAWIP_SOCKET__CONNECT 0x00000800UL
281#define RAWIP_SOCKET__LISTEN 0x00001000UL
282#define RAWIP_SOCKET__ACCEPT 0x00002000UL
283#define RAWIP_SOCKET__GETOPT 0x00004000UL
284#define RAWIP_SOCKET__SETOPT 0x00008000UL
285#define RAWIP_SOCKET__SHUTDOWN 0x00010000UL
286#define RAWIP_SOCKET__RECVFROM 0x00020000UL
287#define RAWIP_SOCKET__SENDTO 0x00040000UL
288#define RAWIP_SOCKET__RECV_MSG 0x00080000UL
289#define RAWIP_SOCKET__SEND_MSG 0x00100000UL
290#define RAWIP_SOCKET__NAME_BIND 0x00200000UL
291#define RAWIP_SOCKET__NODE_BIND 0x00400000UL
292#define NODE__TCP_RECV 0x00000001UL
293#define NODE__TCP_SEND 0x00000002UL
294#define NODE__UDP_RECV 0x00000004UL
295#define NODE__UDP_SEND 0x00000008UL
296#define NODE__RAWIP_RECV 0x00000010UL
297#define NODE__RAWIP_SEND 0x00000020UL
298#define NODE__ENFORCE_DEST 0x00000040UL
299#define NODE__DCCP_RECV 0x00000080UL
300#define NODE__DCCP_SEND 0x00000100UL
301#define NODE__RECVFROM 0x00000200UL
302#define NODE__SENDTO 0x00000400UL
303#define NETIF__TCP_RECV 0x00000001UL
304#define NETIF__TCP_SEND 0x00000002UL
305#define NETIF__UDP_RECV 0x00000004UL
306#define NETIF__UDP_SEND 0x00000008UL
307#define NETIF__RAWIP_RECV 0x00000010UL
308#define NETIF__RAWIP_SEND 0x00000020UL
309#define NETIF__DCCP_RECV 0x00000040UL
310#define NETIF__DCCP_SEND 0x00000080UL
311#define NETIF__INGRESS 0x00000100UL
312#define NETIF__EGRESS 0x00000200UL
313#define NETLINK_SOCKET__IOCTL 0x00000001UL
314#define NETLINK_SOCKET__READ 0x00000002UL
315#define NETLINK_SOCKET__WRITE 0x00000004UL
316#define NETLINK_SOCKET__CREATE 0x00000008UL
317#define NETLINK_SOCKET__GETATTR 0x00000010UL
318#define NETLINK_SOCKET__SETATTR 0x00000020UL
319#define NETLINK_SOCKET__LOCK 0x00000040UL
320#define NETLINK_SOCKET__RELABELFROM 0x00000080UL
321#define NETLINK_SOCKET__RELABELTO 0x00000100UL
322#define NETLINK_SOCKET__APPEND 0x00000200UL
323#define NETLINK_SOCKET__BIND 0x00000400UL
324#define NETLINK_SOCKET__CONNECT 0x00000800UL
325#define NETLINK_SOCKET__LISTEN 0x00001000UL
326#define NETLINK_SOCKET__ACCEPT 0x00002000UL
327#define NETLINK_SOCKET__GETOPT 0x00004000UL
328#define NETLINK_SOCKET__SETOPT 0x00008000UL
329#define NETLINK_SOCKET__SHUTDOWN 0x00010000UL
330#define NETLINK_SOCKET__RECVFROM 0x00020000UL
331#define NETLINK_SOCKET__SENDTO 0x00040000UL
332#define NETLINK_SOCKET__RECV_MSG 0x00080000UL
333#define NETLINK_SOCKET__SEND_MSG 0x00100000UL
334#define NETLINK_SOCKET__NAME_BIND 0x00200000UL
335#define PACKET_SOCKET__IOCTL 0x00000001UL
336#define PACKET_SOCKET__READ 0x00000002UL
337#define PACKET_SOCKET__WRITE 0x00000004UL
338#define PACKET_SOCKET__CREATE 0x00000008UL
339#define PACKET_SOCKET__GETATTR 0x00000010UL
340#define PACKET_SOCKET__SETATTR 0x00000020UL
341#define PACKET_SOCKET__LOCK 0x00000040UL
342#define PACKET_SOCKET__RELABELFROM 0x00000080UL
343#define PACKET_SOCKET__RELABELTO 0x00000100UL
344#define PACKET_SOCKET__APPEND 0x00000200UL
345#define PACKET_SOCKET__BIND 0x00000400UL
346#define PACKET_SOCKET__CONNECT 0x00000800UL
347#define PACKET_SOCKET__LISTEN 0x00001000UL
348#define PACKET_SOCKET__ACCEPT 0x00002000UL
349#define PACKET_SOCKET__GETOPT 0x00004000UL
350#define PACKET_SOCKET__SETOPT 0x00008000UL
351#define PACKET_SOCKET__SHUTDOWN 0x00010000UL
352#define PACKET_SOCKET__RECVFROM 0x00020000UL
353#define PACKET_SOCKET__SENDTO 0x00040000UL
354#define PACKET_SOCKET__RECV_MSG 0x00080000UL
355#define PACKET_SOCKET__SEND_MSG 0x00100000UL
356#define PACKET_SOCKET__NAME_BIND 0x00200000UL
357#define KEY_SOCKET__IOCTL 0x00000001UL
358#define KEY_SOCKET__READ 0x00000002UL
359#define KEY_SOCKET__WRITE 0x00000004UL
360#define KEY_SOCKET__CREATE 0x00000008UL
361#define KEY_SOCKET__GETATTR 0x00000010UL
362#define KEY_SOCKET__SETATTR 0x00000020UL
363#define KEY_SOCKET__LOCK 0x00000040UL
364#define KEY_SOCKET__RELABELFROM 0x00000080UL
365#define KEY_SOCKET__RELABELTO 0x00000100UL
366#define KEY_SOCKET__APPEND 0x00000200UL
367#define KEY_SOCKET__BIND 0x00000400UL
368#define KEY_SOCKET__CONNECT 0x00000800UL
369#define KEY_SOCKET__LISTEN 0x00001000UL
370#define KEY_SOCKET__ACCEPT 0x00002000UL
371#define KEY_SOCKET__GETOPT 0x00004000UL
372#define KEY_SOCKET__SETOPT 0x00008000UL
373#define KEY_SOCKET__SHUTDOWN 0x00010000UL
374#define KEY_SOCKET__RECVFROM 0x00020000UL
375#define KEY_SOCKET__SENDTO 0x00040000UL
376#define KEY_SOCKET__RECV_MSG 0x00080000UL
377#define KEY_SOCKET__SEND_MSG 0x00100000UL
378#define KEY_SOCKET__NAME_BIND 0x00200000UL
379#define UNIX_STREAM_SOCKET__IOCTL 0x00000001UL
380#define UNIX_STREAM_SOCKET__READ 0x00000002UL
381#define UNIX_STREAM_SOCKET__WRITE 0x00000004UL
382#define UNIX_STREAM_SOCKET__CREATE 0x00000008UL
383#define UNIX_STREAM_SOCKET__GETATTR 0x00000010UL
384#define UNIX_STREAM_SOCKET__SETATTR 0x00000020UL
385#define UNIX_STREAM_SOCKET__LOCK 0x00000040UL
386#define UNIX_STREAM_SOCKET__RELABELFROM 0x00000080UL
387#define UNIX_STREAM_SOCKET__RELABELTO 0x00000100UL
388#define UNIX_STREAM_SOCKET__APPEND 0x00000200UL
389#define UNIX_STREAM_SOCKET__BIND 0x00000400UL
390#define UNIX_STREAM_SOCKET__CONNECT 0x00000800UL
391#define UNIX_STREAM_SOCKET__LISTEN 0x00001000UL
392#define UNIX_STREAM_SOCKET__ACCEPT 0x00002000UL
393#define UNIX_STREAM_SOCKET__GETOPT 0x00004000UL
394#define UNIX_STREAM_SOCKET__SETOPT 0x00008000UL
395#define UNIX_STREAM_SOCKET__SHUTDOWN 0x00010000UL
396#define UNIX_STREAM_SOCKET__RECVFROM 0x00020000UL
397#define UNIX_STREAM_SOCKET__SENDTO 0x00040000UL
398#define UNIX_STREAM_SOCKET__RECV_MSG 0x00080000UL
399#define UNIX_STREAM_SOCKET__SEND_MSG 0x00100000UL
400#define UNIX_STREAM_SOCKET__NAME_BIND 0x00200000UL
401#define UNIX_STREAM_SOCKET__CONNECTTO 0x00400000UL
402#define UNIX_STREAM_SOCKET__NEWCONN 0x00800000UL
403#define UNIX_STREAM_SOCKET__ACCEPTFROM 0x01000000UL
404#define UNIX_DGRAM_SOCKET__IOCTL 0x00000001UL
405#define UNIX_DGRAM_SOCKET__READ 0x00000002UL
406#define UNIX_DGRAM_SOCKET__WRITE 0x00000004UL
407#define UNIX_DGRAM_SOCKET__CREATE 0x00000008UL
408#define UNIX_DGRAM_SOCKET__GETATTR 0x00000010UL
409#define UNIX_DGRAM_SOCKET__SETATTR 0x00000020UL
410#define UNIX_DGRAM_SOCKET__LOCK 0x00000040UL
411#define UNIX_DGRAM_SOCKET__RELABELFROM 0x00000080UL
412#define UNIX_DGRAM_SOCKET__RELABELTO 0x00000100UL
413#define UNIX_DGRAM_SOCKET__APPEND 0x00000200UL
414#define UNIX_DGRAM_SOCKET__BIND 0x00000400UL
415#define UNIX_DGRAM_SOCKET__CONNECT 0x00000800UL
416#define UNIX_DGRAM_SOCKET__LISTEN 0x00001000UL
417#define UNIX_DGRAM_SOCKET__ACCEPT 0x00002000UL
418#define UNIX_DGRAM_SOCKET__GETOPT 0x00004000UL
419#define UNIX_DGRAM_SOCKET__SETOPT 0x00008000UL
420#define UNIX_DGRAM_SOCKET__SHUTDOWN 0x00010000UL
421#define UNIX_DGRAM_SOCKET__RECVFROM 0x00020000UL
422#define UNIX_DGRAM_SOCKET__SENDTO 0x00040000UL
423#define UNIX_DGRAM_SOCKET__RECV_MSG 0x00080000UL
424#define UNIX_DGRAM_SOCKET__SEND_MSG 0x00100000UL
425#define UNIX_DGRAM_SOCKET__NAME_BIND 0x00200000UL
426#define TUN_SOCKET__IOCTL 0x00000001UL
427#define TUN_SOCKET__READ 0x00000002UL
428#define TUN_SOCKET__WRITE 0x00000004UL
429#define TUN_SOCKET__CREATE 0x00000008UL
430#define TUN_SOCKET__GETATTR 0x00000010UL
431#define TUN_SOCKET__SETATTR 0x00000020UL
432#define TUN_SOCKET__LOCK 0x00000040UL
433#define TUN_SOCKET__RELABELFROM 0x00000080UL
434#define TUN_SOCKET__RELABELTO 0x00000100UL
435#define TUN_SOCKET__APPEND 0x00000200UL
436#define TUN_SOCKET__BIND 0x00000400UL
437#define TUN_SOCKET__CONNECT 0x00000800UL
438#define TUN_SOCKET__LISTEN 0x00001000UL
439#define TUN_SOCKET__ACCEPT 0x00002000UL
440#define TUN_SOCKET__GETOPT 0x00004000UL
441#define TUN_SOCKET__SETOPT 0x00008000UL
442#define TUN_SOCKET__SHUTDOWN 0x00010000UL
443#define TUN_SOCKET__RECVFROM 0x00020000UL
444#define TUN_SOCKET__SENDTO 0x00040000UL
445#define TUN_SOCKET__RECV_MSG 0x00080000UL
446#define TUN_SOCKET__SEND_MSG 0x00100000UL
447#define TUN_SOCKET__NAME_BIND 0x00200000UL
448#define PROCESS__FORK 0x00000001UL
449#define PROCESS__TRANSITION 0x00000002UL
450#define PROCESS__SIGCHLD 0x00000004UL
451#define PROCESS__SIGKILL 0x00000008UL
452#define PROCESS__SIGSTOP 0x00000010UL
453#define PROCESS__SIGNULL 0x00000020UL
454#define PROCESS__SIGNAL 0x00000040UL
455#define PROCESS__PTRACE 0x00000080UL
456#define PROCESS__GETSCHED 0x00000100UL
457#define PROCESS__SETSCHED 0x00000200UL
458#define PROCESS__GETSESSION 0x00000400UL
459#define PROCESS__GETPGID 0x00000800UL
460#define PROCESS__SETPGID 0x00001000UL
461#define PROCESS__GETCAP 0x00002000UL
462#define PROCESS__SETCAP 0x00004000UL
463#define PROCESS__SHARE 0x00008000UL
464#define PROCESS__GETATTR 0x00010000UL
465#define PROCESS__SETEXEC 0x00020000UL
466#define PROCESS__SETFSCREATE 0x00040000UL
467#define PROCESS__NOATSECURE 0x00080000UL
468#define PROCESS__SIGINH 0x00100000UL
469#define PROCESS__SETRLIMIT 0x00200000UL
470#define PROCESS__RLIMITINH 0x00400000UL
471#define PROCESS__DYNTRANSITION 0x00800000UL
472#define PROCESS__SETCURRENT 0x01000000UL
473#define PROCESS__EXECMEM 0x02000000UL
474#define PROCESS__EXECSTACK 0x04000000UL
475#define PROCESS__EXECHEAP 0x08000000UL
476#define PROCESS__SETKEYCREATE 0x10000000UL
477#define PROCESS__SETSOCKCREATE 0x20000000UL
478#define IPC__CREATE 0x00000001UL
479#define IPC__DESTROY 0x00000002UL
480#define IPC__GETATTR 0x00000004UL
481#define IPC__SETATTR 0x00000008UL
482#define IPC__READ 0x00000010UL
483#define IPC__WRITE 0x00000020UL
484#define IPC__ASSOCIATE 0x00000040UL
485#define IPC__UNIX_READ 0x00000080UL
486#define IPC__UNIX_WRITE 0x00000100UL
487#define SEM__CREATE 0x00000001UL
488#define SEM__DESTROY 0x00000002UL
489#define SEM__GETATTR 0x00000004UL
490#define SEM__SETATTR 0x00000008UL
491#define SEM__READ 0x00000010UL
492#define SEM__WRITE 0x00000020UL
493#define SEM__ASSOCIATE 0x00000040UL
494#define SEM__UNIX_READ 0x00000080UL
495#define SEM__UNIX_WRITE 0x00000100UL
496#define MSGQ__CREATE 0x00000001UL
497#define MSGQ__DESTROY 0x00000002UL
498#define MSGQ__GETATTR 0x00000004UL
499#define MSGQ__SETATTR 0x00000008UL
500#define MSGQ__READ 0x00000010UL
501#define MSGQ__WRITE 0x00000020UL
502#define MSGQ__ASSOCIATE 0x00000040UL
503#define MSGQ__UNIX_READ 0x00000080UL
504#define MSGQ__UNIX_WRITE 0x00000100UL
505#define MSGQ__ENQUEUE 0x00000200UL
506#define MSG__SEND 0x00000001UL
507#define MSG__RECEIVE 0x00000002UL
508#define SHM__CREATE 0x00000001UL
509#define SHM__DESTROY 0x00000002UL
510#define SHM__GETATTR 0x00000004UL
511#define SHM__SETATTR 0x00000008UL
512#define SHM__READ 0x00000010UL
513#define SHM__WRITE 0x00000020UL
514#define SHM__ASSOCIATE 0x00000040UL
515#define SHM__UNIX_READ 0x00000080UL
516#define SHM__UNIX_WRITE 0x00000100UL
517#define SHM__LOCK 0x00000200UL
518#define SECURITY__COMPUTE_AV 0x00000001UL
519#define SECURITY__COMPUTE_CREATE 0x00000002UL
520#define SECURITY__COMPUTE_MEMBER 0x00000004UL
521#define SECURITY__CHECK_CONTEXT 0x00000008UL
522#define SECURITY__LOAD_POLICY 0x00000010UL
523#define SECURITY__COMPUTE_RELABEL 0x00000020UL
524#define SECURITY__COMPUTE_USER 0x00000040UL
525#define SECURITY__SETENFORCE 0x00000080UL
526#define SECURITY__SETBOOL 0x00000100UL
527#define SECURITY__SETSECPARAM 0x00000200UL
528#define SECURITY__SETCHECKREQPROT 0x00000400UL
529#define SYSTEM__IPC_INFO 0x00000001UL
530#define SYSTEM__SYSLOG_READ 0x00000002UL
531#define SYSTEM__SYSLOG_MOD 0x00000004UL
532#define SYSTEM__SYSLOG_CONSOLE 0x00000008UL
533#define SYSTEM__MODULE_REQUEST 0x00000010UL
534#define CAPABILITY__CHOWN 0x00000001UL
535#define CAPABILITY__DAC_OVERRIDE 0x00000002UL
536#define CAPABILITY__DAC_READ_SEARCH 0x00000004UL
537#define CAPABILITY__FOWNER 0x00000008UL
538#define CAPABILITY__FSETID 0x00000010UL
539#define CAPABILITY__KILL 0x00000020UL
540#define CAPABILITY__SETGID 0x00000040UL
541#define CAPABILITY__SETUID 0x00000080UL
542#define CAPABILITY__SETPCAP 0x00000100UL
543#define CAPABILITY__LINUX_IMMUTABLE 0x00000200UL
544#define CAPABILITY__NET_BIND_SERVICE 0x00000400UL
545#define CAPABILITY__NET_BROADCAST 0x00000800UL
546#define CAPABILITY__NET_ADMIN 0x00001000UL
547#define CAPABILITY__NET_RAW 0x00002000UL
548#define CAPABILITY__IPC_LOCK 0x00004000UL
549#define CAPABILITY__IPC_OWNER 0x00008000UL
550#define CAPABILITY__SYS_MODULE 0x00010000UL
551#define CAPABILITY__SYS_RAWIO 0x00020000UL
552#define CAPABILITY__SYS_CHROOT 0x00040000UL
553#define CAPABILITY__SYS_PTRACE 0x00080000UL
554#define CAPABILITY__SYS_PACCT 0x00100000UL
555#define CAPABILITY__SYS_ADMIN 0x00200000UL
556#define CAPABILITY__SYS_BOOT 0x00400000UL
557#define CAPABILITY__SYS_NICE 0x00800000UL
558#define CAPABILITY__SYS_RESOURCE 0x01000000UL
559#define CAPABILITY__SYS_TIME 0x02000000UL
560#define CAPABILITY__SYS_TTY_CONFIG 0x04000000UL
561#define CAPABILITY__MKNOD 0x08000000UL
562#define CAPABILITY__LEASE 0x10000000UL
563#define CAPABILITY__AUDIT_WRITE 0x20000000UL
564#define CAPABILITY__AUDIT_CONTROL 0x40000000UL
565#define CAPABILITY__SETFCAP 0x80000000UL
566#define CAPABILITY2__MAC_OVERRIDE 0x00000001UL
567#define CAPABILITY2__MAC_ADMIN 0x00000002UL
568#define NETLINK_ROUTE_SOCKET__IOCTL 0x00000001UL
569#define NETLINK_ROUTE_SOCKET__READ 0x00000002UL
570#define NETLINK_ROUTE_SOCKET__WRITE 0x00000004UL
571#define NETLINK_ROUTE_SOCKET__CREATE 0x00000008UL
572#define NETLINK_ROUTE_SOCKET__GETATTR 0x00000010UL
573#define NETLINK_ROUTE_SOCKET__SETATTR 0x00000020UL
574#define NETLINK_ROUTE_SOCKET__LOCK 0x00000040UL
575#define NETLINK_ROUTE_SOCKET__RELABELFROM 0x00000080UL
576#define NETLINK_ROUTE_SOCKET__RELABELTO 0x00000100UL
577#define NETLINK_ROUTE_SOCKET__APPEND 0x00000200UL
578#define NETLINK_ROUTE_SOCKET__BIND 0x00000400UL
579#define NETLINK_ROUTE_SOCKET__CONNECT 0x00000800UL
580#define NETLINK_ROUTE_SOCKET__LISTEN 0x00001000UL
581#define NETLINK_ROUTE_SOCKET__ACCEPT 0x00002000UL
582#define NETLINK_ROUTE_SOCKET__GETOPT 0x00004000UL
583#define NETLINK_ROUTE_SOCKET__SETOPT 0x00008000UL
584#define NETLINK_ROUTE_SOCKET__SHUTDOWN 0x00010000UL
585#define NETLINK_ROUTE_SOCKET__RECVFROM 0x00020000UL
586#define NETLINK_ROUTE_SOCKET__SENDTO 0x00040000UL
587#define NETLINK_ROUTE_SOCKET__RECV_MSG 0x00080000UL
588#define NETLINK_ROUTE_SOCKET__SEND_MSG 0x00100000UL
589#define NETLINK_ROUTE_SOCKET__NAME_BIND 0x00200000UL
590#define NETLINK_ROUTE_SOCKET__NLMSG_READ 0x00400000UL
591#define NETLINK_ROUTE_SOCKET__NLMSG_WRITE 0x00800000UL
592#define NETLINK_FIREWALL_SOCKET__IOCTL 0x00000001UL
593#define NETLINK_FIREWALL_SOCKET__READ 0x00000002UL
594#define NETLINK_FIREWALL_SOCKET__WRITE 0x00000004UL
595#define NETLINK_FIREWALL_SOCKET__CREATE 0x00000008UL
596#define NETLINK_FIREWALL_SOCKET__GETATTR 0x00000010UL
597#define NETLINK_FIREWALL_SOCKET__SETATTR 0x00000020UL
598#define NETLINK_FIREWALL_SOCKET__LOCK 0x00000040UL
599#define NETLINK_FIREWALL_SOCKET__RELABELFROM 0x00000080UL
600#define NETLINK_FIREWALL_SOCKET__RELABELTO 0x00000100UL
601#define NETLINK_FIREWALL_SOCKET__APPEND 0x00000200UL
602#define NETLINK_FIREWALL_SOCKET__BIND 0x00000400UL
603#define NETLINK_FIREWALL_SOCKET__CONNECT 0x00000800UL
604#define NETLINK_FIREWALL_SOCKET__LISTEN 0x00001000UL
605#define NETLINK_FIREWALL_SOCKET__ACCEPT 0x00002000UL
606#define NETLINK_FIREWALL_SOCKET__GETOPT 0x00004000UL
607#define NETLINK_FIREWALL_SOCKET__SETOPT 0x00008000UL
608#define NETLINK_FIREWALL_SOCKET__SHUTDOWN 0x00010000UL
609#define NETLINK_FIREWALL_SOCKET__RECVFROM 0x00020000UL
610#define NETLINK_FIREWALL_SOCKET__SENDTO 0x00040000UL
611#define NETLINK_FIREWALL_SOCKET__RECV_MSG 0x00080000UL
612#define NETLINK_FIREWALL_SOCKET__SEND_MSG 0x00100000UL
613#define NETLINK_FIREWALL_SOCKET__NAME_BIND 0x00200000UL
614#define NETLINK_FIREWALL_SOCKET__NLMSG_READ 0x00400000UL
615#define NETLINK_FIREWALL_SOCKET__NLMSG_WRITE 0x00800000UL
616#define NETLINK_TCPDIAG_SOCKET__IOCTL 0x00000001UL
617#define NETLINK_TCPDIAG_SOCKET__READ 0x00000002UL
618#define NETLINK_TCPDIAG_SOCKET__WRITE 0x00000004UL
619#define NETLINK_TCPDIAG_SOCKET__CREATE 0x00000008UL
620#define NETLINK_TCPDIAG_SOCKET__GETATTR 0x00000010UL
621#define NETLINK_TCPDIAG_SOCKET__SETATTR 0x00000020UL
622#define NETLINK_TCPDIAG_SOCKET__LOCK 0x00000040UL
623#define NETLINK_TCPDIAG_SOCKET__RELABELFROM 0x00000080UL
624#define NETLINK_TCPDIAG_SOCKET__RELABELTO 0x00000100UL
625#define NETLINK_TCPDIAG_SOCKET__APPEND 0x00000200UL
626#define NETLINK_TCPDIAG_SOCKET__BIND 0x00000400UL
627#define NETLINK_TCPDIAG_SOCKET__CONNECT 0x00000800UL
628#define NETLINK_TCPDIAG_SOCKET__LISTEN 0x00001000UL
629#define NETLINK_TCPDIAG_SOCKET__ACCEPT 0x00002000UL
630#define NETLINK_TCPDIAG_SOCKET__GETOPT 0x00004000UL
631#define NETLINK_TCPDIAG_SOCKET__SETOPT 0x00008000UL
632#define NETLINK_TCPDIAG_SOCKET__SHUTDOWN 0x00010000UL
633#define NETLINK_TCPDIAG_SOCKET__RECVFROM 0x00020000UL
634#define NETLINK_TCPDIAG_SOCKET__SENDTO 0x00040000UL
635#define NETLINK_TCPDIAG_SOCKET__RECV_MSG 0x00080000UL
636#define NETLINK_TCPDIAG_SOCKET__SEND_MSG 0x00100000UL
637#define NETLINK_TCPDIAG_SOCKET__NAME_BIND 0x00200000UL
638#define NETLINK_TCPDIAG_SOCKET__NLMSG_READ 0x00400000UL
639#define NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE 0x00800000UL
640#define NETLINK_NFLOG_SOCKET__IOCTL 0x00000001UL
641#define NETLINK_NFLOG_SOCKET__READ 0x00000002UL
642#define NETLINK_NFLOG_SOCKET__WRITE 0x00000004UL
643#define NETLINK_NFLOG_SOCKET__CREATE 0x00000008UL
644#define NETLINK_NFLOG_SOCKET__GETATTR 0x00000010UL
645#define NETLINK_NFLOG_SOCKET__SETATTR 0x00000020UL
646#define NETLINK_NFLOG_SOCKET__LOCK 0x00000040UL
647#define NETLINK_NFLOG_SOCKET__RELABELFROM 0x00000080UL
648#define NETLINK_NFLOG_SOCKET__RELABELTO 0x00000100UL
649#define NETLINK_NFLOG_SOCKET__APPEND 0x00000200UL
650#define NETLINK_NFLOG_SOCKET__BIND 0x00000400UL
651#define NETLINK_NFLOG_SOCKET__CONNECT 0x00000800UL
652#define NETLINK_NFLOG_SOCKET__LISTEN 0x00001000UL
653#define NETLINK_NFLOG_SOCKET__ACCEPT 0x00002000UL
654#define NETLINK_NFLOG_SOCKET__GETOPT 0x00004000UL
655#define NETLINK_NFLOG_SOCKET__SETOPT 0x00008000UL
656#define NETLINK_NFLOG_SOCKET__SHUTDOWN 0x00010000UL
657#define NETLINK_NFLOG_SOCKET__RECVFROM 0x00020000UL
658#define NETLINK_NFLOG_SOCKET__SENDTO 0x00040000UL
659#define NETLINK_NFLOG_SOCKET__RECV_MSG 0x00080000UL
660#define NETLINK_NFLOG_SOCKET__SEND_MSG 0x00100000UL
661#define NETLINK_NFLOG_SOCKET__NAME_BIND 0x00200000UL
662#define NETLINK_XFRM_SOCKET__IOCTL 0x00000001UL
663#define NETLINK_XFRM_SOCKET__READ 0x00000002UL
664#define NETLINK_XFRM_SOCKET__WRITE 0x00000004UL
665#define NETLINK_XFRM_SOCKET__CREATE 0x00000008UL
666#define NETLINK_XFRM_SOCKET__GETATTR 0x00000010UL
667#define NETLINK_XFRM_SOCKET__SETATTR 0x00000020UL
668#define NETLINK_XFRM_SOCKET__LOCK 0x00000040UL
669#define NETLINK_XFRM_SOCKET__RELABELFROM 0x00000080UL
670#define NETLINK_XFRM_SOCKET__RELABELTO 0x00000100UL
671#define NETLINK_XFRM_SOCKET__APPEND 0x00000200UL
672#define NETLINK_XFRM_SOCKET__BIND 0x00000400UL
673#define NETLINK_XFRM_SOCKET__CONNECT 0x00000800UL
674#define NETLINK_XFRM_SOCKET__LISTEN 0x00001000UL
675#define NETLINK_XFRM_SOCKET__ACCEPT 0x00002000UL
676#define NETLINK_XFRM_SOCKET__GETOPT 0x00004000UL
677#define NETLINK_XFRM_SOCKET__SETOPT 0x00008000UL
678#define NETLINK_XFRM_SOCKET__SHUTDOWN 0x00010000UL
679#define NETLINK_XFRM_SOCKET__RECVFROM 0x00020000UL
680#define NETLINK_XFRM_SOCKET__SENDTO 0x00040000UL
681#define NETLINK_XFRM_SOCKET__RECV_MSG 0x00080000UL
682#define NETLINK_XFRM_SOCKET__SEND_MSG 0x00100000UL
683#define NETLINK_XFRM_SOCKET__NAME_BIND 0x00200000UL
684#define NETLINK_XFRM_SOCKET__NLMSG_READ 0x00400000UL
685#define NETLINK_XFRM_SOCKET__NLMSG_WRITE 0x00800000UL
686#define NETLINK_SELINUX_SOCKET__IOCTL 0x00000001UL
687#define NETLINK_SELINUX_SOCKET__READ 0x00000002UL
688#define NETLINK_SELINUX_SOCKET__WRITE 0x00000004UL
689#define NETLINK_SELINUX_SOCKET__CREATE 0x00000008UL
690#define NETLINK_SELINUX_SOCKET__GETATTR 0x00000010UL
691#define NETLINK_SELINUX_SOCKET__SETATTR 0x00000020UL
692#define NETLINK_SELINUX_SOCKET__LOCK 0x00000040UL
693#define NETLINK_SELINUX_SOCKET__RELABELFROM 0x00000080UL
694#define NETLINK_SELINUX_SOCKET__RELABELTO 0x00000100UL
695#define NETLINK_SELINUX_SOCKET__APPEND 0x00000200UL
696#define NETLINK_SELINUX_SOCKET__BIND 0x00000400UL
697#define NETLINK_SELINUX_SOCKET__CONNECT 0x00000800UL
698#define NETLINK_SELINUX_SOCKET__LISTEN 0x00001000UL
699#define NETLINK_SELINUX_SOCKET__ACCEPT 0x00002000UL
700#define NETLINK_SELINUX_SOCKET__GETOPT 0x00004000UL
701#define NETLINK_SELINUX_SOCKET__SETOPT 0x00008000UL
702#define NETLINK_SELINUX_SOCKET__SHUTDOWN 0x00010000UL
703#define NETLINK_SELINUX_SOCKET__RECVFROM 0x00020000UL
704#define NETLINK_SELINUX_SOCKET__SENDTO 0x00040000UL
705#define NETLINK_SELINUX_SOCKET__RECV_MSG 0x00080000UL
706#define NETLINK_SELINUX_SOCKET__SEND_MSG 0x00100000UL
707#define NETLINK_SELINUX_SOCKET__NAME_BIND 0x00200000UL
708#define NETLINK_AUDIT_SOCKET__IOCTL 0x00000001UL
709#define NETLINK_AUDIT_SOCKET__READ 0x00000002UL
710#define NETLINK_AUDIT_SOCKET__WRITE 0x00000004UL
711#define NETLINK_AUDIT_SOCKET__CREATE 0x00000008UL
712#define NETLINK_AUDIT_SOCKET__GETATTR 0x00000010UL
713#define NETLINK_AUDIT_SOCKET__SETATTR 0x00000020UL
714#define NETLINK_AUDIT_SOCKET__LOCK 0x00000040UL
715#define NETLINK_AUDIT_SOCKET__RELABELFROM 0x00000080UL
716#define NETLINK_AUDIT_SOCKET__RELABELTO 0x00000100UL
717#define NETLINK_AUDIT_SOCKET__APPEND 0x00000200UL
718#define NETLINK_AUDIT_SOCKET__BIND 0x00000400UL
719#define NETLINK_AUDIT_SOCKET__CONNECT 0x00000800UL
720#define NETLINK_AUDIT_SOCKET__LISTEN 0x00001000UL
721#define NETLINK_AUDIT_SOCKET__ACCEPT 0x00002000UL
722#define NETLINK_AUDIT_SOCKET__GETOPT 0x00004000UL
723#define NETLINK_AUDIT_SOCKET__SETOPT 0x00008000UL
724#define NETLINK_AUDIT_SOCKET__SHUTDOWN 0x00010000UL
725#define NETLINK_AUDIT_SOCKET__RECVFROM 0x00020000UL
726#define NETLINK_AUDIT_SOCKET__SENDTO 0x00040000UL
727#define NETLINK_AUDIT_SOCKET__RECV_MSG 0x00080000UL
728#define NETLINK_AUDIT_SOCKET__SEND_MSG 0x00100000UL
729#define NETLINK_AUDIT_SOCKET__NAME_BIND 0x00200000UL
730#define NETLINK_AUDIT_SOCKET__NLMSG_READ 0x00400000UL
731#define NETLINK_AUDIT_SOCKET__NLMSG_WRITE 0x00800000UL
732#define NETLINK_AUDIT_SOCKET__NLMSG_RELAY 0x01000000UL
733#define NETLINK_AUDIT_SOCKET__NLMSG_READPRIV 0x02000000UL
734#define NETLINK_AUDIT_SOCKET__NLMSG_TTY_AUDIT 0x04000000UL
735#define NETLINK_IP6FW_SOCKET__IOCTL 0x00000001UL
736#define NETLINK_IP6FW_SOCKET__READ 0x00000002UL
737#define NETLINK_IP6FW_SOCKET__WRITE 0x00000004UL
738#define NETLINK_IP6FW_SOCKET__CREATE 0x00000008UL
739#define NETLINK_IP6FW_SOCKET__GETATTR 0x00000010UL
740#define NETLINK_IP6FW_SOCKET__SETATTR 0x00000020UL
741#define NETLINK_IP6FW_SOCKET__LOCK 0x00000040UL
742#define NETLINK_IP6FW_SOCKET__RELABELFROM 0x00000080UL
743#define NETLINK_IP6FW_SOCKET__RELABELTO 0x00000100UL
744#define NETLINK_IP6FW_SOCKET__APPEND 0x00000200UL
745#define NETLINK_IP6FW_SOCKET__BIND 0x00000400UL
746#define NETLINK_IP6FW_SOCKET__CONNECT 0x00000800UL
747#define NETLINK_IP6FW_SOCKET__LISTEN 0x00001000UL
748#define NETLINK_IP6FW_SOCKET__ACCEPT 0x00002000UL
749#define NETLINK_IP6FW_SOCKET__GETOPT 0x00004000UL
750#define NETLINK_IP6FW_SOCKET__SETOPT 0x00008000UL
751#define NETLINK_IP6FW_SOCKET__SHUTDOWN 0x00010000UL
752#define NETLINK_IP6FW_SOCKET__RECVFROM 0x00020000UL
753#define NETLINK_IP6FW_SOCKET__SENDTO 0x00040000UL
754#define NETLINK_IP6FW_SOCKET__RECV_MSG 0x00080000UL
755#define NETLINK_IP6FW_SOCKET__SEND_MSG 0x00100000UL
756#define NETLINK_IP6FW_SOCKET__NAME_BIND 0x00200000UL
757#define NETLINK_IP6FW_SOCKET__NLMSG_READ 0x00400000UL
758#define NETLINK_IP6FW_SOCKET__NLMSG_WRITE 0x00800000UL
759#define NETLINK_DNRT_SOCKET__IOCTL 0x00000001UL
760#define NETLINK_DNRT_SOCKET__READ 0x00000002UL
761#define NETLINK_DNRT_SOCKET__WRITE 0x00000004UL
762#define NETLINK_DNRT_SOCKET__CREATE 0x00000008UL
763#define NETLINK_DNRT_SOCKET__GETATTR 0x00000010UL
764#define NETLINK_DNRT_SOCKET__SETATTR 0x00000020UL
765#define NETLINK_DNRT_SOCKET__LOCK 0x00000040UL
766#define NETLINK_DNRT_SOCKET__RELABELFROM 0x00000080UL
767#define NETLINK_DNRT_SOCKET__RELABELTO 0x00000100UL
768#define NETLINK_DNRT_SOCKET__APPEND 0x00000200UL
769#define NETLINK_DNRT_SOCKET__BIND 0x00000400UL
770#define NETLINK_DNRT_SOCKET__CONNECT 0x00000800UL
771#define NETLINK_DNRT_SOCKET__LISTEN 0x00001000UL
772#define NETLINK_DNRT_SOCKET__ACCEPT 0x00002000UL
773#define NETLINK_DNRT_SOCKET__GETOPT 0x00004000UL
774#define NETLINK_DNRT_SOCKET__SETOPT 0x00008000UL
775#define NETLINK_DNRT_SOCKET__SHUTDOWN 0x00010000UL
776#define NETLINK_DNRT_SOCKET__RECVFROM 0x00020000UL
777#define NETLINK_DNRT_SOCKET__SENDTO 0x00040000UL
778#define NETLINK_DNRT_SOCKET__RECV_MSG 0x00080000UL
779#define NETLINK_DNRT_SOCKET__SEND_MSG 0x00100000UL
780#define NETLINK_DNRT_SOCKET__NAME_BIND 0x00200000UL
781#define ASSOCIATION__SENDTO 0x00000001UL
782#define ASSOCIATION__RECVFROM 0x00000002UL
783#define ASSOCIATION__SETCONTEXT 0x00000004UL
784#define ASSOCIATION__POLMATCH 0x00000008UL
785#define NETLINK_KOBJECT_UEVENT_SOCKET__IOCTL 0x00000001UL
786#define NETLINK_KOBJECT_UEVENT_SOCKET__READ 0x00000002UL
787#define NETLINK_KOBJECT_UEVENT_SOCKET__WRITE 0x00000004UL
788#define NETLINK_KOBJECT_UEVENT_SOCKET__CREATE 0x00000008UL
789#define NETLINK_KOBJECT_UEVENT_SOCKET__GETATTR 0x00000010UL
790#define NETLINK_KOBJECT_UEVENT_SOCKET__SETATTR 0x00000020UL
791#define NETLINK_KOBJECT_UEVENT_SOCKET__LOCK 0x00000040UL
792#define NETLINK_KOBJECT_UEVENT_SOCKET__RELABELFROM 0x00000080UL
793#define NETLINK_KOBJECT_UEVENT_SOCKET__RELABELTO 0x00000100UL
794#define NETLINK_KOBJECT_UEVENT_SOCKET__APPEND 0x00000200UL
795#define NETLINK_KOBJECT_UEVENT_SOCKET__BIND 0x00000400UL
796#define NETLINK_KOBJECT_UEVENT_SOCKET__CONNECT 0x00000800UL
797#define NETLINK_KOBJECT_UEVENT_SOCKET__LISTEN 0x00001000UL
798#define NETLINK_KOBJECT_UEVENT_SOCKET__ACCEPT 0x00002000UL
799#define NETLINK_KOBJECT_UEVENT_SOCKET__GETOPT 0x00004000UL
800#define NETLINK_KOBJECT_UEVENT_SOCKET__SETOPT 0x00008000UL
801#define NETLINK_KOBJECT_UEVENT_SOCKET__SHUTDOWN 0x00010000UL
802#define NETLINK_KOBJECT_UEVENT_SOCKET__RECVFROM 0x00020000UL
803#define NETLINK_KOBJECT_UEVENT_SOCKET__SENDTO 0x00040000UL
804#define NETLINK_KOBJECT_UEVENT_SOCKET__RECV_MSG 0x00080000UL
805#define NETLINK_KOBJECT_UEVENT_SOCKET__SEND_MSG 0x00100000UL
806#define NETLINK_KOBJECT_UEVENT_SOCKET__NAME_BIND 0x00200000UL
807#define APPLETALK_SOCKET__IOCTL 0x00000001UL
808#define APPLETALK_SOCKET__READ 0x00000002UL
809#define APPLETALK_SOCKET__WRITE 0x00000004UL
810#define APPLETALK_SOCKET__CREATE 0x00000008UL
811#define APPLETALK_SOCKET__GETATTR 0x00000010UL
812#define APPLETALK_SOCKET__SETATTR 0x00000020UL
813#define APPLETALK_SOCKET__LOCK 0x00000040UL
814#define APPLETALK_SOCKET__RELABELFROM 0x00000080UL
815#define APPLETALK_SOCKET__RELABELTO 0x00000100UL
816#define APPLETALK_SOCKET__APPEND 0x00000200UL
817#define APPLETALK_SOCKET__BIND 0x00000400UL
818#define APPLETALK_SOCKET__CONNECT 0x00000800UL
819#define APPLETALK_SOCKET__LISTEN 0x00001000UL
820#define APPLETALK_SOCKET__ACCEPT 0x00002000UL
821#define APPLETALK_SOCKET__GETOPT 0x00004000UL
822#define APPLETALK_SOCKET__SETOPT 0x00008000UL
823#define APPLETALK_SOCKET__SHUTDOWN 0x00010000UL
824#define APPLETALK_SOCKET__RECVFROM 0x00020000UL
825#define APPLETALK_SOCKET__SENDTO 0x00040000UL
826#define APPLETALK_SOCKET__RECV_MSG 0x00080000UL
827#define APPLETALK_SOCKET__SEND_MSG 0x00100000UL
828#define APPLETALK_SOCKET__NAME_BIND 0x00200000UL
829#define PACKET__SEND 0x00000001UL
830#define PACKET__RECV 0x00000002UL
831#define PACKET__RELABELTO 0x00000004UL
832#define PACKET__FLOW_IN 0x00000008UL
833#define PACKET__FLOW_OUT 0x00000010UL
834#define PACKET__FORWARD_IN 0x00000020UL
835#define PACKET__FORWARD_OUT 0x00000040UL
836#define KEY__VIEW 0x00000001UL
837#define KEY__READ 0x00000002UL
838#define KEY__WRITE 0x00000004UL
839#define KEY__SEARCH 0x00000008UL
840#define KEY__LINK 0x00000010UL
841#define KEY__SETATTR 0x00000020UL
842#define KEY__CREATE 0x00000040UL
843#define DCCP_SOCKET__IOCTL 0x00000001UL
844#define DCCP_SOCKET__READ 0x00000002UL
845#define DCCP_SOCKET__WRITE 0x00000004UL
846#define DCCP_SOCKET__CREATE 0x00000008UL
847#define DCCP_SOCKET__GETATTR 0x00000010UL
848#define DCCP_SOCKET__SETATTR 0x00000020UL
849#define DCCP_SOCKET__LOCK 0x00000040UL
850#define DCCP_SOCKET__RELABELFROM 0x00000080UL
851#define DCCP_SOCKET__RELABELTO 0x00000100UL
852#define DCCP_SOCKET__APPEND 0x00000200UL
853#define DCCP_SOCKET__BIND 0x00000400UL
854#define DCCP_SOCKET__CONNECT 0x00000800UL
855#define DCCP_SOCKET__LISTEN 0x00001000UL
856#define DCCP_SOCKET__ACCEPT 0x00002000UL
857#define DCCP_SOCKET__GETOPT 0x00004000UL
858#define DCCP_SOCKET__SETOPT 0x00008000UL
859#define DCCP_SOCKET__SHUTDOWN 0x00010000UL
860#define DCCP_SOCKET__RECVFROM 0x00020000UL
861#define DCCP_SOCKET__SENDTO 0x00040000UL
862#define DCCP_SOCKET__RECV_MSG 0x00080000UL
863#define DCCP_SOCKET__SEND_MSG 0x00100000UL
864#define DCCP_SOCKET__NAME_BIND 0x00200000UL
865#define DCCP_SOCKET__NODE_BIND 0x00400000UL
866#define DCCP_SOCKET__NAME_CONNECT 0x00800000UL
867#define MEMPROTECT__MMAP_ZERO 0x00000001UL
868#define PEER__RECV 0x00000001UL
869#define KERNEL_SERVICE__USE_AS_OVERRIDE 0x00000001UL
870#define KERNEL_SERVICE__CREATE_FILES_AS 0x00000002UL
diff --git a/security/selinux/include/avc_ss.h b/security/selinux/include/avc_ss.h
index bb1ec801bdfe..4677aa519b04 100644
--- a/security/selinux/include/avc_ss.h
+++ b/security/selinux/include/avc_ss.h
@@ -10,26 +10,13 @@
10 10
11int avc_ss_reset(u32 seqno); 11int avc_ss_reset(u32 seqno);
12 12
13struct av_perm_to_string { 13/* Class/perm mapping support */
14 u16 tclass; 14struct security_class_mapping {
15 u32 value;
16 const char *name; 15 const char *name;
16 const char *perms[sizeof(u32) * 8 + 1];
17}; 17};
18 18
19struct av_inherit { 19extern struct security_class_mapping secclass_map[];
20 const char **common_pts;
21 u32 common_base;
22 u16 tclass;
23};
24
25struct selinux_class_perm {
26 const struct av_perm_to_string *av_perm_to_string;
27 u32 av_pts_len;
28 u32 cts_len;
29 const char **class_to_string;
30 const struct av_inherit *av_inherit;
31 u32 av_inherit_len;
32};
33 20
34#endif /* _SELINUX_AVC_SS_H_ */ 21#endif /* _SELINUX_AVC_SS_H_ */
35 22
diff --git a/security/selinux/include/class_to_string.h b/security/selinux/include/class_to_string.h
deleted file mode 100644
index 7ab9299bfb6b..000000000000
--- a/security/selinux/include/class_to_string.h
+++ /dev/null
@@ -1,80 +0,0 @@
1/* This file is automatically generated. Do not edit. */
2/*
3 * Security object class definitions
4 */
5 S_(NULL)
6 S_("security")
7 S_("process")
8 S_("system")
9 S_("capability")
10 S_("filesystem")
11 S_("file")
12 S_("dir")
13 S_("fd")
14 S_("lnk_file")
15 S_("chr_file")
16 S_("blk_file")
17 S_("sock_file")
18 S_("fifo_file")
19 S_("socket")
20 S_("tcp_socket")
21 S_("udp_socket")
22 S_("rawip_socket")
23 S_("node")
24 S_("netif")
25 S_("netlink_socket")
26 S_("packet_socket")
27 S_("key_socket")
28 S_("unix_stream_socket")
29 S_("unix_dgram_socket")
30 S_("sem")
31 S_("msg")
32 S_("msgq")
33 S_("shm")
34 S_("ipc")
35 S_(NULL)
36 S_(NULL)
37 S_(NULL)
38 S_(NULL)
39 S_(NULL)
40 S_(NULL)
41 S_(NULL)
42 S_(NULL)
43 S_(NULL)
44 S_(NULL)
45 S_(NULL)
46 S_(NULL)
47 S_(NULL)
48 S_("netlink_route_socket")
49 S_("netlink_firewall_socket")
50 S_("netlink_tcpdiag_socket")
51 S_("netlink_nflog_socket")
52 S_("netlink_xfrm_socket")
53 S_("netlink_selinux_socket")
54 S_("netlink_audit_socket")
55 S_("netlink_ip6fw_socket")
56 S_("netlink_dnrt_socket")
57 S_(NULL)
58 S_(NULL)
59 S_("association")
60 S_("netlink_kobject_uevent_socket")
61 S_("appletalk_socket")
62 S_("packet")
63 S_("key")
64 S_(NULL)
65 S_("dccp_socket")
66 S_("memprotect")
67 S_(NULL)
68 S_(NULL)
69 S_(NULL)
70 S_(NULL)
71 S_(NULL)
72 S_(NULL)
73 S_("peer")
74 S_("capability2")
75 S_(NULL)
76 S_(NULL)
77 S_(NULL)
78 S_(NULL)
79 S_("kernel_service")
80 S_("tun_socket")
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
new file mode 100644
index 000000000000..8b32e959bb2e
--- /dev/null
+++ b/security/selinux/include/classmap.h
@@ -0,0 +1,150 @@
1#define COMMON_FILE_SOCK_PERMS "ioctl", "read", "write", "create", \
2 "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append"
3
4#define COMMON_FILE_PERMS COMMON_FILE_SOCK_PERMS, "unlink", "link", \
5 "rename", "execute", "swapon", "quotaon", "mounton"
6
7#define COMMON_SOCK_PERMS COMMON_FILE_SOCK_PERMS, "bind", "connect", \
8 "listen", "accept", "getopt", "setopt", "shutdown", "recvfrom", \
9 "sendto", "recv_msg", "send_msg", "name_bind"
10
11#define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \
12 "write", "associate", "unix_read", "unix_write"
13
14struct security_class_mapping secclass_map[] = {
15 { "security",
16 { "compute_av", "compute_create", "compute_member",
17 "check_context", "load_policy", "compute_relabel",
18 "compute_user", "setenforce", "setbool", "setsecparam",
19 "setcheckreqprot", NULL } },
20 { "process",
21 { "fork", "transition", "sigchld", "sigkill",
22 "sigstop", "signull", "signal", "ptrace", "getsched", "setsched",
23 "getsession", "getpgid", "setpgid", "getcap", "setcap", "share",
24 "getattr", "setexec", "setfscreate", "noatsecure", "siginh",
25 "setrlimit", "rlimitinh", "dyntransition", "setcurrent",
26 "execmem", "execstack", "execheap", "setkeycreate",
27 "setsockcreate", NULL } },
28 { "system",
29 { "ipc_info", "syslog_read", "syslog_mod",
30 "syslog_console", "module_request", NULL } },
31 { "capability",
32 { "chown", "dac_override", "dac_read_search",
33 "fowner", "fsetid", "kill", "setgid", "setuid", "setpcap",
34 "linux_immutable", "net_bind_service", "net_broadcast",
35 "net_admin", "net_raw", "ipc_lock", "ipc_owner", "sys_module",
36 "sys_rawio", "sys_chroot", "sys_ptrace", "sys_pacct", "sys_admin",
37 "sys_boot", "sys_nice", "sys_resource", "sys_time",
38 "sys_tty_config", "mknod", "lease", "audit_write",
39 "audit_control", "setfcap", NULL } },
40 { "filesystem",
41 { "mount", "remount", "unmount", "getattr",
42 "relabelfrom", "relabelto", "transition", "associate", "quotamod",
43 "quotaget", NULL } },
44 { "file",
45 { COMMON_FILE_PERMS,
46 "execute_no_trans", "entrypoint", "execmod", "open", NULL } },
47 { "dir",
48 { COMMON_FILE_PERMS, "add_name", "remove_name",
49 "reparent", "search", "rmdir", "open", NULL } },
50 { "fd", { "use", NULL } },
51 { "lnk_file",
52 { COMMON_FILE_PERMS, NULL } },
53 { "chr_file",
54 { COMMON_FILE_PERMS,
55 "execute_no_trans", "entrypoint", "execmod", "open", NULL } },
56 { "blk_file",
57 { COMMON_FILE_PERMS, "open", NULL } },
58 { "sock_file",
59 { COMMON_FILE_PERMS, "open", NULL } },
60 { "fifo_file",
61 { COMMON_FILE_PERMS, "open", NULL } },
62 { "socket",
63 { COMMON_SOCK_PERMS, NULL } },
64 { "tcp_socket",
65 { COMMON_SOCK_PERMS,
66 "connectto", "newconn", "acceptfrom", "node_bind", "name_connect",
67 NULL } },
68 { "udp_socket",
69 { COMMON_SOCK_PERMS,
70 "node_bind", NULL } },
71 { "rawip_socket",
72 { COMMON_SOCK_PERMS,
73 "node_bind", NULL } },
74 { "node",
75 { "tcp_recv", "tcp_send", "udp_recv", "udp_send",
76 "rawip_recv", "rawip_send", "enforce_dest",
77 "dccp_recv", "dccp_send", "recvfrom", "sendto", NULL } },
78 { "netif",
79 { "tcp_recv", "tcp_send", "udp_recv", "udp_send",
80 "rawip_recv", "rawip_send", "dccp_recv", "dccp_send",
81 "ingress", "egress", NULL } },
82 { "netlink_socket",
83 { COMMON_SOCK_PERMS, NULL } },
84 { "packet_socket",
85 { COMMON_SOCK_PERMS, NULL } },
86 { "key_socket",
87 { COMMON_SOCK_PERMS, NULL } },
88 { "unix_stream_socket",
89 { COMMON_SOCK_PERMS, "connectto", "newconn", "acceptfrom", NULL
90 } },
91 { "unix_dgram_socket",
92 { COMMON_SOCK_PERMS, NULL
93 } },
94 { "sem",
95 { COMMON_IPC_PERMS, NULL } },
96 { "msg", { "send", "receive", NULL } },
97 { "msgq",
98 { COMMON_IPC_PERMS, "enqueue", NULL } },
99 { "shm",
100 { COMMON_IPC_PERMS, "lock", NULL } },
101 { "ipc",
102 { COMMON_IPC_PERMS, NULL } },
103 { "netlink_route_socket",
104 { COMMON_SOCK_PERMS,
105 "nlmsg_read", "nlmsg_write", NULL } },
106 { "netlink_firewall_socket",
107 { COMMON_SOCK_PERMS,
108 "nlmsg_read", "nlmsg_write", NULL } },
109 { "netlink_tcpdiag_socket",
110 { COMMON_SOCK_PERMS,
111 "nlmsg_read", "nlmsg_write", NULL } },
112 { "netlink_nflog_socket",
113 { COMMON_SOCK_PERMS, NULL } },
114 { "netlink_xfrm_socket",
115 { COMMON_SOCK_PERMS,
116 "nlmsg_read", "nlmsg_write", NULL } },
117 { "netlink_selinux_socket",
118 { COMMON_SOCK_PERMS, NULL } },
119 { "netlink_audit_socket",
120 { COMMON_SOCK_PERMS,
121 "nlmsg_read", "nlmsg_write", "nlmsg_relay", "nlmsg_readpriv",
122 "nlmsg_tty_audit", NULL } },
123 { "netlink_ip6fw_socket",
124 { COMMON_SOCK_PERMS,
125 "nlmsg_read", "nlmsg_write", NULL } },
126 { "netlink_dnrt_socket",
127 { COMMON_SOCK_PERMS, NULL } },
128 { "association",
129 { "sendto", "recvfrom", "setcontext", "polmatch", NULL } },
130 { "netlink_kobject_uevent_socket",
131 { COMMON_SOCK_PERMS, NULL } },
132 { "appletalk_socket",
133 { COMMON_SOCK_PERMS, NULL } },
134 { "packet",
135 { "send", "recv", "relabelto", "flow_in", "flow_out",
136 "forward_in", "forward_out", NULL } },
137 { "key",
138 { "view", "read", "write", "search", "link", "setattr", "create",
139 NULL } },
140 { "dccp_socket",
141 { COMMON_SOCK_PERMS,
142 "node_bind", "name_connect", NULL } },
143 { "memprotect", { "mmap_zero", NULL } },
144 { "peer", { "recv", NULL } },
145 { "capability2", { "mac_override", "mac_admin", NULL } },
146 { "kernel_service", { "use_as_override", "create_files_as", NULL } },
147 { "tun_socket",
148 { COMMON_SOCK_PERMS, NULL } },
149 { NULL }
150 };
diff --git a/security/selinux/include/common_perm_to_string.h b/security/selinux/include/common_perm_to_string.h
deleted file mode 100644
index ce5b6e2fe9dd..000000000000
--- a/security/selinux/include/common_perm_to_string.h
+++ /dev/null
@@ -1,58 +0,0 @@
1/* This file is automatically generated. Do not edit. */
2TB_(common_file_perm_to_string)
3 S_("ioctl")
4 S_("read")
5 S_("write")
6 S_("create")
7 S_("getattr")
8 S_("setattr")
9 S_("lock")
10 S_("relabelfrom")
11 S_("relabelto")
12 S_("append")
13 S_("unlink")
14 S_("link")
15 S_("rename")
16 S_("execute")
17 S_("swapon")
18 S_("quotaon")
19 S_("mounton")
20TE_(common_file_perm_to_string)
21
22TB_(common_socket_perm_to_string)
23 S_("ioctl")
24 S_("read")
25 S_("write")
26 S_("create")
27 S_("getattr")
28 S_("setattr")
29 S_("lock")
30 S_("relabelfrom")
31 S_("relabelto")
32 S_("append")
33 S_("bind")
34 S_("connect")
35 S_("listen")
36 S_("accept")
37 S_("getopt")
38 S_("setopt")
39 S_("shutdown")
40 S_("recvfrom")
41 S_("sendto")
42 S_("recv_msg")
43 S_("send_msg")
44 S_("name_bind")
45TE_(common_socket_perm_to_string)
46
47TB_(common_ipc_perm_to_string)
48 S_("create")
49 S_("destroy")
50 S_("getattr")
51 S_("setattr")
52 S_("read")
53 S_("write")
54 S_("associate")
55 S_("unix_read")
56 S_("unix_write")
57TE_(common_ipc_perm_to_string)
58
diff --git a/security/selinux/include/flask.h b/security/selinux/include/flask.h
deleted file mode 100644
index f248500a1e3c..000000000000
--- a/security/selinux/include/flask.h
+++ /dev/null
@@ -1,91 +0,0 @@
1/* This file is automatically generated. Do not edit. */
2#ifndef _SELINUX_FLASK_H_
3#define _SELINUX_FLASK_H_
4
5/*
6 * Security object class definitions
7 */
8#define SECCLASS_SECURITY 1
9#define SECCLASS_PROCESS 2
10#define SECCLASS_SYSTEM 3
11#define SECCLASS_CAPABILITY 4
12#define SECCLASS_FILESYSTEM 5
13#define SECCLASS_FILE 6
14#define SECCLASS_DIR 7
15#define SECCLASS_FD 8
16#define SECCLASS_LNK_FILE 9
17#define SECCLASS_CHR_FILE 10
18#define SECCLASS_BLK_FILE 11
19#define SECCLASS_SOCK_FILE 12
20#define SECCLASS_FIFO_FILE 13
21#define SECCLASS_SOCKET 14
22#define SECCLASS_TCP_SOCKET 15
23#define SECCLASS_UDP_SOCKET 16
24#define SECCLASS_RAWIP_SOCKET 17
25#define SECCLASS_NODE 18
26#define SECCLASS_NETIF 19
27#define SECCLASS_NETLINK_SOCKET 20
28#define SECCLASS_PACKET_SOCKET 21
29#define SECCLASS_KEY_SOCKET 22
30#define SECCLASS_UNIX_STREAM_SOCKET 23
31#define SECCLASS_UNIX_DGRAM_SOCKET 24
32#define SECCLASS_SEM 25
33#define SECCLASS_MSG 26
34#define SECCLASS_MSGQ 27
35#define SECCLASS_SHM 28
36#define SECCLASS_IPC 29
37#define SECCLASS_NETLINK_ROUTE_SOCKET 43
38#define SECCLASS_NETLINK_FIREWALL_SOCKET 44
39#define SECCLASS_NETLINK_TCPDIAG_SOCKET 45
40#define SECCLASS_NETLINK_NFLOG_SOCKET 46
41#define SECCLASS_NETLINK_XFRM_SOCKET 47
42#define SECCLASS_NETLINK_SELINUX_SOCKET 48
43#define SECCLASS_NETLINK_AUDIT_SOCKET 49
44#define SECCLASS_NETLINK_IP6FW_SOCKET 50
45#define SECCLASS_NETLINK_DNRT_SOCKET 51
46#define SECCLASS_ASSOCIATION 54
47#define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET 55
48#define SECCLASS_APPLETALK_SOCKET 56
49#define SECCLASS_PACKET 57
50#define SECCLASS_KEY 58
51#define SECCLASS_DCCP_SOCKET 60
52#define SECCLASS_MEMPROTECT 61
53#define SECCLASS_PEER 68
54#define SECCLASS_CAPABILITY2 69
55#define SECCLASS_KERNEL_SERVICE 74
56#define SECCLASS_TUN_SOCKET 75
57
58/*
59 * Security identifier indices for initial entities
60 */
61#define SECINITSID_KERNEL 1
62#define SECINITSID_SECURITY 2
63#define SECINITSID_UNLABELED 3
64#define SECINITSID_FS 4
65#define SECINITSID_FILE 5
66#define SECINITSID_FILE_LABELS 6
67#define SECINITSID_INIT 7
68#define SECINITSID_ANY_SOCKET 8
69#define SECINITSID_PORT 9
70#define SECINITSID_NETIF 10
71#define SECINITSID_NETMSG 11
72#define SECINITSID_NODE 12
73#define SECINITSID_IGMP_PACKET 13
74#define SECINITSID_ICMP_SOCKET 14
75#define SECINITSID_TCP_SOCKET 15
76#define SECINITSID_SYSCTL_MODPROBE 16
77#define SECINITSID_SYSCTL 17
78#define SECINITSID_SYSCTL_FS 18
79#define SECINITSID_SYSCTL_KERNEL 19
80#define SECINITSID_SYSCTL_NET 20
81#define SECINITSID_SYSCTL_NET_UNIX 21
82#define SECINITSID_SYSCTL_VM 22
83#define SECINITSID_SYSCTL_DEV 23
84#define SECINITSID_KMOD 24
85#define SECINITSID_POLICY 25
86#define SECINITSID_SCMP_PACKET 26
87#define SECINITSID_DEVNULL 27
88
89#define SECINITSID_NUM 27
90
91#endif
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index ca835795a8b3..1f7c2491d3dc 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -57,7 +57,6 @@
57struct netlbl_lsm_secattr; 57struct netlbl_lsm_secattr;
58 58
59extern int selinux_enabled; 59extern int selinux_enabled;
60extern int selinux_mls_enabled;
61 60
62/* Policy capabilities */ 61/* Policy capabilities */
63enum { 62enum {
@@ -80,6 +79,8 @@ extern int selinux_policycap_openperm;
80/* limitation of boundary depth */ 79/* limitation of boundary depth */
81#define POLICYDB_BOUNDS_MAXDEPTH 4 80#define POLICYDB_BOUNDS_MAXDEPTH 4
82 81
82int security_mls_enabled(void);
83
83int security_load_policy(void *data, size_t len); 84int security_load_policy(void *data, size_t len);
84 85
85int security_policycap_supported(unsigned int req_cap); 86int security_policycap_supported(unsigned int req_cap);
@@ -96,12 +97,17 @@ struct av_decision {
96/* definitions of av_decision.flags */ 97/* definitions of av_decision.flags */
97#define AVD_FLAGS_PERMISSIVE 0x0001 98#define AVD_FLAGS_PERMISSIVE 0x0001
98 99
99int security_compute_av(u32 ssid, u32 tsid, 100void security_compute_av(u32 ssid, u32 tsid,
100 u16 tclass, u32 requested, 101 u16 tclass, struct av_decision *avd);
101 struct av_decision *avd); 102
103void security_compute_av_user(u32 ssid, u32 tsid,
104 u16 tclass, struct av_decision *avd);
102 105
103int security_transition_sid(u32 ssid, u32 tsid, 106int security_transition_sid(u32 ssid, u32 tsid,
104 u16 tclass, u32 *out_sid); 107 u16 tclass, u32 *out_sid);
108
109int security_transition_sid_user(u32 ssid, u32 tsid,
110 u16 tclass, u32 *out_sid);
105 111
106int security_member_sid(u32 ssid, u32 tsid, 112int security_member_sid(u32 ssid, u32 tsid,
107 u16 tclass, u32 *out_sid); 113 u16 tclass, u32 *out_sid);
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index b4e14bc0bf32..d6095d63d831 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -16,6 +16,7 @@
16 */ 16 */
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/slab.h>
19#include <linux/stddef.h> 20#include <linux/stddef.h>
20#include <linux/kernel.h> 21#include <linux/kernel.h>
21#include <linux/list.h> 22#include <linux/list.h>
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index e68823741ad5..628da72ee763 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -29,6 +29,7 @@
29 29
30#include <linux/spinlock.h> 30#include <linux/spinlock.h>
31#include <linux/rcupdate.h> 31#include <linux/rcupdate.h>
32#include <linux/gfp.h>
32#include <linux/ip.h> 33#include <linux/ip.h>
33#include <linux/ipv6.h> 34#include <linux/ipv6.h>
34#include <net/sock.h> 35#include <net/sock.h>
@@ -204,7 +205,7 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
204 * 205 *
205 * Description 206 * Description
206 * Call the NetLabel mechanism to set the label of a packet using @sid. 207 * Call the NetLabel mechanism to set the label of a packet using @sid.
207 * Returns zero on auccess, negative values on failure. 208 * Returns zero on success, negative values on failure.
208 * 209 *
209 */ 210 */
210int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, 211int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,
diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c
index 1ae556446e65..0e147b6914ad 100644
--- a/security/selinux/netlink.c
+++ b/security/selinux/netlink.c
@@ -11,6 +11,7 @@
11 */ 11 */
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/slab.h>
14#include <linux/stddef.h> 15#include <linux/stddef.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/list.h> 17#include <linux/list.h>
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index 7100072bb1b0..dc92792271f1 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -31,6 +31,7 @@
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/rcupdate.h> 32#include <linux/rcupdate.h>
33#include <linux/list.h> 33#include <linux/list.h>
34#include <linux/slab.h>
34#include <linux/spinlock.h> 35#include <linux/spinlock.h>
35#include <linux/in.h> 36#include <linux/in.h>
36#include <linux/in6.h> 37#include <linux/in6.h>
diff --git a/security/selinux/netport.c b/security/selinux/netport.c
index fe7fba67f19f..cfe2d72d3fb7 100644
--- a/security/selinux/netport.c
+++ b/security/selinux/netport.c
@@ -30,6 +30,7 @@
30#include <linux/types.h> 30#include <linux/types.h>
31#include <linux/rcupdate.h> 31#include <linux/rcupdate.h>
32#include <linux/list.h> 32#include <linux/list.h>
33#include <linux/slab.h>
33#include <linux/spinlock.h> 34#include <linux/spinlock.h>
34#include <linux/in.h> 35#include <linux/in.h>
35#include <linux/in6.h> 36#include <linux/in6.h>
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index b4fc506e7a87..cd191bbec03c 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -282,7 +282,8 @@ static ssize_t sel_read_mls(struct file *filp, char __user *buf,
282 char tmpbuf[TMPBUFLEN]; 282 char tmpbuf[TMPBUFLEN];
283 ssize_t length; 283 ssize_t length;
284 284
285 length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled); 285 length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
286 security_mls_enabled());
286 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); 287 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
287} 288}
288 289
@@ -494,7 +495,6 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
494 char *scon, *tcon; 495 char *scon, *tcon;
495 u32 ssid, tsid; 496 u32 ssid, tsid;
496 u16 tclass; 497 u16 tclass;
497 u32 req;
498 struct av_decision avd; 498 struct av_decision avd;
499 ssize_t length; 499 ssize_t length;
500 500
@@ -512,7 +512,7 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
512 goto out; 512 goto out;
513 513
514 length = -EINVAL; 514 length = -EINVAL;
515 if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4) 515 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
516 goto out2; 516 goto out2;
517 517
518 length = security_context_to_sid(scon, strlen(scon)+1, &ssid); 518 length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
@@ -522,9 +522,7 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
522 if (length < 0) 522 if (length < 0)
523 goto out2; 523 goto out2;
524 524
525 length = security_compute_av(ssid, tsid, tclass, req, &avd); 525 security_compute_av_user(ssid, tsid, tclass, &avd);
526 if (length < 0)
527 goto out2;
528 526
529 length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, 527 length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
530 "%x %x %x %x %u %x", 528 "%x %x %x %x %u %x",
@@ -571,7 +569,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
571 if (length < 0) 569 if (length < 0)
572 goto out2; 570 goto out2;
573 571
574 length = security_transition_sid(ssid, tsid, tclass, &newsid); 572 length = security_transition_sid_user(ssid, tsid, tclass, &newsid);
575 if (length < 0) 573 if (length < 0)
576 goto out2; 574 goto out2;
577 575
@@ -979,6 +977,8 @@ static int sel_make_bools(void)
979 u32 sid; 977 u32 sid;
980 978
981 /* remove any existing files */ 979 /* remove any existing files */
980 for (i = 0; i < bool_num; i++)
981 kfree(bool_pending_names[i]);
982 kfree(bool_pending_names); 982 kfree(bool_pending_names);
983 kfree(bool_pending_values); 983 kfree(bool_pending_values);
984 bool_pending_names = NULL; 984 bool_pending_names = NULL;
diff --git a/security/selinux/ss/Makefile b/security/selinux/ss/Makefile
index bad78779b9b0..15d4e62917de 100644
--- a/security/selinux/ss/Makefile
+++ b/security/selinux/ss/Makefile
@@ -2,7 +2,7 @@
2# Makefile for building the SELinux security server as part of the kernel tree. 2# Makefile for building the SELinux security server as part of the kernel tree.
3# 3#
4 4
5EXTRA_CFLAGS += -Isecurity/selinux/include 5EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include
6obj-y := ss.o 6obj-y := ss.o
7 7
8ss-y := ebitmap.o hashtab.o symtab.o sidtab.o avtab.o policydb.o services.o conditional.o mls.o 8ss-y := ebitmap.o hashtab.o symtab.o sidtab.o avtab.o policydb.o services.o conditional.o mls.o
diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h
index 8da6a8428086..cd4f734e2749 100644
--- a/security/selinux/ss/avtab.h
+++ b/security/selinux/ss/avtab.h
@@ -82,7 +82,7 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified
82void avtab_cache_init(void); 82void avtab_cache_init(void);
83void avtab_cache_destroy(void); 83void avtab_cache_destroy(void);
84 84
85#define MAX_AVTAB_HASH_BITS 13 85#define MAX_AVTAB_HASH_BITS 11
86#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) 86#define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS)
87#define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1) 87#define MAX_AVTAB_HASH_MASK (MAX_AVTAB_HASH_BUCKETS-1)
88#define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS 88#define MAX_AVTAB_SIZE MAX_AVTAB_HASH_BUCKETS
diff --git a/security/selinux/ss/context.h b/security/selinux/ss/context.h
index d9dd7a2f6a8a..45e8fb0515f8 100644
--- a/security/selinux/ss/context.h
+++ b/security/selinux/ss/context.h
@@ -41,9 +41,6 @@ static inline int mls_context_cpy(struct context *dst, struct context *src)
41{ 41{
42 int rc; 42 int rc;
43 43
44 if (!selinux_mls_enabled)
45 return 0;
46
47 dst->range.level[0].sens = src->range.level[0].sens; 44 dst->range.level[0].sens = src->range.level[0].sens;
48 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat); 45 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
49 if (rc) 46 if (rc)
@@ -64,9 +61,6 @@ static inline int mls_context_cpy_low(struct context *dst, struct context *src)
64{ 61{
65 int rc; 62 int rc;
66 63
67 if (!selinux_mls_enabled)
68 return 0;
69
70 dst->range.level[0].sens = src->range.level[0].sens; 64 dst->range.level[0].sens = src->range.level[0].sens;
71 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat); 65 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
72 if (rc) 66 if (rc)
@@ -82,9 +76,6 @@ out:
82 76
83static inline int mls_context_cmp(struct context *c1, struct context *c2) 77static inline int mls_context_cmp(struct context *c1, struct context *c2)
84{ 78{
85 if (!selinux_mls_enabled)
86 return 1;
87
88 return ((c1->range.level[0].sens == c2->range.level[0].sens) && 79 return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
89 ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) && 80 ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
90 (c1->range.level[1].sens == c2->range.level[1].sens) && 81 (c1->range.level[1].sens == c2->range.level[1].sens) &&
@@ -93,9 +84,6 @@ static inline int mls_context_cmp(struct context *c1, struct context *c2)
93 84
94static inline void mls_context_destroy(struct context *c) 85static inline void mls_context_destroy(struct context *c)
95{ 86{
96 if (!selinux_mls_enabled)
97 return;
98
99 ebitmap_destroy(&c->range.level[0].cat); 87 ebitmap_destroy(&c->range.level[0].cat);
100 ebitmap_destroy(&c->range.level[1].cat); 88 ebitmap_destroy(&c->range.level[1].cat);
101 mls_context_init(c); 89 mls_context_init(c);
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 68c7348d1acc..04b6145d767f 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -128,7 +128,7 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap,
128 cmap_idx = delta / NETLBL_CATMAP_MAPSIZE; 128 cmap_idx = delta / NETLBL_CATMAP_MAPSIZE;
129 cmap_sft = delta % NETLBL_CATMAP_MAPSIZE; 129 cmap_sft = delta % NETLBL_CATMAP_MAPSIZE;
130 c_iter->bitmap[cmap_idx] 130 c_iter->bitmap[cmap_idx]
131 |= e_iter->maps[cmap_idx] << cmap_sft; 131 |= e_iter->maps[i] << cmap_sft;
132 } 132 }
133 e_iter = e_iter->next; 133 e_iter = e_iter->next;
134 } 134 }
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index b5407f16c2a4..372b773f8210 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -39,7 +39,7 @@ int mls_compute_context_len(struct context *context)
39 struct ebitmap *e; 39 struct ebitmap *e;
40 struct ebitmap_node *node; 40 struct ebitmap_node *node;
41 41
42 if (!selinux_mls_enabled) 42 if (!policydb.mls_enabled)
43 return 0; 43 return 0;
44 44
45 len = 1; /* for the beginning ":" */ 45 len = 1; /* for the beginning ":" */
@@ -93,7 +93,7 @@ void mls_sid_to_context(struct context *context,
93 struct ebitmap *e; 93 struct ebitmap *e;
94 struct ebitmap_node *node; 94 struct ebitmap_node *node;
95 95
96 if (!selinux_mls_enabled) 96 if (!policydb.mls_enabled)
97 return; 97 return;
98 98
99 scontextp = *scontext; 99 scontextp = *scontext;
@@ -200,7 +200,7 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
200{ 200{
201 struct user_datum *usrdatum; 201 struct user_datum *usrdatum;
202 202
203 if (!selinux_mls_enabled) 203 if (!p->mls_enabled)
204 return 1; 204 return 1;
205 205
206 if (!mls_range_isvalid(p, &c->range)) 206 if (!mls_range_isvalid(p, &c->range))
@@ -253,7 +253,7 @@ int mls_context_to_sid(struct policydb *pol,
253 struct cat_datum *catdatum, *rngdatum; 253 struct cat_datum *catdatum, *rngdatum;
254 int l, rc = -EINVAL; 254 int l, rc = -EINVAL;
255 255
256 if (!selinux_mls_enabled) { 256 if (!pol->mls_enabled) {
257 if (def_sid != SECSID_NULL && oldc) 257 if (def_sid != SECSID_NULL && oldc)
258 *scontext += strlen(*scontext)+1; 258 *scontext += strlen(*scontext)+1;
259 return 0; 259 return 0;
@@ -387,7 +387,7 @@ int mls_from_string(char *str, struct context *context, gfp_t gfp_mask)
387 char *tmpstr, *freestr; 387 char *tmpstr, *freestr;
388 int rc; 388 int rc;
389 389
390 if (!selinux_mls_enabled) 390 if (!policydb.mls_enabled)
391 return -EINVAL; 391 return -EINVAL;
392 392
393 /* we need freestr because mls_context_to_sid will change 393 /* we need freestr because mls_context_to_sid will change
@@ -407,7 +407,7 @@ int mls_from_string(char *str, struct context *context, gfp_t gfp_mask)
407/* 407/*
408 * Copies the MLS range `range' into `context'. 408 * Copies the MLS range `range' into `context'.
409 */ 409 */
410static inline int mls_range_set(struct context *context, 410int mls_range_set(struct context *context,
411 struct mls_range *range) 411 struct mls_range *range)
412{ 412{
413 int l, rc = 0; 413 int l, rc = 0;
@@ -427,7 +427,7 @@ static inline int mls_range_set(struct context *context,
427int mls_setup_user_range(struct context *fromcon, struct user_datum *user, 427int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
428 struct context *usercon) 428 struct context *usercon)
429{ 429{
430 if (selinux_mls_enabled) { 430 if (policydb.mls_enabled) {
431 struct mls_level *fromcon_sen = &(fromcon->range.level[0]); 431 struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
432 struct mls_level *fromcon_clr = &(fromcon->range.level[1]); 432 struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
433 struct mls_level *user_low = &(user->range.level[0]); 433 struct mls_level *user_low = &(user->range.level[0]);
@@ -477,7 +477,7 @@ int mls_convert_context(struct policydb *oldp,
477 struct ebitmap_node *node; 477 struct ebitmap_node *node;
478 int l, i; 478 int l, i;
479 479
480 if (!selinux_mls_enabled) 480 if (!policydb.mls_enabled)
481 return 0; 481 return 0;
482 482
483 for (l = 0; l < 2; l++) { 483 for (l = 0; l < 2; l++) {
@@ -513,26 +513,24 @@ int mls_compute_sid(struct context *scontext,
513 u32 specified, 513 u32 specified,
514 struct context *newcontext) 514 struct context *newcontext)
515{ 515{
516 struct range_trans *rtr; 516 struct range_trans rtr;
517 struct mls_range *r;
517 518
518 if (!selinux_mls_enabled) 519 if (!policydb.mls_enabled)
519 return 0; 520 return 0;
520 521
521 switch (specified) { 522 switch (specified) {
522 case AVTAB_TRANSITION: 523 case AVTAB_TRANSITION:
523 /* Look for a range transition rule. */ 524 /* Look for a range transition rule. */
524 for (rtr = policydb.range_tr; rtr; rtr = rtr->next) { 525 rtr.source_type = scontext->type;
525 if (rtr->source_type == scontext->type && 526 rtr.target_type = tcontext->type;
526 rtr->target_type == tcontext->type && 527 rtr.target_class = tclass;
527 rtr->target_class == tclass) { 528 r = hashtab_search(policydb.range_tr, &rtr);
528 /* Set the range from the rule */ 529 if (r)
529 return mls_range_set(newcontext, 530 return mls_range_set(newcontext, r);
530 &rtr->target_range);
531 }
532 }
533 /* Fallthrough */ 531 /* Fallthrough */
534 case AVTAB_CHANGE: 532 case AVTAB_CHANGE:
535 if (tclass == SECCLASS_PROCESS) 533 if (tclass == policydb.process_class)
536 /* Use the process MLS attributes. */ 534 /* Use the process MLS attributes. */
537 return mls_context_cpy(newcontext, scontext); 535 return mls_context_cpy(newcontext, scontext);
538 else 536 else
@@ -541,8 +539,8 @@ int mls_compute_sid(struct context *scontext,
541 case AVTAB_MEMBER: 539 case AVTAB_MEMBER:
542 /* Use the process effective MLS attributes. */ 540 /* Use the process effective MLS attributes. */
543 return mls_context_cpy_low(newcontext, scontext); 541 return mls_context_cpy_low(newcontext, scontext);
544 default: 542
545 return -EINVAL; 543 /* fall through */
546 } 544 }
547 return -EINVAL; 545 return -EINVAL;
548} 546}
@@ -561,7 +559,7 @@ int mls_compute_sid(struct context *scontext,
561void mls_export_netlbl_lvl(struct context *context, 559void mls_export_netlbl_lvl(struct context *context,
562 struct netlbl_lsm_secattr *secattr) 560 struct netlbl_lsm_secattr *secattr)
563{ 561{
564 if (!selinux_mls_enabled) 562 if (!policydb.mls_enabled)
565 return; 563 return;
566 564
567 secattr->attr.mls.lvl = context->range.level[0].sens - 1; 565 secattr->attr.mls.lvl = context->range.level[0].sens - 1;
@@ -581,7 +579,7 @@ void mls_export_netlbl_lvl(struct context *context,
581void mls_import_netlbl_lvl(struct context *context, 579void mls_import_netlbl_lvl(struct context *context,
582 struct netlbl_lsm_secattr *secattr) 580 struct netlbl_lsm_secattr *secattr)
583{ 581{
584 if (!selinux_mls_enabled) 582 if (!policydb.mls_enabled)
585 return; 583 return;
586 584
587 context->range.level[0].sens = secattr->attr.mls.lvl + 1; 585 context->range.level[0].sens = secattr->attr.mls.lvl + 1;
@@ -603,7 +601,7 @@ int mls_export_netlbl_cat(struct context *context,
603{ 601{
604 int rc; 602 int rc;
605 603
606 if (!selinux_mls_enabled) 604 if (!policydb.mls_enabled)
607 return 0; 605 return 0;
608 606
609 rc = ebitmap_netlbl_export(&context->range.level[0].cat, 607 rc = ebitmap_netlbl_export(&context->range.level[0].cat,
@@ -631,7 +629,7 @@ int mls_import_netlbl_cat(struct context *context,
631{ 629{
632 int rc; 630 int rc;
633 631
634 if (!selinux_mls_enabled) 632 if (!policydb.mls_enabled)
635 return 0; 633 return 0;
636 634
637 rc = ebitmap_netlbl_import(&context->range.level[0].cat, 635 rc = ebitmap_netlbl_import(&context->range.level[0].cat,
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
index 1276715aaa8b..cd9152632e54 100644
--- a/security/selinux/ss/mls.h
+++ b/security/selinux/ss/mls.h
@@ -39,6 +39,8 @@ int mls_context_to_sid(struct policydb *p,
39 39
40int mls_from_string(char *str, struct context *context, gfp_t gfp_mask); 40int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);
41 41
42int mls_range_set(struct context *context, struct mls_range *range);
43
42int mls_convert_context(struct policydb *oldp, 44int mls_convert_context(struct policydb *oldp,
43 struct policydb *newp, 45 struct policydb *newp,
44 struct context *context); 46 struct context *context);
diff --git a/security/selinux/ss/mls_types.h b/security/selinux/ss/mls_types.h
index b6e943a21061..03bed52a8052 100644
--- a/security/selinux/ss/mls_types.h
+++ b/security/selinux/ss/mls_types.h
@@ -15,6 +15,7 @@
15#define _SS_MLS_TYPES_H_ 15#define _SS_MLS_TYPES_H_
16 16
17#include "security.h" 17#include "security.h"
18#include "ebitmap.h"
18 19
19struct mls_level { 20struct mls_level {
20 u32 sens; /* sensitivity */ 21 u32 sens; /* sensitivity */
@@ -27,18 +28,12 @@ struct mls_range {
27 28
28static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2) 29static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
29{ 30{
30 if (!selinux_mls_enabled)
31 return 1;
32
33 return ((l1->sens == l2->sens) && 31 return ((l1->sens == l2->sens) &&
34 ebitmap_cmp(&l1->cat, &l2->cat)); 32 ebitmap_cmp(&l1->cat, &l2->cat));
35} 33}
36 34
37static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) 35static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
38{ 36{
39 if (!selinux_mls_enabled)
40 return 1;
41
42 return ((l1->sens >= l2->sens) && 37 return ((l1->sens >= l2->sens) &&
43 ebitmap_contains(&l1->cat, &l2->cat)); 38 ebitmap_contains(&l1->cat, &l2->cat));
44} 39}
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 72e4a54973aa..23c6e53c102c 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -52,8 +52,6 @@ static char *symtab_name[SYM_NUM] = {
52}; 52};
53#endif 53#endif
54 54
55int selinux_mls_enabled;
56
57static unsigned int symtab_sizes[SYM_NUM] = { 55static unsigned int symtab_sizes[SYM_NUM] = {
58 2, 56 2,
59 32, 57 32,
@@ -177,6 +175,21 @@ out_free_role:
177 goto out; 175 goto out;
178} 176}
179 177
178static u32 rangetr_hash(struct hashtab *h, const void *k)
179{
180 const struct range_trans *key = k;
181 return (key->source_type + (key->target_type << 3) +
182 (key->target_class << 5)) & (h->size - 1);
183}
184
185static int rangetr_cmp(struct hashtab *h, const void *k1, const void *k2)
186{
187 const struct range_trans *key1 = k1, *key2 = k2;
188 return (key1->source_type != key2->source_type ||
189 key1->target_type != key2->target_type ||
190 key1->target_class != key2->target_class);
191}
192
180/* 193/*
181 * Initialize a policy database structure. 194 * Initialize a policy database structure.
182 */ 195 */
@@ -204,6 +217,10 @@ static int policydb_init(struct policydb *p)
204 if (rc) 217 if (rc)
205 goto out_free_symtab; 218 goto out_free_symtab;
206 219
220 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
221 if (!p->range_tr)
222 goto out_free_symtab;
223
207 ebitmap_init(&p->policycaps); 224 ebitmap_init(&p->policycaps);
208 ebitmap_init(&p->permissive_map); 225 ebitmap_init(&p->permissive_map);
209 226
@@ -408,6 +425,20 @@ static void symtab_hash_eval(struct symtab *s)
408 info.slots_used, h->size, info.max_chain_len); 425 info.slots_used, h->size, info.max_chain_len);
409 } 426 }
410} 427}
428
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
439static inline void rangetr_hash_eval(struct hashtab *h)
440{
441}
411#endif 442#endif
412 443
413/* 444/*
@@ -422,7 +453,7 @@ static int policydb_index_others(struct policydb *p)
422 453
423 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools", 454 printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools",
424 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); 455 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
425 if (selinux_mls_enabled) 456 if (p->mls_enabled)
426 printk(", %d sens, %d cats", p->p_levels.nprim, 457 printk(", %d sens, %d cats", p->p_levels.nprim,
427 p->p_cats.nprim); 458 p->p_cats.nprim);
428 printk("\n"); 459 printk("\n");
@@ -612,6 +643,17 @@ static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) =
612 cat_destroy, 643 cat_destroy,
613}; 644};
614 645
646static int range_tr_destroy(void *key, void *datum, void *p)
647{
648 struct mls_range *rt = datum;
649 kfree(key);
650 ebitmap_destroy(&rt->level[0].cat);
651 ebitmap_destroy(&rt->level[1].cat);
652 kfree(datum);
653 cond_resched();
654 return 0;
655}
656
615static void ocontext_destroy(struct ocontext *c, int i) 657static void ocontext_destroy(struct ocontext *c, int i)
616{ 658{
617 context_destroy(&c->context[0]); 659 context_destroy(&c->context[0]);
@@ -632,7 +674,6 @@ void policydb_destroy(struct policydb *p)
632 int i; 674 int i;
633 struct role_allow *ra, *lra = NULL; 675 struct role_allow *ra, *lra = NULL;
634 struct role_trans *tr, *ltr = NULL; 676 struct role_trans *tr, *ltr = NULL;
635 struct range_trans *rt, *lrt = NULL;
636 677
637 for (i = 0; i < SYM_NUM; i++) { 678 for (i = 0; i < SYM_NUM; i++) {
638 cond_resched(); 679 cond_resched();
@@ -693,27 +734,14 @@ void policydb_destroy(struct policydb *p)
693 } 734 }
694 kfree(lra); 735 kfree(lra);
695 736
696 for (rt = p->range_tr; rt; rt = rt->next) { 737 hashtab_map(p->range_tr, range_tr_destroy, NULL);
697 cond_resched(); 738 hashtab_destroy(p->range_tr);
698 if (lrt) {
699 ebitmap_destroy(&lrt->target_range.level[0].cat);
700 ebitmap_destroy(&lrt->target_range.level[1].cat);
701 kfree(lrt);
702 }
703 lrt = rt;
704 }
705 if (lrt) {
706 ebitmap_destroy(&lrt->target_range.level[0].cat);
707 ebitmap_destroy(&lrt->target_range.level[1].cat);
708 kfree(lrt);
709 }
710 739
711 if (p->type_attr_map) { 740 if (p->type_attr_map) {
712 for (i = 0; i < p->p_types.nprim; i++) 741 for (i = 0; i < p->p_types.nprim; i++)
713 ebitmap_destroy(&p->type_attr_map[i]); 742 ebitmap_destroy(&p->type_attr_map[i]);
714 } 743 }
715 kfree(p->type_attr_map); 744 kfree(p->type_attr_map);
716 kfree(p->undefined_perms);
717 ebitmap_destroy(&p->policycaps); 745 ebitmap_destroy(&p->policycaps);
718 ebitmap_destroy(&p->permissive_map); 746 ebitmap_destroy(&p->permissive_map);
719 747
@@ -1640,6 +1668,40 @@ static int policydb_bounds_sanity_check(struct policydb *p)
1640 1668
1641extern int ss_initialized; 1669extern int ss_initialized;
1642 1670
1671u16 string_to_security_class(struct policydb *p, const char *name)
1672{
1673 struct class_datum *cladatum;
1674
1675 cladatum = hashtab_search(p->p_classes.table, name);
1676 if (!cladatum)
1677 return 0;
1678
1679 return cladatum->value;
1680}
1681
1682u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name)
1683{
1684 struct class_datum *cladatum;
1685 struct perm_datum *perdatum = NULL;
1686 struct common_datum *comdatum;
1687
1688 if (!tclass || tclass > p->p_classes.nprim)
1689 return 0;
1690
1691 cladatum = p->class_val_to_struct[tclass-1];
1692 comdatum = cladatum->comdatum;
1693 if (comdatum)
1694 perdatum = hashtab_search(comdatum->permissions.table,
1695 name);
1696 if (!perdatum)
1697 perdatum = hashtab_search(cladatum->permissions.table,
1698 name);
1699 if (!perdatum)
1700 return 0;
1701
1702 return 1U << (perdatum->value-1);
1703}
1704
1643/* 1705/*
1644 * Read the configuration data from a policy database binary 1706 * Read the configuration data from a policy database binary
1645 * representation file into a policy database structure. 1707 * representation file into a policy database structure.
@@ -1653,12 +1715,11 @@ int policydb_read(struct policydb *p, void *fp)
1653 int i, j, rc; 1715 int i, j, rc;
1654 __le32 buf[4]; 1716 __le32 buf[4];
1655 u32 nodebuf[8]; 1717 u32 nodebuf[8];
1656 u32 len, len2, config, nprim, nel, nel2; 1718 u32 len, len2, nprim, nel, nel2;
1657 char *policydb_str; 1719 char *policydb_str;
1658 struct policydb_compat_info *info; 1720 struct policydb_compat_info *info;
1659 struct range_trans *rt, *lrt; 1721 struct range_trans *rt;
1660 1722 struct mls_range *r;
1661 config = 0;
1662 1723
1663 rc = policydb_init(p); 1724 rc = policydb_init(p);
1664 if (rc) 1725 if (rc)
@@ -1707,7 +1768,7 @@ int policydb_read(struct policydb *p, void *fp)
1707 kfree(policydb_str); 1768 kfree(policydb_str);
1708 policydb_str = NULL; 1769 policydb_str = NULL;
1709 1770
1710 /* Read the version, config, and table sizes. */ 1771 /* Read the version and table sizes. */
1711 rc = next_entry(buf, fp, sizeof(u32)*4); 1772 rc = next_entry(buf, fp, sizeof(u32)*4);
1712 if (rc < 0) 1773 if (rc < 0)
1713 goto bad; 1774 goto bad;
@@ -1722,13 +1783,7 @@ int policydb_read(struct policydb *p, void *fp)
1722 } 1783 }
1723 1784
1724 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { 1785 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
1725 if (ss_initialized && !selinux_mls_enabled) { 1786 p->mls_enabled = 1;
1726 printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
1727 " and MLS policies\n");
1728 goto bad;
1729 }
1730 selinux_mls_enabled = 1;
1731 config |= POLICYDB_CONFIG_MLS;
1732 1787
1733 if (p->policyvers < POLICYDB_VERSION_MLS) { 1788 if (p->policyvers < POLICYDB_VERSION_MLS) {
1734 printk(KERN_ERR "SELinux: security policydb version %d " 1789 printk(KERN_ERR "SELinux: security policydb version %d "
@@ -1736,12 +1791,6 @@ int policydb_read(struct policydb *p, void *fp)
1736 p->policyvers); 1791 p->policyvers);
1737 goto bad; 1792 goto bad;
1738 } 1793 }
1739 } else {
1740 if (ss_initialized && selinux_mls_enabled) {
1741 printk(KERN_ERR "SELinux: Cannot switch between MLS and"
1742 " non-MLS policies\n");
1743 goto bad;
1744 }
1745 } 1794 }
1746 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); 1795 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
1747 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); 1796 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
@@ -1861,6 +1910,16 @@ int policydb_read(struct policydb *p, void *fp)
1861 if (rc) 1910 if (rc)
1862 goto bad; 1911 goto bad;
1863 1912
1913 p->process_class = string_to_security_class(p, "process");
1914 if (!p->process_class)
1915 goto bad;
1916 p->process_trans_perms = string_to_av_perm(p, p->process_class,
1917 "transition");
1918 p->process_trans_perms |= string_to_av_perm(p, p->process_class,
1919 "dyntransition");
1920 if (!p->process_trans_perms)
1921 goto bad;
1922
1864 for (i = 0; i < info->ocon_num; i++) { 1923 for (i = 0; i < info->ocon_num; i++) {
1865 rc = next_entry(buf, fp, sizeof(u32)); 1924 rc = next_entry(buf, fp, sizeof(u32));
1866 if (rc < 0) 1925 if (rc < 0)
@@ -2079,44 +2138,61 @@ int policydb_read(struct policydb *p, void *fp)
2079 if (rc < 0) 2138 if (rc < 0)
2080 goto bad; 2139 goto bad;
2081 nel = le32_to_cpu(buf[0]); 2140 nel = le32_to_cpu(buf[0]);
2082 lrt = NULL;
2083 for (i = 0; i < nel; i++) { 2141 for (i = 0; i < nel; i++) {
2084 rt = kzalloc(sizeof(*rt), GFP_KERNEL); 2142 rt = kzalloc(sizeof(*rt), GFP_KERNEL);
2085 if (!rt) { 2143 if (!rt) {
2086 rc = -ENOMEM; 2144 rc = -ENOMEM;
2087 goto bad; 2145 goto bad;
2088 } 2146 }
2089 if (lrt)
2090 lrt->next = rt;
2091 else
2092 p->range_tr = rt;
2093 rc = next_entry(buf, fp, (sizeof(u32) * 2)); 2147 rc = next_entry(buf, fp, (sizeof(u32) * 2));
2094 if (rc < 0) 2148 if (rc < 0) {
2149 kfree(rt);
2095 goto bad; 2150 goto bad;
2151 }
2096 rt->source_type = le32_to_cpu(buf[0]); 2152 rt->source_type = le32_to_cpu(buf[0]);
2097 rt->target_type = le32_to_cpu(buf[1]); 2153 rt->target_type = le32_to_cpu(buf[1]);
2098 if (new_rangetr) { 2154 if (new_rangetr) {
2099 rc = next_entry(buf, fp, sizeof(u32)); 2155 rc = next_entry(buf, fp, sizeof(u32));
2100 if (rc < 0) 2156 if (rc < 0) {
2157 kfree(rt);
2101 goto bad; 2158 goto bad;
2159 }
2102 rt->target_class = le32_to_cpu(buf[0]); 2160 rt->target_class = le32_to_cpu(buf[0]);
2103 } else 2161 } else
2104 rt->target_class = SECCLASS_PROCESS; 2162 rt->target_class = p->process_class;
2105 if (!policydb_type_isvalid(p, rt->source_type) || 2163 if (!policydb_type_isvalid(p, rt->source_type) ||
2106 !policydb_type_isvalid(p, rt->target_type) || 2164 !policydb_type_isvalid(p, rt->target_type) ||
2107 !policydb_class_isvalid(p, rt->target_class)) { 2165 !policydb_class_isvalid(p, rt->target_class)) {
2166 kfree(rt);
2108 rc = -EINVAL; 2167 rc = -EINVAL;
2109 goto bad; 2168 goto bad;
2110 } 2169 }
2111 rc = mls_read_range_helper(&rt->target_range, fp); 2170 r = kzalloc(sizeof(*r), GFP_KERNEL);
2112 if (rc) 2171 if (!r) {
2172 kfree(rt);
2173 rc = -ENOMEM;
2174 goto bad;
2175 }
2176 rc = mls_read_range_helper(r, fp);
2177 if (rc) {
2178 kfree(rt);
2179 kfree(r);
2113 goto bad; 2180 goto bad;
2114 if (!mls_range_isvalid(p, &rt->target_range)) { 2181 }
2182 if (!mls_range_isvalid(p, r)) {
2115 printk(KERN_WARNING "SELinux: rangetrans: invalid range\n"); 2183 printk(KERN_WARNING "SELinux: rangetrans: invalid range\n");
2184 kfree(rt);
2185 kfree(r);
2186 goto bad;
2187 }
2188 rc = hashtab_insert(p->range_tr, rt, r);
2189 if (rc) {
2190 kfree(rt);
2191 kfree(r);
2116 goto bad; 2192 goto bad;
2117 } 2193 }
2118 lrt = rt;
2119 } 2194 }
2195 rangetr_hash_eval(p->range_tr);
2120 } 2196 }
2121 2197
2122 p->type_attr_map = kmalloc(p->p_types.nprim*sizeof(struct ebitmap), GFP_KERNEL); 2198 p->type_attr_map = kmalloc(p->p_types.nprim*sizeof(struct ebitmap), GFP_KERNEL);
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 55152d498b53..26d9adf8542b 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -27,6 +27,8 @@
27#include "symtab.h" 27#include "symtab.h"
28#include "avtab.h" 28#include "avtab.h"
29#include "sidtab.h" 29#include "sidtab.h"
30#include "ebitmap.h"
31#include "mls_types.h"
30#include "context.h" 32#include "context.h"
31#include "constraint.h" 33#include "constraint.h"
32 34
@@ -113,8 +115,6 @@ struct range_trans {
113 u32 source_type; 115 u32 source_type;
114 u32 target_type; 116 u32 target_type;
115 u32 target_class; 117 u32 target_class;
116 struct mls_range target_range;
117 struct range_trans *next;
118}; 118};
119 119
120/* Boolean data type */ 120/* Boolean data type */
@@ -187,6 +187,8 @@ struct genfs {
187 187
188/* The policy database */ 188/* The policy database */
189struct policydb { 189struct policydb {
190 int mls_enabled;
191
190 /* symbol tables */ 192 /* symbol tables */
191 struct symtab symtab[SYM_NUM]; 193 struct symtab symtab[SYM_NUM];
192#define p_commons symtab[SYM_COMMONS] 194#define p_commons symtab[SYM_COMMONS]
@@ -240,8 +242,8 @@ struct policydb {
240 fixed labeling behavior. */ 242 fixed labeling behavior. */
241 struct genfs *genfs; 243 struct genfs *genfs;
242 244
243 /* range transitions */ 245 /* range transitions table (range_trans_key -> mls_range) */
244 struct range_trans *range_tr; 246 struct hashtab *range_tr;
245 247
246 /* type -> attribute reverse mapping */ 248 /* type -> attribute reverse mapping */
247 struct ebitmap *type_attr_map; 249 struct ebitmap *type_attr_map;
@@ -254,7 +256,9 @@ struct policydb {
254 256
255 unsigned int reject_unknown : 1; 257 unsigned int reject_unknown : 1;
256 unsigned int allow_unknown : 1; 258 unsigned int allow_unknown : 1;
257 u32 *undefined_perms; 259
260 u16 process_class;
261 u32 process_trans_perms;
258}; 262};
259 263
260extern void policydb_destroy(struct policydb *p); 264extern void policydb_destroy(struct policydb *p);
@@ -295,5 +299,8 @@ static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes)
295 return 0; 299 return 0;
296} 300}
297 301
302extern u16 string_to_security_class(struct policydb *p, const char *name);
303extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name);
304
298#endif /* _SS_POLICYDB_H_ */ 305#endif /* _SS_POLICYDB_H_ */
299 306
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index ff17820d35ec..cf27b3ee1a95 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -26,6 +26,10 @@
26 * 26 *
27 * Added support for bounds domain and audit messaged on masked permissions 27 * Added support for bounds domain and audit messaged on masked permissions
28 * 28 *
29 * Updated: Guido Trentalancia <guido@trentalancia.com>
30 *
31 * Added support for runtime switching of the policy type
32 *
29 * Copyright (C) 2008, 2009 NEC Corporation 33 * Copyright (C) 2008, 2009 NEC Corporation
30 * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. 34 * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
31 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. 35 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
@@ -65,16 +69,10 @@
65#include "audit.h" 69#include "audit.h"
66 70
67extern void selnl_notify_policyload(u32 seqno); 71extern void selnl_notify_policyload(u32 seqno);
68unsigned int policydb_loaded_version;
69 72
70int selinux_policycap_netpeer; 73int selinux_policycap_netpeer;
71int selinux_policycap_openperm; 74int selinux_policycap_openperm;
72 75
73/*
74 * This is declared in avc.c
75 */
76extern const struct selinux_class_perm selinux_class_perm;
77
78static DEFINE_RWLOCK(policy_rwlock); 76static DEFINE_RWLOCK(policy_rwlock);
79 77
80static struct sidtab sidtab; 78static struct sidtab sidtab;
@@ -93,11 +91,156 @@ static u32 latest_granting;
93static int context_struct_to_string(struct context *context, char **scontext, 91static int context_struct_to_string(struct context *context, char **scontext,
94 u32 *scontext_len); 92 u32 *scontext_len);
95 93
96static int context_struct_compute_av(struct context *scontext, 94static void context_struct_compute_av(struct context *scontext,
97 struct context *tcontext, 95 struct context *tcontext,
98 u16 tclass, 96 u16 tclass,
99 u32 requested, 97 struct av_decision *avd);
100 struct av_decision *avd); 98
99struct selinux_mapping {
100 u16 value; /* policy value */
101 unsigned num_perms;
102 u32 perms[sizeof(u32) * 8];
103};
104
105static struct selinux_mapping *current_mapping;
106static u16 current_mapping_size;
107
108static int selinux_set_mapping(struct policydb *pol,
109 struct security_class_mapping *map,
110 struct selinux_mapping **out_map_p,
111 u16 *out_map_size)
112{
113 struct selinux_mapping *out_map = NULL;
114 size_t size = sizeof(struct selinux_mapping);
115 u16 i, j;
116 unsigned k;
117 bool print_unknown_handle = false;
118
119 /* Find number of classes in the input mapping */
120 if (!map)
121 return -EINVAL;
122 i = 0;
123 while (map[i].name)
124 i++;
125
126 /* Allocate space for the class records, plus one for class zero */
127 out_map = kcalloc(++i, size, GFP_ATOMIC);
128 if (!out_map)
129 return -ENOMEM;
130
131 /* Store the raw class and permission values */
132 j = 0;
133 while (map[j].name) {
134 struct security_class_mapping *p_in = map + (j++);
135 struct selinux_mapping *p_out = out_map + j;
136
137 /* An empty class string skips ahead */
138 if (!strcmp(p_in->name, "")) {
139 p_out->num_perms = 0;
140 continue;
141 }
142
143 p_out->value = string_to_security_class(pol, p_in->name);
144 if (!p_out->value) {
145 printk(KERN_INFO
146 "SELinux: Class %s not defined in policy.\n",
147 p_in->name);
148 if (pol->reject_unknown)
149 goto err;
150 p_out->num_perms = 0;
151 print_unknown_handle = true;
152 continue;
153 }
154
155 k = 0;
156 while (p_in->perms && p_in->perms[k]) {
157 /* An empty permission string skips ahead */
158 if (!*p_in->perms[k]) {
159 k++;
160 continue;
161 }
162 p_out->perms[k] = string_to_av_perm(pol, p_out->value,
163 p_in->perms[k]);
164 if (!p_out->perms[k]) {
165 printk(KERN_INFO
166 "SELinux: Permission %s in class %s not defined in policy.\n",
167 p_in->perms[k], p_in->name);
168 if (pol->reject_unknown)
169 goto err;
170 print_unknown_handle = true;
171 }
172
173 k++;
174 }
175 p_out->num_perms = k;
176 }
177
178 if (print_unknown_handle)
179 printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n",
180 pol->allow_unknown ? "allowed" : "denied");
181
182 *out_map_p = out_map;
183 *out_map_size = i;
184 return 0;
185err:
186 kfree(out_map);
187 return -EINVAL;
188}
189
190/*
191 * Get real, policy values from mapped values
192 */
193
194static u16 unmap_class(u16 tclass)
195{
196 if (tclass < current_mapping_size)
197 return current_mapping[tclass].value;
198
199 return tclass;
200}
201
202static void map_decision(u16 tclass, struct av_decision *avd,
203 int allow_unknown)
204{
205 if (tclass < current_mapping_size) {
206 unsigned i, n = current_mapping[tclass].num_perms;
207 u32 result;
208
209 for (i = 0, result = 0; i < n; i++) {
210 if (avd->allowed & current_mapping[tclass].perms[i])
211 result |= 1<<i;
212 if (allow_unknown && !current_mapping[tclass].perms[i])
213 result |= 1<<i;
214 }
215 avd->allowed = result;
216
217 for (i = 0, result = 0; i < n; i++)
218 if (avd->auditallow & current_mapping[tclass].perms[i])
219 result |= 1<<i;
220 avd->auditallow = result;
221
222 for (i = 0, result = 0; i < n; i++) {
223 if (avd->auditdeny & current_mapping[tclass].perms[i])
224 result |= 1<<i;
225 if (!allow_unknown && !current_mapping[tclass].perms[i])
226 result |= 1<<i;
227 }
228 /*
229 * In case the kernel has a bug and requests a permission
230 * between num_perms and the maximum permission number, we
231 * should audit that denial
232 */
233 for (; i < (sizeof(u32)*8); i++)
234 result |= 1<<i;
235 avd->auditdeny = result;
236 }
237}
238
239int security_mls_enabled(void)
240{
241 return policydb.mls_enabled;
242}
243
101/* 244/*
102 * Return the boolean value of a constraint expression 245 * Return the boolean value of a constraint expression
103 * when it is applied to the specified source and target 246 * when it is applied to the specified source and target
@@ -312,7 +455,8 @@ static void security_dump_masked_av(struct context *scontext,
312 char *scontext_name = NULL; 455 char *scontext_name = NULL;
313 char *tcontext_name = NULL; 456 char *tcontext_name = NULL;
314 char *permission_names[32]; 457 char *permission_names[32];
315 int index, length; 458 int index;
459 u32 length;
316 bool need_comma = false; 460 bool need_comma = false;
317 461
318 if (!permissions) 462 if (!permissions)
@@ -379,7 +523,6 @@ out:
379static void type_attribute_bounds_av(struct context *scontext, 523static void type_attribute_bounds_av(struct context *scontext,
380 struct context *tcontext, 524 struct context *tcontext,
381 u16 tclass, 525 u16 tclass,
382 u32 requested,
383 struct av_decision *avd) 526 struct av_decision *avd)
384{ 527{
385 struct context lo_scontext; 528 struct context lo_scontext;
@@ -400,7 +543,6 @@ static void type_attribute_bounds_av(struct context *scontext,
400 context_struct_compute_av(&lo_scontext, 543 context_struct_compute_av(&lo_scontext,
401 tcontext, 544 tcontext,
402 tclass, 545 tclass,
403 requested,
404 &lo_avd); 546 &lo_avd);
405 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 547 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
406 return; /* no masked permission */ 548 return; /* no masked permission */
@@ -416,7 +558,6 @@ static void type_attribute_bounds_av(struct context *scontext,
416 context_struct_compute_av(scontext, 558 context_struct_compute_av(scontext,
417 &lo_tcontext, 559 &lo_tcontext,
418 tclass, 560 tclass,
419 requested,
420 &lo_avd); 561 &lo_avd);
421 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 562 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
422 return; /* no masked permission */ 563 return; /* no masked permission */
@@ -433,7 +574,6 @@ static void type_attribute_bounds_av(struct context *scontext,
433 context_struct_compute_av(&lo_scontext, 574 context_struct_compute_av(&lo_scontext,
434 &lo_tcontext, 575 &lo_tcontext,
435 tclass, 576 tclass,
436 requested,
437 &lo_avd); 577 &lo_avd);
438 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 578 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
439 return; /* no masked permission */ 579 return; /* no masked permission */
@@ -454,11 +594,10 @@ static void type_attribute_bounds_av(struct context *scontext,
454 * Compute access vectors based on a context structure pair for 594 * Compute access vectors based on a context structure pair for
455 * the permissions in a particular class. 595 * the permissions in a particular class.
456 */ 596 */
457static int context_struct_compute_av(struct context *scontext, 597static void context_struct_compute_av(struct context *scontext,
458 struct context *tcontext, 598 struct context *tcontext,
459 u16 tclass, 599 u16 tclass,
460 u32 requested, 600 struct av_decision *avd)
461 struct av_decision *avd)
462{ 601{
463 struct constraint_node *constraint; 602 struct constraint_node *constraint;
464 struct role_allow *ra; 603 struct role_allow *ra;
@@ -467,56 +606,17 @@ static int context_struct_compute_av(struct context *scontext,
467 struct class_datum *tclass_datum; 606 struct class_datum *tclass_datum;
468 struct ebitmap *sattr, *tattr; 607 struct ebitmap *sattr, *tattr;
469 struct ebitmap_node *snode, *tnode; 608 struct ebitmap_node *snode, *tnode;
470 const struct selinux_class_perm *kdefs = &selinux_class_perm;
471 unsigned int i, j; 609 unsigned int i, j;
472 610
473 /*
474 * Remap extended Netlink classes for old policy versions.
475 * Do this here rather than socket_type_to_security_class()
476 * in case a newer policy version is loaded, allowing sockets
477 * to remain in the correct class.
478 */
479 if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
480 if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET &&
481 tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
482 tclass = SECCLASS_NETLINK_SOCKET;
483
484 /*
485 * Initialize the access vectors to the default values.
486 */
487 avd->allowed = 0; 611 avd->allowed = 0;
488 avd->auditallow = 0; 612 avd->auditallow = 0;
489 avd->auditdeny = 0xffffffff; 613 avd->auditdeny = 0xffffffff;
490 avd->seqno = latest_granting;
491 avd->flags = 0;
492 614
493 /* 615 if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) {
494 * Check for all the invalid cases. 616 if (printk_ratelimit())
495 * - tclass 0 617 printk(KERN_WARNING "SELinux: Invalid class %hu\n", tclass);
496 * - tclass > policy and > kernel 618 return;
497 * - tclass > policy but is a userspace class 619 }
498 * - tclass > policy but we do not allow unknowns
499 */
500 if (unlikely(!tclass))
501 goto inval_class;
502 if (unlikely(tclass > policydb.p_classes.nprim))
503 if (tclass > kdefs->cts_len ||
504 !kdefs->class_to_string[tclass] ||
505 !policydb.allow_unknown)
506 goto inval_class;
507
508 /*
509 * Kernel class and we allow unknown so pad the allow decision
510 * the pad will be all 1 for unknown classes.
511 */
512 if (tclass <= kdefs->cts_len && policydb.allow_unknown)
513 avd->allowed = policydb.undefined_perms[tclass - 1];
514
515 /*
516 * Not in policy. Since decision is completed (all 1 or all 0) return.
517 */
518 if (unlikely(tclass > policydb.p_classes.nprim))
519 return 0;
520 620
521 tclass_datum = policydb.class_val_to_struct[tclass - 1]; 621 tclass_datum = policydb.class_val_to_struct[tclass - 1];
522 622
@@ -568,8 +668,8 @@ static int context_struct_compute_av(struct context *scontext,
568 * role is changing, then check the (current_role, new_role) 668 * role is changing, then check the (current_role, new_role)
569 * pair. 669 * pair.
570 */ 670 */
571 if (tclass == SECCLASS_PROCESS && 671 if (tclass == policydb.process_class &&
572 (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) && 672 (avd->allowed & policydb.process_trans_perms) &&
573 scontext->role != tcontext->role) { 673 scontext->role != tcontext->role) {
574 for (ra = policydb.role_allow; ra; ra = ra->next) { 674 for (ra = policydb.role_allow; ra; ra = ra->next) {
575 if (scontext->role == ra->role && 675 if (scontext->role == ra->role &&
@@ -577,8 +677,7 @@ static int context_struct_compute_av(struct context *scontext,
577 break; 677 break;
578 } 678 }
579 if (!ra) 679 if (!ra)
580 avd->allowed &= ~(PROCESS__TRANSITION | 680 avd->allowed &= ~policydb.process_trans_perms;
581 PROCESS__DYNTRANSITION);
582 } 681 }
583 682
584 /* 683 /*
@@ -587,24 +686,7 @@ static int context_struct_compute_av(struct context *scontext,
587 * permission and notice it to userspace via audit. 686 * permission and notice it to userspace via audit.
588 */ 687 */
589 type_attribute_bounds_av(scontext, tcontext, 688 type_attribute_bounds_av(scontext, tcontext,
590 tclass, requested, avd); 689 tclass, avd);
591
592 return 0;
593
594inval_class:
595 if (!tclass || tclass > kdefs->cts_len ||
596 !kdefs->class_to_string[tclass]) {
597 if (printk_ratelimit())
598 printk(KERN_ERR "SELinux: %s: unrecognized class %d\n",
599 __func__, tclass);
600 return -EINVAL;
601 }
602
603 /*
604 * Known to the kernel, but not to the policy.
605 * Handle as a denial (allowed is 0).
606 */
607 return 0;
608} 690}
609 691
610static int security_validtrans_handle_fail(struct context *ocontext, 692static int security_validtrans_handle_fail(struct context *ocontext,
@@ -636,13 +718,14 @@ out:
636} 718}
637 719
638int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, 720int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
639 u16 tclass) 721 u16 orig_tclass)
640{ 722{
641 struct context *ocontext; 723 struct context *ocontext;
642 struct context *ncontext; 724 struct context *ncontext;
643 struct context *tcontext; 725 struct context *tcontext;
644 struct class_datum *tclass_datum; 726 struct class_datum *tclass_datum;
645 struct constraint_node *constraint; 727 struct constraint_node *constraint;
728 u16 tclass;
646 int rc = 0; 729 int rc = 0;
647 730
648 if (!ss_initialized) 731 if (!ss_initialized)
@@ -650,16 +733,7 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
650 733
651 read_lock(&policy_rwlock); 734 read_lock(&policy_rwlock);
652 735
653 /* 736 tclass = unmap_class(orig_tclass);
654 * Remap extended Netlink classes for old policy versions.
655 * Do this here rather than socket_type_to_security_class()
656 * in case a newer policy version is loaded, allowing sockets
657 * to remain in the correct class.
658 */
659 if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
660 if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET &&
661 tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
662 tclass = SECCLASS_NETLINK_SOCKET;
663 737
664 if (!tclass || tclass > policydb.p_classes.nprim) { 738 if (!tclass || tclass > policydb.p_classes.nprim) {
665 printk(KERN_ERR "SELinux: %s: unrecognized class %d\n", 739 printk(KERN_ERR "SELinux: %s: unrecognized class %d\n",
@@ -741,7 +815,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
741 goto out; 815 goto out;
742 } 816 }
743 817
744 /* type/domain unchaned */ 818 /* type/domain unchanged */
745 if (old_context->type == new_context->type) { 819 if (old_context->type == new_context->type) {
746 rc = 0; 820 rc = 0;
747 goto out; 821 goto out;
@@ -769,7 +843,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
769 if (rc) { 843 if (rc) {
770 char *old_name = NULL; 844 char *old_name = NULL;
771 char *new_name = NULL; 845 char *new_name = NULL;
772 int length; 846 u32 length;
773 847
774 if (!context_struct_to_string(old_context, 848 if (!context_struct_to_string(old_context,
775 &old_name, &length) && 849 &old_name, &length) &&
@@ -791,63 +865,116 @@ out:
791 return rc; 865 return rc;
792} 866}
793 867
868static void avd_init(struct av_decision *avd)
869{
870 avd->allowed = 0;
871 avd->auditallow = 0;
872 avd->auditdeny = 0xffffffff;
873 avd->seqno = latest_granting;
874 avd->flags = 0;
875}
876
794 877
795/** 878/**
796 * security_compute_av - Compute access vector decisions. 879 * security_compute_av - Compute access vector decisions.
797 * @ssid: source security identifier 880 * @ssid: source security identifier
798 * @tsid: target security identifier 881 * @tsid: target security identifier
799 * @tclass: target security class 882 * @tclass: target security class
800 * @requested: requested permissions
801 * @avd: access vector decisions 883 * @avd: access vector decisions
802 * 884 *
803 * Compute a set of access vector decisions based on the 885 * Compute a set of access vector decisions based on the
804 * SID pair (@ssid, @tsid) for the permissions in @tclass. 886 * SID pair (@ssid, @tsid) for the permissions in @tclass.
805 * Return -%EINVAL if any of the parameters are invalid or %0
806 * if the access vector decisions were computed successfully.
807 */ 887 */
808int security_compute_av(u32 ssid, 888void security_compute_av(u32 ssid,
809 u32 tsid, 889 u32 tsid,
810 u16 tclass, 890 u16 orig_tclass,
811 u32 requested, 891 struct av_decision *avd)
812 struct av_decision *avd)
813{ 892{
893 u16 tclass;
814 struct context *scontext = NULL, *tcontext = NULL; 894 struct context *scontext = NULL, *tcontext = NULL;
815 int rc = 0;
816
817 if (!ss_initialized) {
818 avd->allowed = 0xffffffff;
819 avd->auditallow = 0;
820 avd->auditdeny = 0xffffffff;
821 avd->seqno = latest_granting;
822 return 0;
823 }
824 895
825 read_lock(&policy_rwlock); 896 read_lock(&policy_rwlock);
897 avd_init(avd);
898 if (!ss_initialized)
899 goto allow;
826 900
827 scontext = sidtab_search(&sidtab, ssid); 901 scontext = sidtab_search(&sidtab, ssid);
828 if (!scontext) { 902 if (!scontext) {
829 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 903 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
830 __func__, ssid); 904 __func__, ssid);
831 rc = -EINVAL;
832 goto out; 905 goto out;
833 } 906 }
907
908 /* permissive domain? */
909 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
910 avd->flags |= AVD_FLAGS_PERMISSIVE;
911
834 tcontext = sidtab_search(&sidtab, tsid); 912 tcontext = sidtab_search(&sidtab, tsid);
835 if (!tcontext) { 913 if (!tcontext) {
836 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 914 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
837 __func__, tsid); 915 __func__, tsid);
838 rc = -EINVAL;
839 goto out; 916 goto out;
840 } 917 }
841 918
842 rc = context_struct_compute_av(scontext, tcontext, tclass, 919 tclass = unmap_class(orig_tclass);
843 requested, avd); 920 if (unlikely(orig_tclass && !tclass)) {
921 if (policydb.allow_unknown)
922 goto allow;
923 goto out;
924 }
925 context_struct_compute_av(scontext, tcontext, tclass, avd);
926 map_decision(orig_tclass, avd, policydb.allow_unknown);
927out:
928 read_unlock(&policy_rwlock);
929 return;
930allow:
931 avd->allowed = 0xffffffff;
932 goto out;
933}
934
935void security_compute_av_user(u32 ssid,
936 u32 tsid,
937 u16 tclass,
938 struct av_decision *avd)
939{
940 struct context *scontext = NULL, *tcontext = NULL;
941
942 read_lock(&policy_rwlock);
943 avd_init(avd);
944 if (!ss_initialized)
945 goto allow;
946
947 scontext = sidtab_search(&sidtab, ssid);
948 if (!scontext) {
949 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
950 __func__, ssid);
951 goto out;
952 }
844 953
845 /* permissive domain? */ 954 /* permissive domain? */
846 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type)) 955 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
847 avd->flags |= AVD_FLAGS_PERMISSIVE; 956 avd->flags |= AVD_FLAGS_PERMISSIVE;
848out: 957
958 tcontext = sidtab_search(&sidtab, tsid);
959 if (!tcontext) {
960 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
961 __func__, tsid);
962 goto out;
963 }
964
965 if (unlikely(!tclass)) {
966 if (policydb.allow_unknown)
967 goto allow;
968 goto out;
969 }
970
971 context_struct_compute_av(scontext, tcontext, tclass, avd);
972 out:
849 read_unlock(&policy_rwlock); 973 read_unlock(&policy_rwlock);
850 return rc; 974 return;
975allow:
976 avd->allowed = 0xffffffff;
977 goto out;
851} 978}
852 979
853/* 980/*
@@ -1204,20 +1331,22 @@ out:
1204 1331
1205static int security_compute_sid(u32 ssid, 1332static int security_compute_sid(u32 ssid,
1206 u32 tsid, 1333 u32 tsid,
1207 u16 tclass, 1334 u16 orig_tclass,
1208 u32 specified, 1335 u32 specified,
1209 u32 *out_sid) 1336 u32 *out_sid,
1337 bool kern)
1210{ 1338{
1211 struct context *scontext = NULL, *tcontext = NULL, newcontext; 1339 struct context *scontext = NULL, *tcontext = NULL, newcontext;
1212 struct role_trans *roletr = NULL; 1340 struct role_trans *roletr = NULL;
1213 struct avtab_key avkey; 1341 struct avtab_key avkey;
1214 struct avtab_datum *avdatum; 1342 struct avtab_datum *avdatum;
1215 struct avtab_node *node; 1343 struct avtab_node *node;
1344 u16 tclass;
1216 int rc = 0; 1345 int rc = 0;
1217 1346
1218 if (!ss_initialized) { 1347 if (!ss_initialized) {
1219 switch (tclass) { 1348 switch (orig_tclass) {
1220 case SECCLASS_PROCESS: 1349 case SECCLASS_PROCESS: /* kernel value */
1221 *out_sid = ssid; 1350 *out_sid = ssid;
1222 break; 1351 break;
1223 default: 1352 default:
@@ -1231,6 +1360,11 @@ static int security_compute_sid(u32 ssid,
1231 1360
1232 read_lock(&policy_rwlock); 1361 read_lock(&policy_rwlock);
1233 1362
1363 if (kern)
1364 tclass = unmap_class(orig_tclass);
1365 else
1366 tclass = orig_tclass;
1367
1234 scontext = sidtab_search(&sidtab, ssid); 1368 scontext = sidtab_search(&sidtab, ssid);
1235 if (!scontext) { 1369 if (!scontext) {
1236 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n", 1370 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
@@ -1260,13 +1394,11 @@ static int security_compute_sid(u32 ssid,
1260 } 1394 }
1261 1395
1262 /* Set the role and type to default values. */ 1396 /* Set the role and type to default values. */
1263 switch (tclass) { 1397 if (tclass == policydb.process_class) {
1264 case SECCLASS_PROCESS:
1265 /* Use the current role and type of process. */ 1398 /* Use the current role and type of process. */
1266 newcontext.role = scontext->role; 1399 newcontext.role = scontext->role;
1267 newcontext.type = scontext->type; 1400 newcontext.type = scontext->type;
1268 break; 1401 } else {
1269 default:
1270 /* Use the well-defined object role. */ 1402 /* Use the well-defined object role. */
1271 newcontext.role = OBJECT_R_VAL; 1403 newcontext.role = OBJECT_R_VAL;
1272 /* Use the type of the related object. */ 1404 /* Use the type of the related object. */
@@ -1297,8 +1429,7 @@ static int security_compute_sid(u32 ssid,
1297 } 1429 }
1298 1430
1299 /* Check for class-specific changes. */ 1431 /* Check for class-specific changes. */
1300 switch (tclass) { 1432 if (tclass == policydb.process_class) {
1301 case SECCLASS_PROCESS:
1302 if (specified & AVTAB_TRANSITION) { 1433 if (specified & AVTAB_TRANSITION) {
1303 /* Look for a role transition rule. */ 1434 /* Look for a role transition rule. */
1304 for (roletr = policydb.role_tr; roletr; 1435 for (roletr = policydb.role_tr; roletr;
@@ -1311,9 +1442,6 @@ static int security_compute_sid(u32 ssid,
1311 } 1442 }
1312 } 1443 }
1313 } 1444 }
1314 break;
1315 default:
1316 break;
1317 } 1445 }
1318 1446
1319 /* Set the MLS attributes. 1447 /* Set the MLS attributes.
@@ -1358,7 +1486,17 @@ int security_transition_sid(u32 ssid,
1358 u16 tclass, 1486 u16 tclass,
1359 u32 *out_sid) 1487 u32 *out_sid)
1360{ 1488{
1361 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid); 1489 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1490 out_sid, true);
1491}
1492
1493int security_transition_sid_user(u32 ssid,
1494 u32 tsid,
1495 u16 tclass,
1496 u32 *out_sid)
1497{
1498 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1499 out_sid, false);
1362} 1500}
1363 1501
1364/** 1502/**
@@ -1379,7 +1517,8 @@ int security_member_sid(u32 ssid,
1379 u16 tclass, 1517 u16 tclass,
1380 u32 *out_sid) 1518 u32 *out_sid)
1381{ 1519{
1382 return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid); 1520 return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid,
1521 false);
1383} 1522}
1384 1523
1385/** 1524/**
@@ -1400,144 +1539,8 @@ int security_change_sid(u32 ssid,
1400 u16 tclass, 1539 u16 tclass,
1401 u32 *out_sid) 1540 u32 *out_sid)
1402{ 1541{
1403 return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid); 1542 return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid,
1404} 1543 false);
1405
1406/*
1407 * Verify that each kernel class that is defined in the
1408 * policy is correct
1409 */
1410static int validate_classes(struct policydb *p)
1411{
1412 int i, j;
1413 struct class_datum *cladatum;
1414 struct perm_datum *perdatum;
1415 u32 nprim, tmp, common_pts_len, perm_val, pol_val;
1416 u16 class_val;
1417 const struct selinux_class_perm *kdefs = &selinux_class_perm;
1418 const char *def_class, *def_perm, *pol_class;
1419 struct symtab *perms;
1420 bool print_unknown_handle = 0;
1421
1422 if (p->allow_unknown) {
1423 u32 num_classes = kdefs->cts_len;
1424 p->undefined_perms = kcalloc(num_classes, sizeof(u32), GFP_KERNEL);
1425 if (!p->undefined_perms)
1426 return -ENOMEM;
1427 }
1428
1429 for (i = 1; i < kdefs->cts_len; i++) {
1430 def_class = kdefs->class_to_string[i];
1431 if (!def_class)
1432 continue;
1433 if (i > p->p_classes.nprim) {
1434 printk(KERN_INFO
1435 "SELinux: class %s not defined in policy\n",
1436 def_class);
1437 if (p->reject_unknown)
1438 return -EINVAL;
1439 if (p->allow_unknown)
1440 p->undefined_perms[i-1] = ~0U;
1441 print_unknown_handle = 1;
1442 continue;
1443 }
1444 pol_class = p->p_class_val_to_name[i-1];
1445 if (strcmp(pol_class, def_class)) {
1446 printk(KERN_ERR
1447 "SELinux: class %d is incorrect, found %s but should be %s\n",
1448 i, pol_class, def_class);
1449 return -EINVAL;
1450 }
1451 }
1452 for (i = 0; i < kdefs->av_pts_len; i++) {
1453 class_val = kdefs->av_perm_to_string[i].tclass;
1454 perm_val = kdefs->av_perm_to_string[i].value;
1455 def_perm = kdefs->av_perm_to_string[i].name;
1456 if (class_val > p->p_classes.nprim)
1457 continue;
1458 pol_class = p->p_class_val_to_name[class_val-1];
1459 cladatum = hashtab_search(p->p_classes.table, pol_class);
1460 BUG_ON(!cladatum);
1461 perms = &cladatum->permissions;
1462 nprim = 1 << (perms->nprim - 1);
1463 if (perm_val > nprim) {
1464 printk(KERN_INFO
1465 "SELinux: permission %s in class %s not defined in policy\n",
1466 def_perm, pol_class);
1467 if (p->reject_unknown)
1468 return -EINVAL;
1469 if (p->allow_unknown)
1470 p->undefined_perms[class_val-1] |= perm_val;
1471 print_unknown_handle = 1;
1472 continue;
1473 }
1474 perdatum = hashtab_search(perms->table, def_perm);
1475 if (perdatum == NULL) {
1476 printk(KERN_ERR
1477 "SELinux: permission %s in class %s not found in policy, bad policy\n",
1478 def_perm, pol_class);
1479 return -EINVAL;
1480 }
1481 pol_val = 1 << (perdatum->value - 1);
1482 if (pol_val != perm_val) {
1483 printk(KERN_ERR
1484 "SELinux: permission %s in class %s has incorrect value\n",
1485 def_perm, pol_class);
1486 return -EINVAL;
1487 }
1488 }
1489 for (i = 0; i < kdefs->av_inherit_len; i++) {
1490 class_val = kdefs->av_inherit[i].tclass;
1491 if (class_val > p->p_classes.nprim)
1492 continue;
1493 pol_class = p->p_class_val_to_name[class_val-1];
1494 cladatum = hashtab_search(p->p_classes.table, pol_class);
1495 BUG_ON(!cladatum);
1496 if (!cladatum->comdatum) {
1497 printk(KERN_ERR
1498 "SELinux: class %s should have an inherits clause but does not\n",
1499 pol_class);
1500 return -EINVAL;
1501 }
1502 tmp = kdefs->av_inherit[i].common_base;
1503 common_pts_len = 0;
1504 while (!(tmp & 0x01)) {
1505 common_pts_len++;
1506 tmp >>= 1;
1507 }
1508 perms = &cladatum->comdatum->permissions;
1509 for (j = 0; j < common_pts_len; j++) {
1510 def_perm = kdefs->av_inherit[i].common_pts[j];
1511 if (j >= perms->nprim) {
1512 printk(KERN_INFO
1513 "SELinux: permission %s in class %s not defined in policy\n",
1514 def_perm, pol_class);
1515 if (p->reject_unknown)
1516 return -EINVAL;
1517 if (p->allow_unknown)
1518 p->undefined_perms[class_val-1] |= (1 << j);
1519 print_unknown_handle = 1;
1520 continue;
1521 }
1522 perdatum = hashtab_search(perms->table, def_perm);
1523 if (perdatum == NULL) {
1524 printk(KERN_ERR
1525 "SELinux: permission %s in class %s not found in policy, bad policy\n",
1526 def_perm, pol_class);
1527 return -EINVAL;
1528 }
1529 if (perdatum->value != j + 1) {
1530 printk(KERN_ERR
1531 "SELinux: permission %s in class %s has incorrect value\n",
1532 def_perm, pol_class);
1533 return -EINVAL;
1534 }
1535 }
1536 }
1537 if (print_unknown_handle)
1538 printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n",
1539 (security_get_allow_unknown() ? "allowed" : "denied"));
1540 return 0;
1541} 1544}
1542 1545
1543/* Clone the SID into the new SID table. */ 1546/* Clone the SID into the new SID table. */
@@ -1547,7 +1550,10 @@ static int clone_sid(u32 sid,
1547{ 1550{
1548 struct sidtab *s = arg; 1551 struct sidtab *s = arg;
1549 1552
1550 return sidtab_insert(s, sid, context); 1553 if (sid > SECINITSID_NUM)
1554 return sidtab_insert(s, sid, context);
1555 else
1556 return 0;
1551} 1557}
1552 1558
1553static inline int convert_context_handle_invalid_context(struct context *context) 1559static inline int convert_context_handle_invalid_context(struct context *context)
@@ -1588,12 +1594,17 @@ static int convert_context(u32 key,
1588{ 1594{
1589 struct convert_context_args *args; 1595 struct convert_context_args *args;
1590 struct context oldc; 1596 struct context oldc;
1597 struct ocontext *oc;
1598 struct mls_range *range;
1591 struct role_datum *role; 1599 struct role_datum *role;
1592 struct type_datum *typdatum; 1600 struct type_datum *typdatum;
1593 struct user_datum *usrdatum; 1601 struct user_datum *usrdatum;
1594 char *s; 1602 char *s;
1595 u32 len; 1603 u32 len;
1596 int rc; 1604 int rc = 0;
1605
1606 if (key <= SECINITSID_NUM)
1607 goto out;
1597 1608
1598 args = p; 1609 args = p;
1599 1610
@@ -1655,9 +1666,39 @@ static int convert_context(u32 key,
1655 goto bad; 1666 goto bad;
1656 c->type = typdatum->value; 1667 c->type = typdatum->value;
1657 1668
1658 rc = mls_convert_context(args->oldp, args->newp, c); 1669 /* Convert the MLS fields if dealing with MLS policies */
1659 if (rc) 1670 if (args->oldp->mls_enabled && args->newp->mls_enabled) {
1660 goto bad; 1671 rc = mls_convert_context(args->oldp, args->newp, c);
1672 if (rc)
1673 goto bad;
1674 } else if (args->oldp->mls_enabled && !args->newp->mls_enabled) {
1675 /*
1676 * Switching between MLS and non-MLS policy:
1677 * free any storage used by the MLS fields in the
1678 * context for all existing entries in the sidtab.
1679 */
1680 mls_context_destroy(c);
1681 } else if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
1682 /*
1683 * Switching between non-MLS and MLS policy:
1684 * ensure that the MLS fields of the context for all
1685 * existing entries in the sidtab are filled in with a
1686 * suitable default value, likely taken from one of the
1687 * initial SIDs.
1688 */
1689 oc = args->newp->ocontexts[OCON_ISID];
1690 while (oc && oc->sid[0] != SECINITSID_UNLABELED)
1691 oc = oc->next;
1692 if (!oc) {
1693 printk(KERN_ERR "SELinux: unable to look up"
1694 " the initial SIDs list\n");
1695 goto bad;
1696 }
1697 range = &oc->context[0].range;
1698 rc = mls_range_set(c, range);
1699 if (rc)
1700 goto bad;
1701 }
1661 1702
1662 /* Check the validity of the new context. */ 1703 /* Check the validity of the new context. */
1663 if (!policydb_context_isvalid(args->newp, c)) { 1704 if (!policydb_context_isvalid(args->newp, c)) {
@@ -1710,8 +1751,10 @@ int security_load_policy(void *data, size_t len)
1710{ 1751{
1711 struct policydb oldpolicydb, newpolicydb; 1752 struct policydb oldpolicydb, newpolicydb;
1712 struct sidtab oldsidtab, newsidtab; 1753 struct sidtab oldsidtab, newsidtab;
1754 struct selinux_mapping *oldmap, *map = NULL;
1713 struct convert_context_args args; 1755 struct convert_context_args args;
1714 u32 seqno; 1756 u32 seqno;
1757 u16 map_size;
1715 int rc = 0; 1758 int rc = 0;
1716 struct policy_file file = { data, len }, *fp = &file; 1759 struct policy_file file = { data, len }, *fp = &file;
1717 1760
@@ -1721,22 +1764,19 @@ int security_load_policy(void *data, size_t len)
1721 avtab_cache_destroy(); 1764 avtab_cache_destroy();
1722 return -EINVAL; 1765 return -EINVAL;
1723 } 1766 }
1724 if (policydb_load_isids(&policydb, &sidtab)) { 1767 if (selinux_set_mapping(&policydb, secclass_map,
1768 &current_mapping,
1769 &current_mapping_size)) {
1725 policydb_destroy(&policydb); 1770 policydb_destroy(&policydb);
1726 avtab_cache_destroy(); 1771 avtab_cache_destroy();
1727 return -EINVAL; 1772 return -EINVAL;
1728 } 1773 }
1729 /* Verify that the kernel defined classes are correct. */ 1774 if (policydb_load_isids(&policydb, &sidtab)) {
1730 if (validate_classes(&policydb)) {
1731 printk(KERN_ERR
1732 "SELinux: the definition of a class is incorrect\n");
1733 sidtab_destroy(&sidtab);
1734 policydb_destroy(&policydb); 1775 policydb_destroy(&policydb);
1735 avtab_cache_destroy(); 1776 avtab_cache_destroy();
1736 return -EINVAL; 1777 return -EINVAL;
1737 } 1778 }
1738 security_load_policycaps(); 1779 security_load_policycaps();
1739 policydb_loaded_version = policydb.policyvers;
1740 ss_initialized = 1; 1780 ss_initialized = 1;
1741 seqno = ++latest_granting; 1781 seqno = ++latest_granting;
1742 selinux_complete_init(); 1782 selinux_complete_init();
@@ -1754,18 +1794,22 @@ int security_load_policy(void *data, size_t len)
1754 if (policydb_read(&newpolicydb, fp)) 1794 if (policydb_read(&newpolicydb, fp))
1755 return -EINVAL; 1795 return -EINVAL;
1756 1796
1757 if (sidtab_init(&newsidtab)) { 1797 /* If switching between different policy types, log MLS status */
1798 if (policydb.mls_enabled && !newpolicydb.mls_enabled)
1799 printk(KERN_INFO "SELinux: Disabling MLS support...\n");
1800 else if (!policydb.mls_enabled && newpolicydb.mls_enabled)
1801 printk(KERN_INFO "SELinux: Enabling MLS support...\n");
1802
1803 rc = policydb_load_isids(&newpolicydb, &newsidtab);
1804 if (rc) {
1805 printk(KERN_ERR "SELinux: unable to load the initial SIDs\n");
1758 policydb_destroy(&newpolicydb); 1806 policydb_destroy(&newpolicydb);
1759 return -ENOMEM; 1807 return rc;
1760 } 1808 }
1761 1809
1762 /* Verify that the kernel defined classes are correct. */ 1810 if (selinux_set_mapping(&newpolicydb, secclass_map,
1763 if (validate_classes(&newpolicydb)) { 1811 &map, &map_size))
1764 printk(KERN_ERR
1765 "SELinux: the definition of a class is incorrect\n");
1766 rc = -EINVAL;
1767 goto err; 1812 goto err;
1768 }
1769 1813
1770 rc = security_preserve_bools(&newpolicydb); 1814 rc = security_preserve_bools(&newpolicydb);
1771 if (rc) { 1815 if (rc) {
@@ -1787,8 +1831,12 @@ int security_load_policy(void *data, size_t len)
1787 args.oldp = &policydb; 1831 args.oldp = &policydb;
1788 args.newp = &newpolicydb; 1832 args.newp = &newpolicydb;
1789 rc = sidtab_map(&newsidtab, convert_context, &args); 1833 rc = sidtab_map(&newsidtab, convert_context, &args);
1790 if (rc) 1834 if (rc) {
1835 printk(KERN_ERR "SELinux: unable to convert the internal"
1836 " representation of contexts in the new SID"
1837 " table\n");
1791 goto err; 1838 goto err;
1839 }
1792 1840
1793 /* Save the old policydb and SID table to free later. */ 1841 /* Save the old policydb and SID table to free later. */
1794 memcpy(&oldpolicydb, &policydb, sizeof policydb); 1842 memcpy(&oldpolicydb, &policydb, sizeof policydb);
@@ -1799,13 +1847,16 @@ int security_load_policy(void *data, size_t len)
1799 memcpy(&policydb, &newpolicydb, sizeof policydb); 1847 memcpy(&policydb, &newpolicydb, sizeof policydb);
1800 sidtab_set(&sidtab, &newsidtab); 1848 sidtab_set(&sidtab, &newsidtab);
1801 security_load_policycaps(); 1849 security_load_policycaps();
1850 oldmap = current_mapping;
1851 current_mapping = map;
1852 current_mapping_size = map_size;
1802 seqno = ++latest_granting; 1853 seqno = ++latest_granting;
1803 policydb_loaded_version = policydb.policyvers;
1804 write_unlock_irq(&policy_rwlock); 1854 write_unlock_irq(&policy_rwlock);
1805 1855
1806 /* Free the old policydb and SID table. */ 1856 /* Free the old policydb and SID table. */
1807 policydb_destroy(&oldpolicydb); 1857 policydb_destroy(&oldpolicydb);
1808 sidtab_destroy(&oldsidtab); 1858 sidtab_destroy(&oldsidtab);
1859 kfree(oldmap);
1809 1860
1810 avc_ss_reset(seqno); 1861 avc_ss_reset(seqno);
1811 selnl_notify_policyload(seqno); 1862 selnl_notify_policyload(seqno);
@@ -1815,6 +1866,7 @@ int security_load_policy(void *data, size_t len)
1815 return 0; 1866 return 0;
1816 1867
1817err: 1868err:
1869 kfree(map);
1818 sidtab_destroy(&newsidtab); 1870 sidtab_destroy(&newsidtab);
1819 policydb_destroy(&newpolicydb); 1871 policydb_destroy(&newpolicydb);
1820 return rc; 1872 return rc;
@@ -2091,7 +2143,7 @@ out_unlock:
2091 } 2143 }
2092 for (i = 0, j = 0; i < mynel; i++) { 2144 for (i = 0, j = 0; i < mynel; i++) {
2093 rc = avc_has_perm_noaudit(fromsid, mysids[i], 2145 rc = avc_has_perm_noaudit(fromsid, mysids[i],
2094 SECCLASS_PROCESS, 2146 SECCLASS_PROCESS, /* kernel value */
2095 PROCESS__TRANSITION, AVC_STRICT, 2147 PROCESS__TRANSITION, AVC_STRICT,
2096 NULL); 2148 NULL);
2097 if (!rc) 2149 if (!rc)
@@ -2119,10 +2171,11 @@ out:
2119 */ 2171 */
2120int security_genfs_sid(const char *fstype, 2172int security_genfs_sid(const char *fstype,
2121 char *path, 2173 char *path,
2122 u16 sclass, 2174 u16 orig_sclass,
2123 u32 *sid) 2175 u32 *sid)
2124{ 2176{
2125 int len; 2177 int len;
2178 u16 sclass;
2126 struct genfs *genfs; 2179 struct genfs *genfs;
2127 struct ocontext *c; 2180 struct ocontext *c;
2128 int rc = 0, cmp = 0; 2181 int rc = 0, cmp = 0;
@@ -2132,6 +2185,8 @@ int security_genfs_sid(const char *fstype,
2132 2185
2133 read_lock(&policy_rwlock); 2186 read_lock(&policy_rwlock);
2134 2187
2188 sclass = unmap_class(orig_sclass);
2189
2135 for (genfs = policydb.genfs; genfs; genfs = genfs->next) { 2190 for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
2136 cmp = strcmp(fstype, genfs->fstype); 2191 cmp = strcmp(fstype, genfs->fstype);
2137 if (cmp <= 0) 2192 if (cmp <= 0)
@@ -2377,7 +2432,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2377 u32 len; 2432 u32 len;
2378 int rc = 0; 2433 int rc = 0;
2379 2434
2380 if (!ss_initialized || !selinux_mls_enabled) { 2435 if (!ss_initialized || !policydb.mls_enabled) {
2381 *new_sid = sid; 2436 *new_sid = sid;
2382 goto out; 2437 goto out;
2383 } 2438 }
@@ -2478,7 +2533,7 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2478 /* we don't need to check ss_initialized here since the only way both 2533 /* we don't need to check ss_initialized here since the only way both
2479 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the 2534 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
2480 * security server was initialized and ss_initialized was true */ 2535 * security server was initialized and ss_initialized was true */
2481 if (!selinux_mls_enabled) { 2536 if (!policydb.mls_enabled) {
2482 *peer_sid = SECSID_NULL; 2537 *peer_sid = SECSID_NULL;
2483 return 0; 2538 return 0;
2484 } 2539 }
@@ -2535,7 +2590,7 @@ int security_get_classes(char ***classes, int *nclasses)
2535 read_lock(&policy_rwlock); 2590 read_lock(&policy_rwlock);
2536 2591
2537 *nclasses = policydb.p_classes.nprim; 2592 *nclasses = policydb.p_classes.nprim;
2538 *classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC); 2593 *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC);
2539 if (!*classes) 2594 if (!*classes)
2540 goto out; 2595 goto out;
2541 2596
@@ -2582,7 +2637,7 @@ int security_get_permissions(char *class, char ***perms, int *nperms)
2582 } 2637 }
2583 2638
2584 *nperms = match->permissions.nprim; 2639 *nperms = match->permissions.nprim;
2585 *perms = kcalloc(*nperms, sizeof(*perms), GFP_ATOMIC); 2640 *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC);
2586 if (!*perms) 2641 if (!*perms)
2587 goto out; 2642 goto out;
2588 2643
diff --git a/security/selinux/ss/symtab.c b/security/selinux/ss/symtab.c
index 837658a98a54..bcf9f620426e 100644
--- a/security/selinux/ss/symtab.c
+++ b/security/selinux/ss/symtab.c
@@ -4,7 +4,6 @@
4 * Author : Stephen Smalley, <sds@epoch.ncsc.mil> 4 * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
5 */ 5 */
6#include <linux/kernel.h> 6#include <linux/kernel.h>
7#include <linux/slab.h>
8#include <linux/string.h> 7#include <linux/string.h>
9#include <linux/errno.h> 8#include <linux/errno.h>
10#include "symtab.h" 9#include "symtab.h"
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index f3cb9ed731a9..fff78d3b51a2 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -38,6 +38,7 @@
38#include <linux/netfilter.h> 38#include <linux/netfilter.h>
39#include <linux/netfilter_ipv4.h> 39#include <linux/netfilter_ipv4.h>
40#include <linux/netfilter_ipv6.h> 40#include <linux/netfilter_ipv6.h>
41#include <linux/slab.h>
41#include <linux/ip.h> 42#include <linux/ip.h>
42#include <linux/tcp.h> 43#include <linux/tcp.h>
43#include <linux/skbuff.h> 44#include <linux/skbuff.h>
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 0f9ac8146900..f4fac64c4da8 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/types.h> 13#include <linux/types.h>
14#include <linux/slab.h>
14#include <linux/fs.h> 15#include <linux/fs.h>
15#include <linux/sched.h> 16#include <linux/sched.h>
16#include "smack.h" 17#include "smack.h"
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index c33b6bb9b6dd..fdfeaa2f28ec 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -25,6 +25,7 @@
25#include <linux/ip.h> 25#include <linux/ip.h>
26#include <linux/tcp.h> 26#include <linux/tcp.h>
27#include <linux/udp.h> 27#include <linux/udp.h>
28#include <linux/slab.h>
28#include <linux/mutex.h> 29#include <linux/mutex.h>
29#include <linux/pipe_fs_i.h> 30#include <linux/pipe_fs_i.h>
30#include <net/netlabel.h> 31#include <net/netlabel.h>
@@ -157,12 +158,12 @@ static int smack_ptrace_traceme(struct task_struct *ptp)
157 * 158 *
158 * Returns 0 on success, error code otherwise. 159 * Returns 0 on success, error code otherwise.
159 */ 160 */
160static int smack_syslog(int type) 161static int smack_syslog(int type, bool from_file)
161{ 162{
162 int rc; 163 int rc;
163 char *sp = current_security(); 164 char *sp = current_security();
164 165
165 rc = cap_syslog(type); 166 rc = cap_syslog(type, from_file);
166 if (rc != 0) 167 if (rc != 0)
167 return rc; 168 return rc;
168 169
@@ -387,7 +388,7 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags)
387 struct smk_audit_info ad; 388 struct smk_audit_info ad;
388 389
389 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 390 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS);
390 smk_ad_setfield_u_fs_path_dentry(&ad, mnt->mnt_mountpoint); 391 smk_ad_setfield_u_fs_path_dentry(&ad, mnt->mnt_root);
391 smk_ad_setfield_u_fs_path_mnt(&ad, mnt); 392 smk_ad_setfield_u_fs_path_mnt(&ad, mnt);
392 393
393 sbp = mnt->mnt_sb->s_security; 394 sbp = mnt->mnt_sb->s_security;
@@ -2602,7 +2603,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
2602#ifdef CONFIG_AUDIT 2603#ifdef CONFIG_AUDIT
2603 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); 2604 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2604 ad.a.u.net.family = sk->sk_family; 2605 ad.a.u.net.family = sk->sk_family;
2605 ad.a.u.net.netif = skb->iif; 2606 ad.a.u.net.netif = skb->skb_iif;
2606 ipv4_skb_to_auditdata(skb, &ad.a, NULL); 2607 ipv4_skb_to_auditdata(skb, &ad.a, NULL);
2607#endif 2608#endif
2608 /* 2609 /*
@@ -2757,7 +2758,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb,
2757#ifdef CONFIG_AUDIT 2758#ifdef CONFIG_AUDIT
2758 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET); 2759 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NET);
2759 ad.a.u.net.family = family; 2760 ad.a.u.net.family = family;
2760 ad.a.u.net.netif = skb->iif; 2761 ad.a.u.net.netif = skb->skb_iif;
2761 ipv4_skb_to_auditdata(skb, &ad.a, NULL); 2762 ipv4_skb_to_auditdata(skb, &ad.a, NULL);
2762#endif 2763#endif
2763 /* 2764 /*
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index aeead7585093..a2b72d77f926 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -20,6 +20,7 @@
20#include <linux/vmalloc.h> 20#include <linux/vmalloc.h>
21#include <linux/security.h> 21#include <linux/security.h>
22#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <linux/slab.h>
23#include <net/net_namespace.h> 24#include <net/net_namespace.h>
24#include <net/netlabel.h> 25#include <net/netlabel.h>
25#include <net/cipso_ipv4.h> 26#include <net/cipso_ipv4.h>
diff --git a/security/tomoyo/Makefile b/security/tomoyo/Makefile
index 10ccd686b290..60a9e2002da1 100644
--- a/security/tomoyo/Makefile
+++ b/security/tomoyo/Makefile
@@ -1 +1 @@
obj-y = common.o realpath.o tomoyo.o domain.o file.o obj-y = common.o realpath.o tomoyo.o domain.o file.o gc.o
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 3c8bd8ee0b95..975c45d88baa 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -10,11 +10,13 @@
10 */ 10 */
11 11
12#include <linux/uaccess.h> 12#include <linux/uaccess.h>
13#include <linux/slab.h>
13#include <linux/security.h> 14#include <linux/security.h>
14#include <linux/hardirq.h> 15#include <linux/hardirq.h>
15#include "realpath.h"
16#include "common.h" 16#include "common.h"
17#include "tomoyo.h" 17
18/* Lock for protecting policy. */
19DEFINE_MUTEX(tomoyo_policy_lock);
18 20
19/* Has loading policy done? */ 21/* Has loading policy done? */
20bool tomoyo_policy_loaded; 22bool tomoyo_policy_loaded;
@@ -178,20 +180,19 @@ static void tomoyo_normalize_line(unsigned char *buffer)
178 * 1 = must / -1 = must not / 0 = don't care 180 * 1 = must / -1 = must not / 0 = don't care
179 * @end_type: Should the pathname end with '/'? 181 * @end_type: Should the pathname end with '/'?
180 * 1 = must / -1 = must not / 0 = don't care 182 * 1 = must / -1 = must not / 0 = don't care
181 * @function: The name of function calling me.
182 * 183 *
183 * Check whether the given filename follows the naming rules. 184 * Check whether the given filename follows the naming rules.
184 * Returns true if @filename follows the naming rules, false otherwise. 185 * Returns true if @filename follows the naming rules, false otherwise.
185 */ 186 */
186bool tomoyo_is_correct_path(const char *filename, const s8 start_type, 187bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
187 const s8 pattern_type, const s8 end_type, 188 const s8 pattern_type, const s8 end_type)
188 const char *function)
189{ 189{
190 const char *const start = filename;
191 bool in_repetition = false;
190 bool contains_pattern = false; 192 bool contains_pattern = false;
191 unsigned char c; 193 unsigned char c;
192 unsigned char d; 194 unsigned char d;
193 unsigned char e; 195 unsigned char e;
194 const char *original_filename = filename;
195 196
196 if (!filename) 197 if (!filename)
197 goto out; 198 goto out;
@@ -212,9 +213,13 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
212 if (c == '/') 213 if (c == '/')
213 goto out; 214 goto out;
214 } 215 }
215 while ((c = *filename++) != '\0') { 216 while (1) {
217 c = *filename++;
218 if (!c)
219 break;
216 if (c == '\\') { 220 if (c == '\\') {
217 switch ((c = *filename++)) { 221 c = *filename++;
222 switch (c) {
218 case '\\': /* "\\" */ 223 case '\\': /* "\\" */
219 continue; 224 continue;
220 case '$': /* "\$" */ 225 case '$': /* "\$" */
@@ -231,6 +236,22 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
231 break; /* Must not contain pattern */ 236 break; /* Must not contain pattern */
232 contains_pattern = true; 237 contains_pattern = true;
233 continue; 238 continue;
239 case '{': /* "/\{" */
240 if (filename - 3 < start ||
241 *(filename - 3) != '/')
242 break;
243 if (pattern_type == -1)
244 break; /* Must not contain pattern */
245 contains_pattern = true;
246 in_repetition = true;
247 continue;
248 case '}': /* "\}/" */
249 if (*filename != '/')
250 break;
251 if (!in_repetition)
252 break;
253 in_repetition = false;
254 continue;
234 case '0': /* "\ooo" */ 255 case '0': /* "\ooo" */
235 case '1': 256 case '1':
236 case '2': 257 case '2':
@@ -246,6 +267,8 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
246 continue; /* pattern is not \000 */ 267 continue; /* pattern is not \000 */
247 } 268 }
248 goto out; 269 goto out;
270 } else if (in_repetition && c == '/') {
271 goto out;
249 } else if (tomoyo_is_invalid(c)) { 272 } else if (tomoyo_is_invalid(c)) {
250 goto out; 273 goto out;
251 } 274 }
@@ -254,27 +277,24 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
254 if (!contains_pattern) 277 if (!contains_pattern)
255 goto out; 278 goto out;
256 } 279 }
280 if (in_repetition)
281 goto out;
257 return true; 282 return true;
258 out: 283 out:
259 printk(KERN_DEBUG "%s: Invalid pathname '%s'\n", function,
260 original_filename);
261 return false; 284 return false;
262} 285}
263 286
264/** 287/**
265 * tomoyo_is_correct_domain - Check whether the given domainname follows the naming rules. 288 * tomoyo_is_correct_domain - Check whether the given domainname follows the naming rules.
266 * @domainname: The domainname to check. 289 * @domainname: The domainname to check.
267 * @function: The name of function calling me.
268 * 290 *
269 * Returns true if @domainname follows the naming rules, false otherwise. 291 * Returns true if @domainname follows the naming rules, false otherwise.
270 */ 292 */
271bool tomoyo_is_correct_domain(const unsigned char *domainname, 293bool tomoyo_is_correct_domain(const unsigned char *domainname)
272 const char *function)
273{ 294{
274 unsigned char c; 295 unsigned char c;
275 unsigned char d; 296 unsigned char d;
276 unsigned char e; 297 unsigned char e;
277 const char *org_domainname = domainname;
278 298
279 if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME, 299 if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME,
280 TOMOYO_ROOT_NAME_LEN)) 300 TOMOYO_ROOT_NAME_LEN))
@@ -317,8 +337,6 @@ bool tomoyo_is_correct_domain(const unsigned char *domainname,
317 } while (*domainname); 337 } while (*domainname);
318 return true; 338 return true;
319 out: 339 out:
320 printk(KERN_DEBUG "%s: Invalid domainname '%s'\n", function,
321 org_domainname);
322 return false; 340 return false;
323} 341}
324 342
@@ -339,10 +357,9 @@ bool tomoyo_is_domain_def(const unsigned char *buffer)
339 * 357 *
340 * @domainname: The domainname to find. 358 * @domainname: The domainname to find.
341 * 359 *
342 * Caller must call down_read(&tomoyo_domain_list_lock); or
343 * down_write(&tomoyo_domain_list_lock); .
344 *
345 * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise. 360 * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise.
361 *
362 * Caller holds tomoyo_read_lock().
346 */ 363 */
347struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname) 364struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)
348{ 365{
@@ -351,7 +368,7 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)
351 368
352 name.name = domainname; 369 name.name = domainname;
353 tomoyo_fill_path_info(&name); 370 tomoyo_fill_path_info(&name);
354 list_for_each_entry(domain, &tomoyo_domain_list, list) { 371 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
355 if (!domain->is_deleted && 372 if (!domain->is_deleted &&
356 !tomoyo_pathcmp(&name, domain->domainname)) 373 !tomoyo_pathcmp(&name, domain->domainname))
357 return domain; 374 return domain;
@@ -360,33 +377,6 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)
360} 377}
361 378
362/** 379/**
363 * tomoyo_path_depth - Evaluate the number of '/' in a string.
364 *
365 * @pathname: The string to evaluate.
366 *
367 * Returns path depth of the string.
368 *
369 * I score 2 for each of the '/' in the @pathname
370 * and score 1 if the @pathname ends with '/'.
371 */
372static int tomoyo_path_depth(const char *pathname)
373{
374 int i = 0;
375
376 if (pathname) {
377 const char *ep = pathname + strlen(pathname);
378 if (pathname < ep--) {
379 if (*ep != '/')
380 i++;
381 while (pathname <= ep)
382 if (*ep-- == '/')
383 i += 2;
384 }
385 }
386 return i;
387}
388
389/**
390 * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token. 380 * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token.
391 * 381 *
392 * @filename: The string to evaluate. 382 * @filename: The string to evaluate.
@@ -444,11 +434,10 @@ void tomoyo_fill_path_info(struct tomoyo_path_info *ptr)
444 ptr->is_dir = len && (name[len - 1] == '/'); 434 ptr->is_dir = len && (name[len - 1] == '/');
445 ptr->is_patterned = (ptr->const_len < len); 435 ptr->is_patterned = (ptr->const_len < len);
446 ptr->hash = full_name_hash(name, len); 436 ptr->hash = full_name_hash(name, len);
447 ptr->depth = tomoyo_path_depth(name);
448} 437}
449 438
450/** 439/**
451 * tomoyo_file_matches_to_pattern2 - Pattern matching without '/' character 440 * tomoyo_file_matches_pattern2 - Pattern matching without '/' character
452 * and "\-" pattern. 441 * and "\-" pattern.
453 * 442 *
454 * @filename: The start of string to check. 443 * @filename: The start of string to check.
@@ -458,10 +447,10 @@ void tomoyo_fill_path_info(struct tomoyo_path_info *ptr)
458 * 447 *
459 * Returns true if @filename matches @pattern, false otherwise. 448 * Returns true if @filename matches @pattern, false otherwise.
460 */ 449 */
461static bool tomoyo_file_matches_to_pattern2(const char *filename, 450static bool tomoyo_file_matches_pattern2(const char *filename,
462 const char *filename_end, 451 const char *filename_end,
463 const char *pattern, 452 const char *pattern,
464 const char *pattern_end) 453 const char *pattern_end)
465{ 454{
466 while (filename < filename_end && pattern < pattern_end) { 455 while (filename < filename_end && pattern < pattern_end) {
467 char c; 456 char c;
@@ -519,7 +508,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename,
519 case '*': 508 case '*':
520 case '@': 509 case '@':
521 for (i = 0; i <= filename_end - filename; i++) { 510 for (i = 0; i <= filename_end - filename; i++) {
522 if (tomoyo_file_matches_to_pattern2( 511 if (tomoyo_file_matches_pattern2(
523 filename + i, filename_end, 512 filename + i, filename_end,
524 pattern + 1, pattern_end)) 513 pattern + 1, pattern_end))
525 return true; 514 return true;
@@ -550,7 +539,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename,
550 j++; 539 j++;
551 } 540 }
552 for (i = 1; i <= j; i++) { 541 for (i = 1; i <= j; i++) {
553 if (tomoyo_file_matches_to_pattern2( 542 if (tomoyo_file_matches_pattern2(
554 filename + i, filename_end, 543 filename + i, filename_end,
555 pattern + 1, pattern_end)) 544 pattern + 1, pattern_end))
556 return true; 545 return true;
@@ -567,7 +556,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename,
567} 556}
568 557
569/** 558/**
570 * tomoyo_file_matches_to_pattern - Pattern matching without without '/' character. 559 * tomoyo_file_matches_pattern - Pattern matching without without '/' character.
571 * 560 *
572 * @filename: The start of string to check. 561 * @filename: The start of string to check.
573 * @filename_end: The end of string to check. 562 * @filename_end: The end of string to check.
@@ -576,7 +565,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename,
576 * 565 *
577 * Returns true if @filename matches @pattern, false otherwise. 566 * Returns true if @filename matches @pattern, false otherwise.
578 */ 567 */
579static bool tomoyo_file_matches_to_pattern(const char *filename, 568static bool tomoyo_file_matches_pattern(const char *filename,
580 const char *filename_end, 569 const char *filename_end,
581 const char *pattern, 570 const char *pattern,
582 const char *pattern_end) 571 const char *pattern_end)
@@ -589,10 +578,10 @@ static bool tomoyo_file_matches_to_pattern(const char *filename,
589 /* Split at "\-" pattern. */ 578 /* Split at "\-" pattern. */
590 if (*pattern++ != '\\' || *pattern++ != '-') 579 if (*pattern++ != '\\' || *pattern++ != '-')
591 continue; 580 continue;
592 result = tomoyo_file_matches_to_pattern2(filename, 581 result = tomoyo_file_matches_pattern2(filename,
593 filename_end, 582 filename_end,
594 pattern_start, 583 pattern_start,
595 pattern - 2); 584 pattern - 2);
596 if (first) 585 if (first)
597 result = !result; 586 result = !result;
598 if (result) 587 if (result)
@@ -600,13 +589,79 @@ static bool tomoyo_file_matches_to_pattern(const char *filename,
600 first = false; 589 first = false;
601 pattern_start = pattern; 590 pattern_start = pattern;
602 } 591 }
603 result = tomoyo_file_matches_to_pattern2(filename, filename_end, 592 result = tomoyo_file_matches_pattern2(filename, filename_end,
604 pattern_start, pattern_end); 593 pattern_start, pattern_end);
605 return first ? result : !result; 594 return first ? result : !result;
606} 595}
607 596
608/** 597/**
598 * tomoyo_path_matches_pattern2 - Do pathname pattern matching.
599 *
600 * @f: The start of string to check.
601 * @p: The start of pattern to compare.
602 *
603 * Returns true if @f matches @p, false otherwise.
604 */
605static bool tomoyo_path_matches_pattern2(const char *f, const char *p)
606{
607 const char *f_delimiter;
608 const char *p_delimiter;
609
610 while (*f && *p) {
611 f_delimiter = strchr(f, '/');
612 if (!f_delimiter)
613 f_delimiter = f + strlen(f);
614 p_delimiter = strchr(p, '/');
615 if (!p_delimiter)
616 p_delimiter = p + strlen(p);
617 if (*p == '\\' && *(p + 1) == '{')
618 goto recursive;
619 if (!tomoyo_file_matches_pattern(f, f_delimiter, p,
620 p_delimiter))
621 return false;
622 f = f_delimiter;
623 if (*f)
624 f++;
625 p = p_delimiter;
626 if (*p)
627 p++;
628 }
629 /* Ignore trailing "\*" and "\@" in @pattern. */
630 while (*p == '\\' &&
631 (*(p + 1) == '*' || *(p + 1) == '@'))
632 p += 2;
633 return !*f && !*p;
634 recursive:
635 /*
636 * The "\{" pattern is permitted only after '/' character.
637 * This guarantees that below "*(p - 1)" is safe.
638 * Also, the "\}" pattern is permitted only before '/' character
639 * so that "\{" + "\}" pair will not break the "\-" operator.
640 */
641 if (*(p - 1) != '/' || p_delimiter <= p + 3 || *p_delimiter != '/' ||
642 *(p_delimiter - 1) != '}' || *(p_delimiter - 2) != '\\')
643 return false; /* Bad pattern. */
644 do {
645 /* Compare current component with pattern. */
646 if (!tomoyo_file_matches_pattern(f, f_delimiter, p + 2,
647 p_delimiter - 2))
648 break;
649 /* Proceed to next component. */
650 f = f_delimiter;
651 if (!*f)
652 break;
653 f++;
654 /* Continue comparison. */
655 if (tomoyo_path_matches_pattern2(f, p_delimiter + 1))
656 return true;
657 f_delimiter = strchr(f, '/');
658 } while (f_delimiter);
659 return false; /* Not matched. */
660}
661
662/**
609 * tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern. 663 * tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern.
664 *
610 * @filename: The filename to check. 665 * @filename: The filename to check.
611 * @pattern: The pattern to compare. 666 * @pattern: The pattern to compare.
612 * 667 *
@@ -615,24 +670,24 @@ static bool tomoyo_file_matches_to_pattern(const char *filename,
615 * The following patterns are available. 670 * The following patterns are available.
616 * \\ \ itself. 671 * \\ \ itself.
617 * \ooo Octal representation of a byte. 672 * \ooo Octal representation of a byte.
618 * \* More than or equals to 0 character other than '/'. 673 * \* Zero or more repetitions of characters other than '/'.
619 * \@ More than or equals to 0 character other than '/' or '.'. 674 * \@ Zero or more repetitions of characters other than '/' or '.'.
620 * \? 1 byte character other than '/'. 675 * \? 1 byte character other than '/'.
621 * \$ More than or equals to 1 decimal digit. 676 * \$ One or more repetitions of decimal digits.
622 * \+ 1 decimal digit. 677 * \+ 1 decimal digit.
623 * \X More than or equals to 1 hexadecimal digit. 678 * \X One or more repetitions of hexadecimal digits.
624 * \x 1 hexadecimal digit. 679 * \x 1 hexadecimal digit.
625 * \A More than or equals to 1 alphabet character. 680 * \A One or more repetitions of alphabet characters.
626 * \a 1 alphabet character. 681 * \a 1 alphabet character.
682 *
627 * \- Subtraction operator. 683 * \- Subtraction operator.
684 *
685 * /\{dir\}/ '/' + 'One or more repetitions of dir/' (e.g. /dir/ /dir/dir/
686 * /dir/dir/dir/ ).
628 */ 687 */
629bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, 688bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
630 const struct tomoyo_path_info *pattern) 689 const struct tomoyo_path_info *pattern)
631{ 690{
632 /*
633 if (!filename || !pattern)
634 return false;
635 */
636 const char *f = filename->name; 691 const char *f = filename->name;
637 const char *p = pattern->name; 692 const char *p = pattern->name;
638 const int len = pattern->const_len; 693 const int len = pattern->const_len;
@@ -640,37 +695,15 @@ bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
640 /* If @pattern doesn't contain pattern, I can use strcmp(). */ 695 /* If @pattern doesn't contain pattern, I can use strcmp(). */
641 if (!pattern->is_patterned) 696 if (!pattern->is_patterned)
642 return !tomoyo_pathcmp(filename, pattern); 697 return !tomoyo_pathcmp(filename, pattern);
643 /* Dont compare if the number of '/' differs. */ 698 /* Don't compare directory and non-directory. */
644 if (filename->depth != pattern->depth) 699 if (filename->is_dir != pattern->is_dir)
645 return false; 700 return false;
646 /* Compare the initial length without patterns. */ 701 /* Compare the initial length without patterns. */
647 if (strncmp(f, p, len)) 702 if (strncmp(f, p, len))
648 return false; 703 return false;
649 f += len; 704 f += len;
650 p += len; 705 p += len;
651 /* Main loop. Compare each directory component. */ 706 return tomoyo_path_matches_pattern2(f, p);
652 while (*f && *p) {
653 const char *f_delimiter = strchr(f, '/');
654 const char *p_delimiter = strchr(p, '/');
655 if (!f_delimiter)
656 f_delimiter = f + strlen(f);
657 if (!p_delimiter)
658 p_delimiter = p + strlen(p);
659 if (!tomoyo_file_matches_to_pattern(f, f_delimiter,
660 p, p_delimiter))
661 return false;
662 f = f_delimiter;
663 if (*f)
664 f++;
665 p = p_delimiter;
666 if (*p)
667 p++;
668 }
669 /* Ignore trailing "\*" and "\@" in @pattern. */
670 while (*p == '\\' &&
671 (*(p + 1) == '*' || *(p + 1) == '@'))
672 p += 2;
673 return !*f && !*p;
674} 707}
675 708
676/** 709/**
@@ -706,7 +739,7 @@ bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
706 * 739 *
707 * Returns the tomoyo_realpath() of current process on success, NULL otherwise. 740 * Returns the tomoyo_realpath() of current process on success, NULL otherwise.
708 * 741 *
709 * This function uses tomoyo_alloc(), so the caller must call tomoyo_free() 742 * This function uses kzalloc(), so the caller must call kfree()
710 * if this function didn't return NULL. 743 * if this function didn't return NULL.
711 */ 744 */
712static const char *tomoyo_get_exe(void) 745static const char *tomoyo_get_exe(void)
@@ -787,6 +820,8 @@ bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain)
787 * @domain: Pointer to "struct tomoyo_domain_info". 820 * @domain: Pointer to "struct tomoyo_domain_info".
788 * 821 *
789 * Returns true if the domain is not exceeded quota, false otherwise. 822 * Returns true if the domain is not exceeded quota, false otherwise.
823 *
824 * Caller holds tomoyo_read_lock().
790 */ 825 */
791bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain) 826bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain)
792{ 827{
@@ -795,61 +830,29 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain)
795 830
796 if (!domain) 831 if (!domain)
797 return true; 832 return true;
798 down_read(&tomoyo_domain_acl_info_list_lock); 833 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
799 list_for_each_entry(ptr, &domain->acl_info_list, list) { 834 switch (ptr->type) {
800 if (ptr->type & TOMOYO_ACL_DELETED) 835 struct tomoyo_path_acl *acl;
801 continue; 836 u32 perm;
802 switch (tomoyo_acl_type2(ptr)) { 837 u8 i;
803 struct tomoyo_single_path_acl_record *acl1; 838 case TOMOYO_TYPE_PATH_ACL:
804 struct tomoyo_double_path_acl_record *acl2; 839 acl = container_of(ptr, struct tomoyo_path_acl, head);
805 u16 perm; 840 perm = acl->perm | (((u32) acl->perm_high) << 16);
806 case TOMOYO_TYPE_SINGLE_PATH_ACL: 841 for (i = 0; i < TOMOYO_MAX_PATH_OPERATION; i++)
807 acl1 = container_of(ptr, 842 if (perm & (1 << i))
808 struct tomoyo_single_path_acl_record, 843 count++;
809 head); 844 if (perm & (1 << TOMOYO_TYPE_READ_WRITE))
810 perm = acl1->perm; 845 count -= 2;
811 if (perm & (1 << TOMOYO_TYPE_EXECUTE_ACL))
812 count++;
813 if (perm &
814 ((1 << TOMOYO_TYPE_READ_ACL) |
815 (1 << TOMOYO_TYPE_WRITE_ACL)))
816 count++;
817 if (perm & (1 << TOMOYO_TYPE_CREATE_ACL))
818 count++;
819 if (perm & (1 << TOMOYO_TYPE_UNLINK_ACL))
820 count++;
821 if (perm & (1 << TOMOYO_TYPE_MKDIR_ACL))
822 count++;
823 if (perm & (1 << TOMOYO_TYPE_RMDIR_ACL))
824 count++;
825 if (perm & (1 << TOMOYO_TYPE_MKFIFO_ACL))
826 count++;
827 if (perm & (1 << TOMOYO_TYPE_MKSOCK_ACL))
828 count++;
829 if (perm & (1 << TOMOYO_TYPE_MKBLOCK_ACL))
830 count++;
831 if (perm & (1 << TOMOYO_TYPE_MKCHAR_ACL))
832 count++;
833 if (perm & (1 << TOMOYO_TYPE_TRUNCATE_ACL))
834 count++;
835 if (perm & (1 << TOMOYO_TYPE_SYMLINK_ACL))
836 count++;
837 if (perm & (1 << TOMOYO_TYPE_REWRITE_ACL))
838 count++;
839 break; 846 break;
840 case TOMOYO_TYPE_DOUBLE_PATH_ACL: 847 case TOMOYO_TYPE_PATH2_ACL:
841 acl2 = container_of(ptr, 848 perm = container_of(ptr, struct tomoyo_path2_acl, head)
842 struct tomoyo_double_path_acl_record, 849 ->perm;
843 head); 850 for (i = 0; i < TOMOYO_MAX_PATH2_OPERATION; i++)
844 perm = acl2->perm; 851 if (perm & (1 << i))
845 if (perm & (1 << TOMOYO_TYPE_LINK_ACL)) 852 count++;
846 count++;
847 if (perm & (1 << TOMOYO_TYPE_RENAME_ACL))
848 count++;
849 break; 853 break;
850 } 854 }
851 } 855 }
852 up_read(&tomoyo_domain_acl_info_list_lock);
853 if (count < tomoyo_check_flags(domain, TOMOYO_MAX_ACCEPT_ENTRY)) 856 if (count < tomoyo_check_flags(domain, TOMOYO_MAX_ACCEPT_ENTRY))
854 return true; 857 return true;
855 if (!domain->quota_warned) { 858 if (!domain->quota_warned) {
@@ -881,9 +884,12 @@ static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned
881 ptr = tomoyo_profile_ptr[profile]; 884 ptr = tomoyo_profile_ptr[profile];
882 if (ptr) 885 if (ptr)
883 goto ok; 886 goto ok;
884 ptr = tomoyo_alloc_element(sizeof(*ptr)); 887 ptr = kmalloc(sizeof(*ptr), GFP_KERNEL);
885 if (!ptr) 888 if (!tomoyo_memory_ok(ptr)) {
889 kfree(ptr);
890 ptr = NULL;
886 goto ok; 891 goto ok;
892 }
887 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) 893 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++)
888 ptr->value[i] = tomoyo_control_array[i].current_value; 894 ptr->value[i] = tomoyo_control_array[i].current_value;
889 mb(); /* Avoid out-of-order execution. */ 895 mb(); /* Avoid out-of-order execution. */
@@ -924,7 +930,9 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
924 return -EINVAL; 930 return -EINVAL;
925 *cp = '\0'; 931 *cp = '\0';
926 if (!strcmp(data, "COMMENT")) { 932 if (!strcmp(data, "COMMENT")) {
927 profile->comment = tomoyo_save_name(cp + 1); 933 const struct tomoyo_path_info *old_comment = profile->comment;
934 profile->comment = tomoyo_get_name(cp + 1);
935 tomoyo_put_name(old_comment);
928 return 0; 936 return 0;
929 } 937 }
930 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) { 938 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) {
@@ -1019,27 +1027,6 @@ static int tomoyo_read_profile(struct tomoyo_io_buffer *head)
1019} 1027}
1020 1028
1021/* 1029/*
1022 * tomoyo_policy_manager_entry is a structure which is used for holding list of
1023 * domainnames or programs which are permitted to modify configuration via
1024 * /sys/kernel/security/tomoyo/ interface.
1025 * It has following fields.
1026 *
1027 * (1) "list" which is linked to tomoyo_policy_manager_list .
1028 * (2) "manager" is a domainname or a program's pathname.
1029 * (3) "is_domain" is a bool which is true if "manager" is a domainname, false
1030 * otherwise.
1031 * (4) "is_deleted" is a bool which is true if marked as deleted, false
1032 * otherwise.
1033 */
1034struct tomoyo_policy_manager_entry {
1035 struct list_head list;
1036 /* A path to program or a domainname. */
1037 const struct tomoyo_path_info *manager;
1038 bool is_domain; /* True if manager is a domainname. */
1039 bool is_deleted; /* True if this entry is deleted. */
1040};
1041
1042/*
1043 * tomoyo_policy_manager_list is used for holding list of domainnames or 1030 * tomoyo_policy_manager_list is used for holding list of domainnames or
1044 * programs which are permitted to modify configuration via 1031 * programs which are permitted to modify configuration via
1045 * /sys/kernel/security/tomoyo/ interface. 1032 * /sys/kernel/security/tomoyo/ interface.
@@ -1069,8 +1056,7 @@ struct tomoyo_policy_manager_entry {
1069 * 1056 *
1070 * # cat /sys/kernel/security/tomoyo/manager 1057 * # cat /sys/kernel/security/tomoyo/manager
1071 */ 1058 */
1072static LIST_HEAD(tomoyo_policy_manager_list); 1059LIST_HEAD(tomoyo_policy_manager_list);
1073static DECLARE_RWSEM(tomoyo_policy_manager_list_lock);
1074 1060
1075/** 1061/**
1076 * tomoyo_update_manager_entry - Add a manager entry. 1062 * tomoyo_update_manager_entry - Add a manager entry.
@@ -1079,48 +1065,50 @@ static DECLARE_RWSEM(tomoyo_policy_manager_list_lock);
1079 * @is_delete: True if it is a delete request. 1065 * @is_delete: True if it is a delete request.
1080 * 1066 *
1081 * Returns 0 on success, negative value otherwise. 1067 * Returns 0 on success, negative value otherwise.
1068 *
1069 * Caller holds tomoyo_read_lock().
1082 */ 1070 */
1083static int tomoyo_update_manager_entry(const char *manager, 1071static int tomoyo_update_manager_entry(const char *manager,
1084 const bool is_delete) 1072 const bool is_delete)
1085{ 1073{
1086 struct tomoyo_policy_manager_entry *new_entry; 1074 struct tomoyo_policy_manager_entry *entry = NULL;
1087 struct tomoyo_policy_manager_entry *ptr; 1075 struct tomoyo_policy_manager_entry *ptr;
1088 const struct tomoyo_path_info *saved_manager; 1076 const struct tomoyo_path_info *saved_manager;
1089 int error = -ENOMEM; 1077 int error = is_delete ? -ENOENT : -ENOMEM;
1090 bool is_domain = false; 1078 bool is_domain = false;
1091 1079
1092 if (tomoyo_is_domain_def(manager)) { 1080 if (tomoyo_is_domain_def(manager)) {
1093 if (!tomoyo_is_correct_domain(manager, __func__)) 1081 if (!tomoyo_is_correct_domain(manager))
1094 return -EINVAL; 1082 return -EINVAL;
1095 is_domain = true; 1083 is_domain = true;
1096 } else { 1084 } else {
1097 if (!tomoyo_is_correct_path(manager, 1, -1, -1, __func__)) 1085 if (!tomoyo_is_correct_path(manager, 1, -1, -1))
1098 return -EINVAL; 1086 return -EINVAL;
1099 } 1087 }
1100 saved_manager = tomoyo_save_name(manager); 1088 saved_manager = tomoyo_get_name(manager);
1101 if (!saved_manager) 1089 if (!saved_manager)
1102 return -ENOMEM; 1090 return -ENOMEM;
1103 down_write(&tomoyo_policy_manager_list_lock); 1091 if (!is_delete)
1104 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) { 1092 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
1093 mutex_lock(&tomoyo_policy_lock);
1094 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
1105 if (ptr->manager != saved_manager) 1095 if (ptr->manager != saved_manager)
1106 continue; 1096 continue;
1107 ptr->is_deleted = is_delete; 1097 ptr->is_deleted = is_delete;
1108 error = 0; 1098 error = 0;
1109 goto out; 1099 break;
1110 } 1100 }
1111 if (is_delete) { 1101 if (!is_delete && error && tomoyo_memory_ok(entry)) {
1112 error = -ENOENT; 1102 entry->manager = saved_manager;
1113 goto out; 1103 saved_manager = NULL;
1104 entry->is_domain = is_domain;
1105 list_add_tail_rcu(&entry->list, &tomoyo_policy_manager_list);
1106 entry = NULL;
1107 error = 0;
1114 } 1108 }
1115 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 1109 mutex_unlock(&tomoyo_policy_lock);
1116 if (!new_entry) 1110 tomoyo_put_name(saved_manager);
1117 goto out; 1111 kfree(entry);
1118 new_entry->manager = saved_manager;
1119 new_entry->is_domain = is_domain;
1120 list_add_tail(&new_entry->list, &tomoyo_policy_manager_list);
1121 error = 0;
1122 out:
1123 up_write(&tomoyo_policy_manager_list_lock);
1124 return error; 1112 return error;
1125} 1113}
1126 1114
@@ -1130,6 +1118,8 @@ static int tomoyo_update_manager_entry(const char *manager,
1130 * @head: Pointer to "struct tomoyo_io_buffer". 1118 * @head: Pointer to "struct tomoyo_io_buffer".
1131 * 1119 *
1132 * Returns 0 on success, negative value otherwise. 1120 * Returns 0 on success, negative value otherwise.
1121 *
1122 * Caller holds tomoyo_read_lock().
1133 */ 1123 */
1134static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head) 1124static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head)
1135{ 1125{
@@ -1149,6 +1139,8 @@ static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head)
1149 * @head: Pointer to "struct tomoyo_io_buffer". 1139 * @head: Pointer to "struct tomoyo_io_buffer".
1150 * 1140 *
1151 * Returns 0. 1141 * Returns 0.
1142 *
1143 * Caller holds tomoyo_read_lock().
1152 */ 1144 */
1153static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head) 1145static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
1154{ 1146{
@@ -1157,7 +1149,6 @@ static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
1157 1149
1158 if (head->read_eof) 1150 if (head->read_eof)
1159 return 0; 1151 return 0;
1160 down_read(&tomoyo_policy_manager_list_lock);
1161 list_for_each_cookie(pos, head->read_var2, 1152 list_for_each_cookie(pos, head->read_var2,
1162 &tomoyo_policy_manager_list) { 1153 &tomoyo_policy_manager_list) {
1163 struct tomoyo_policy_manager_entry *ptr; 1154 struct tomoyo_policy_manager_entry *ptr;
@@ -1169,7 +1160,6 @@ static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
1169 if (!done) 1160 if (!done)
1170 break; 1161 break;
1171 } 1162 }
1172 up_read(&tomoyo_policy_manager_list_lock);
1173 head->read_eof = done; 1163 head->read_eof = done;
1174 return 0; 1164 return 0;
1175} 1165}
@@ -1179,6 +1169,8 @@ static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
1179 * 1169 *
1180 * Returns true if the current process is permitted to modify policy 1170 * Returns true if the current process is permitted to modify policy
1181 * via /sys/kernel/security/tomoyo/ interface. 1171 * via /sys/kernel/security/tomoyo/ interface.
1172 *
1173 * Caller holds tomoyo_read_lock().
1182 */ 1174 */
1183static bool tomoyo_is_policy_manager(void) 1175static bool tomoyo_is_policy_manager(void)
1184{ 1176{
@@ -1192,29 +1184,25 @@ static bool tomoyo_is_policy_manager(void)
1192 return true; 1184 return true;
1193 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid)) 1185 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid))
1194 return false; 1186 return false;
1195 down_read(&tomoyo_policy_manager_list_lock); 1187 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
1196 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) {
1197 if (!ptr->is_deleted && ptr->is_domain 1188 if (!ptr->is_deleted && ptr->is_domain
1198 && !tomoyo_pathcmp(domainname, ptr->manager)) { 1189 && !tomoyo_pathcmp(domainname, ptr->manager)) {
1199 found = true; 1190 found = true;
1200 break; 1191 break;
1201 } 1192 }
1202 } 1193 }
1203 up_read(&tomoyo_policy_manager_list_lock);
1204 if (found) 1194 if (found)
1205 return true; 1195 return true;
1206 exe = tomoyo_get_exe(); 1196 exe = tomoyo_get_exe();
1207 if (!exe) 1197 if (!exe)
1208 return false; 1198 return false;
1209 down_read(&tomoyo_policy_manager_list_lock); 1199 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
1210 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) {
1211 if (!ptr->is_deleted && !ptr->is_domain 1200 if (!ptr->is_deleted && !ptr->is_domain
1212 && !strcmp(exe, ptr->manager->name)) { 1201 && !strcmp(exe, ptr->manager->name)) {
1213 found = true; 1202 found = true;
1214 break; 1203 break;
1215 } 1204 }
1216 } 1205 }
1217 up_read(&tomoyo_policy_manager_list_lock);
1218 if (!found) { /* Reduce error messages. */ 1206 if (!found) { /* Reduce error messages. */
1219 static pid_t last_pid; 1207 static pid_t last_pid;
1220 const pid_t pid = current->pid; 1208 const pid_t pid = current->pid;
@@ -1224,7 +1212,7 @@ static bool tomoyo_is_policy_manager(void)
1224 last_pid = pid; 1212 last_pid = pid;
1225 } 1213 }
1226 } 1214 }
1227 tomoyo_free(exe); 1215 kfree(exe);
1228 return found; 1216 return found;
1229} 1217}
1230 1218
@@ -1235,6 +1223,8 @@ static bool tomoyo_is_policy_manager(void)
1235 * @data: String to parse. 1223 * @data: String to parse.
1236 * 1224 *
1237 * Returns true on success, false otherwise. 1225 * Returns true on success, false otherwise.
1226 *
1227 * Caller holds tomoyo_read_lock().
1238 */ 1228 */
1239static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head, 1229static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
1240 const char *data) 1230 const char *data)
@@ -1244,17 +1234,16 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
1244 1234
1245 if (sscanf(data, "pid=%u", &pid) == 1) { 1235 if (sscanf(data, "pid=%u", &pid) == 1) {
1246 struct task_struct *p; 1236 struct task_struct *p;
1237 rcu_read_lock();
1247 read_lock(&tasklist_lock); 1238 read_lock(&tasklist_lock);
1248 p = find_task_by_vpid(pid); 1239 p = find_task_by_vpid(pid);
1249 if (p) 1240 if (p)
1250 domain = tomoyo_real_domain(p); 1241 domain = tomoyo_real_domain(p);
1251 read_unlock(&tasklist_lock); 1242 read_unlock(&tasklist_lock);
1243 rcu_read_unlock();
1252 } else if (!strncmp(data, "domain=", 7)) { 1244 } else if (!strncmp(data, "domain=", 7)) {
1253 if (tomoyo_is_domain_def(data + 7)) { 1245 if (tomoyo_is_domain_def(data + 7))
1254 down_read(&tomoyo_domain_list_lock);
1255 domain = tomoyo_find_domain(data + 7); 1246 domain = tomoyo_find_domain(data + 7);
1256 up_read(&tomoyo_domain_list_lock);
1257 }
1258 } else 1247 } else
1259 return false; 1248 return false;
1260 head->write_var1 = domain; 1249 head->write_var1 = domain;
@@ -1268,13 +1257,11 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
1268 if (domain) { 1257 if (domain) {
1269 struct tomoyo_domain_info *d; 1258 struct tomoyo_domain_info *d;
1270 head->read_var1 = NULL; 1259 head->read_var1 = NULL;
1271 down_read(&tomoyo_domain_list_lock); 1260 list_for_each_entry_rcu(d, &tomoyo_domain_list, list) {
1272 list_for_each_entry(d, &tomoyo_domain_list, list) {
1273 if (d == domain) 1261 if (d == domain)
1274 break; 1262 break;
1275 head->read_var1 = &d->list; 1263 head->read_var1 = &d->list;
1276 } 1264 }
1277 up_read(&tomoyo_domain_list_lock);
1278 head->read_var2 = NULL; 1265 head->read_var2 = NULL;
1279 head->read_bit = 0; 1266 head->read_bit = 0;
1280 head->read_step = 0; 1267 head->read_step = 0;
@@ -1290,6 +1277,8 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
1290 * @domainname: The name of domain. 1277 * @domainname: The name of domain.
1291 * 1278 *
1292 * Returns 0. 1279 * Returns 0.
1280 *
1281 * Caller holds tomoyo_read_lock().
1293 */ 1282 */
1294static int tomoyo_delete_domain(char *domainname) 1283static int tomoyo_delete_domain(char *domainname)
1295{ 1284{
@@ -1298,9 +1287,9 @@ static int tomoyo_delete_domain(char *domainname)
1298 1287
1299 name.name = domainname; 1288 name.name = domainname;
1300 tomoyo_fill_path_info(&name); 1289 tomoyo_fill_path_info(&name);
1301 down_write(&tomoyo_domain_list_lock); 1290 mutex_lock(&tomoyo_policy_lock);
1302 /* Is there an active domain? */ 1291 /* Is there an active domain? */
1303 list_for_each_entry(domain, &tomoyo_domain_list, list) { 1292 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
1304 /* Never delete tomoyo_kernel_domain */ 1293 /* Never delete tomoyo_kernel_domain */
1305 if (domain == &tomoyo_kernel_domain) 1294 if (domain == &tomoyo_kernel_domain)
1306 continue; 1295 continue;
@@ -1310,7 +1299,7 @@ static int tomoyo_delete_domain(char *domainname)
1310 domain->is_deleted = true; 1299 domain->is_deleted = true;
1311 break; 1300 break;
1312 } 1301 }
1313 up_write(&tomoyo_domain_list_lock); 1302 mutex_unlock(&tomoyo_policy_lock);
1314 return 0; 1303 return 0;
1315} 1304}
1316 1305
@@ -1320,6 +1309,8 @@ static int tomoyo_delete_domain(char *domainname)
1320 * @head: Pointer to "struct tomoyo_io_buffer". 1309 * @head: Pointer to "struct tomoyo_io_buffer".
1321 * 1310 *
1322 * Returns 0 on success, negative value otherwise. 1311 * Returns 0 on success, negative value otherwise.
1312 *
1313 * Caller holds tomoyo_read_lock().
1323 */ 1314 */
1324static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head) 1315static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
1325{ 1316{
@@ -1342,11 +1333,9 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
1342 domain = NULL; 1333 domain = NULL;
1343 if (is_delete) 1334 if (is_delete)
1344 tomoyo_delete_domain(data); 1335 tomoyo_delete_domain(data);
1345 else if (is_select) { 1336 else if (is_select)
1346 down_read(&tomoyo_domain_list_lock);
1347 domain = tomoyo_find_domain(data); 1337 domain = tomoyo_find_domain(data);
1348 up_read(&tomoyo_domain_list_lock); 1338 else
1349 } else
1350 domain = tomoyo_find_or_assign_new_domain(data, 0); 1339 domain = tomoyo_find_or_assign_new_domain(data, 0);
1351 head->write_var1 = domain; 1340 head->write_var1 = domain;
1352 return 0; 1341 return 0;
@@ -1361,43 +1350,39 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
1361 return 0; 1350 return 0;
1362 } 1351 }
1363 if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) { 1352 if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
1364 tomoyo_set_domain_flag(domain, is_delete, 1353 domain->ignore_global_allow_read = !is_delete;
1365 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ);
1366 return 0; 1354 return 0;
1367 } 1355 }
1368 return tomoyo_write_file_policy(data, domain, is_delete); 1356 return tomoyo_write_file_policy(data, domain, is_delete);
1369} 1357}
1370 1358
1371/** 1359/**
1372 * tomoyo_print_single_path_acl - Print a single path ACL entry. 1360 * tomoyo_print_path_acl - Print a single path ACL entry.
1373 * 1361 *
1374 * @head: Pointer to "struct tomoyo_io_buffer". 1362 * @head: Pointer to "struct tomoyo_io_buffer".
1375 * @ptr: Pointer to "struct tomoyo_single_path_acl_record". 1363 * @ptr: Pointer to "struct tomoyo_path_acl".
1376 * 1364 *
1377 * Returns true on success, false otherwise. 1365 * Returns true on success, false otherwise.
1378 */ 1366 */
1379static bool tomoyo_print_single_path_acl(struct tomoyo_io_buffer *head, 1367static bool tomoyo_print_path_acl(struct tomoyo_io_buffer *head,
1380 struct tomoyo_single_path_acl_record * 1368 struct tomoyo_path_acl *ptr)
1381 ptr)
1382{ 1369{
1383 int pos; 1370 int pos;
1384 u8 bit; 1371 u8 bit;
1385 const char *atmark = ""; 1372 const char *atmark = "";
1386 const char *filename; 1373 const char *filename;
1387 const u16 perm = ptr->perm; 1374 const u32 perm = ptr->perm | (((u32) ptr->perm_high) << 16);
1388 1375
1389 filename = ptr->filename->name; 1376 filename = ptr->filename->name;
1390 for (bit = head->read_bit; bit < TOMOYO_MAX_SINGLE_PATH_OPERATION; 1377 for (bit = head->read_bit; bit < TOMOYO_MAX_PATH_OPERATION; bit++) {
1391 bit++) {
1392 const char *msg; 1378 const char *msg;
1393 if (!(perm & (1 << bit))) 1379 if (!(perm & (1 << bit)))
1394 continue; 1380 continue;
1395 /* Print "read/write" instead of "read" and "write". */ 1381 /* Print "read/write" instead of "read" and "write". */
1396 if ((bit == TOMOYO_TYPE_READ_ACL || 1382 if ((bit == TOMOYO_TYPE_READ || bit == TOMOYO_TYPE_WRITE)
1397 bit == TOMOYO_TYPE_WRITE_ACL) 1383 && (perm & (1 << TOMOYO_TYPE_READ_WRITE)))
1398 && (perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)))
1399 continue; 1384 continue;
1400 msg = tomoyo_sp2keyword(bit); 1385 msg = tomoyo_path2keyword(bit);
1401 pos = head->read_avail; 1386 pos = head->read_avail;
1402 if (!tomoyo_io_printf(head, "allow_%s %s%s\n", msg, 1387 if (!tomoyo_io_printf(head, "allow_%s %s%s\n", msg,
1403 atmark, filename)) 1388 atmark, filename))
@@ -1412,16 +1397,15 @@ static bool tomoyo_print_single_path_acl(struct tomoyo_io_buffer *head,
1412} 1397}
1413 1398
1414/** 1399/**
1415 * tomoyo_print_double_path_acl - Print a double path ACL entry. 1400 * tomoyo_print_path2_acl - Print a double path ACL entry.
1416 * 1401 *
1417 * @head: Pointer to "struct tomoyo_io_buffer". 1402 * @head: Pointer to "struct tomoyo_io_buffer".
1418 * @ptr: Pointer to "struct tomoyo_double_path_acl_record". 1403 * @ptr: Pointer to "struct tomoyo_path2_acl".
1419 * 1404 *
1420 * Returns true on success, false otherwise. 1405 * Returns true on success, false otherwise.
1421 */ 1406 */
1422static bool tomoyo_print_double_path_acl(struct tomoyo_io_buffer *head, 1407static bool tomoyo_print_path2_acl(struct tomoyo_io_buffer *head,
1423 struct tomoyo_double_path_acl_record * 1408 struct tomoyo_path2_acl *ptr)
1424 ptr)
1425{ 1409{
1426 int pos; 1410 int pos;
1427 const char *atmark1 = ""; 1411 const char *atmark1 = "";
@@ -1433,12 +1417,11 @@ static bool tomoyo_print_double_path_acl(struct tomoyo_io_buffer *head,
1433 1417
1434 filename1 = ptr->filename1->name; 1418 filename1 = ptr->filename1->name;
1435 filename2 = ptr->filename2->name; 1419 filename2 = ptr->filename2->name;
1436 for (bit = head->read_bit; bit < TOMOYO_MAX_DOUBLE_PATH_OPERATION; 1420 for (bit = head->read_bit; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) {
1437 bit++) {
1438 const char *msg; 1421 const char *msg;
1439 if (!(perm & (1 << bit))) 1422 if (!(perm & (1 << bit)))
1440 continue; 1423 continue;
1441 msg = tomoyo_dp2keyword(bit); 1424 msg = tomoyo_path22keyword(bit);
1442 pos = head->read_avail; 1425 pos = head->read_avail;
1443 if (!tomoyo_io_printf(head, "allow_%s %s%s %s%s\n", msg, 1426 if (!tomoyo_io_printf(head, "allow_%s %s%s %s%s\n", msg,
1444 atmark1, filename1, atmark2, filename2)) 1427 atmark1, filename1, atmark2, filename2))
@@ -1463,23 +1446,17 @@ static bool tomoyo_print_double_path_acl(struct tomoyo_io_buffer *head,
1463static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, 1446static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
1464 struct tomoyo_acl_info *ptr) 1447 struct tomoyo_acl_info *ptr)
1465{ 1448{
1466 const u8 acl_type = tomoyo_acl_type2(ptr); 1449 const u8 acl_type = ptr->type;
1467 1450
1468 if (acl_type & TOMOYO_ACL_DELETED) 1451 if (acl_type == TOMOYO_TYPE_PATH_ACL) {
1469 return true; 1452 struct tomoyo_path_acl *acl
1470 if (acl_type == TOMOYO_TYPE_SINGLE_PATH_ACL) { 1453 = container_of(ptr, struct tomoyo_path_acl, head);
1471 struct tomoyo_single_path_acl_record *acl 1454 return tomoyo_print_path_acl(head, acl);
1472 = container_of(ptr,
1473 struct tomoyo_single_path_acl_record,
1474 head);
1475 return tomoyo_print_single_path_acl(head, acl);
1476 } 1455 }
1477 if (acl_type == TOMOYO_TYPE_DOUBLE_PATH_ACL) { 1456 if (acl_type == TOMOYO_TYPE_PATH2_ACL) {
1478 struct tomoyo_double_path_acl_record *acl 1457 struct tomoyo_path2_acl *acl
1479 = container_of(ptr, 1458 = container_of(ptr, struct tomoyo_path2_acl, head);
1480 struct tomoyo_double_path_acl_record, 1459 return tomoyo_print_path2_acl(head, acl);
1481 head);
1482 return tomoyo_print_double_path_acl(head, acl);
1483 } 1460 }
1484 BUG(); /* This must not happen. */ 1461 BUG(); /* This must not happen. */
1485 return false; 1462 return false;
@@ -1491,6 +1468,8 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
1491 * @head: Pointer to "struct tomoyo_io_buffer". 1468 * @head: Pointer to "struct tomoyo_io_buffer".
1492 * 1469 *
1493 * Returns 0. 1470 * Returns 0.
1471 *
1472 * Caller holds tomoyo_read_lock().
1494 */ 1473 */
1495static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head) 1474static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
1496{ 1475{
@@ -1502,7 +1481,6 @@ static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
1502 return 0; 1481 return 0;
1503 if (head->read_step == 0) 1482 if (head->read_step == 0)
1504 head->read_step = 1; 1483 head->read_step = 1;
1505 down_read(&tomoyo_domain_list_lock);
1506 list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) { 1484 list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) {
1507 struct tomoyo_domain_info *domain; 1485 struct tomoyo_domain_info *domain;
1508 const char *quota_exceeded = ""; 1486 const char *quota_exceeded = "";
@@ -1516,10 +1494,9 @@ static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
1516 /* Print domainname and flags. */ 1494 /* Print domainname and flags. */
1517 if (domain->quota_warned) 1495 if (domain->quota_warned)
1518 quota_exceeded = "quota_exceeded\n"; 1496 quota_exceeded = "quota_exceeded\n";
1519 if (domain->flags & TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED) 1497 if (domain->transition_failed)
1520 transition_failed = "transition_failed\n"; 1498 transition_failed = "transition_failed\n";
1521 if (domain->flags & 1499 if (domain->ignore_global_allow_read)
1522 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ)
1523 ignore_global_allow_read 1500 ignore_global_allow_read
1524 = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n"; 1501 = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
1525 done = tomoyo_io_printf(head, "%s\n" TOMOYO_KEYWORD_USE_PROFILE 1502 done = tomoyo_io_printf(head, "%s\n" TOMOYO_KEYWORD_USE_PROFILE
@@ -1535,7 +1512,6 @@ acl_loop:
1535 if (head->read_step == 3) 1512 if (head->read_step == 3)
1536 goto tail_mark; 1513 goto tail_mark;
1537 /* Print ACL entries in the domain. */ 1514 /* Print ACL entries in the domain. */
1538 down_read(&tomoyo_domain_acl_info_list_lock);
1539 list_for_each_cookie(apos, head->read_var2, 1515 list_for_each_cookie(apos, head->read_var2,
1540 &domain->acl_info_list) { 1516 &domain->acl_info_list) {
1541 struct tomoyo_acl_info *ptr 1517 struct tomoyo_acl_info *ptr
@@ -1545,7 +1521,6 @@ acl_loop:
1545 if (!done) 1521 if (!done)
1546 break; 1522 break;
1547 } 1523 }
1548 up_read(&tomoyo_domain_acl_info_list_lock);
1549 if (!done) 1524 if (!done)
1550 break; 1525 break;
1551 head->read_step = 3; 1526 head->read_step = 3;
@@ -1557,7 +1532,6 @@ tail_mark:
1557 if (head->read_single_domain) 1532 if (head->read_single_domain)
1558 break; 1533 break;
1559 } 1534 }
1560 up_read(&tomoyo_domain_list_lock);
1561 head->read_eof = done; 1535 head->read_eof = done;
1562 return 0; 1536 return 0;
1563} 1537}
@@ -1573,6 +1547,8 @@ tail_mark:
1573 * 1547 *
1574 * ( echo "select " $domainname; echo "use_profile " $profile ) | 1548 * ( echo "select " $domainname; echo "use_profile " $profile ) |
1575 * /usr/lib/ccs/loadpolicy -d 1549 * /usr/lib/ccs/loadpolicy -d
1550 *
1551 * Caller holds tomoyo_read_lock().
1576 */ 1552 */
1577static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head) 1553static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
1578{ 1554{
@@ -1584,9 +1560,7 @@ static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
1584 if (!cp) 1560 if (!cp)
1585 return -EINVAL; 1561 return -EINVAL;
1586 *cp = '\0'; 1562 *cp = '\0';
1587 down_read(&tomoyo_domain_list_lock);
1588 domain = tomoyo_find_domain(cp + 1); 1563 domain = tomoyo_find_domain(cp + 1);
1589 up_read(&tomoyo_domain_list_lock);
1590 if (strict_strtoul(data, 10, &profile)) 1564 if (strict_strtoul(data, 10, &profile))
1591 return -EINVAL; 1565 return -EINVAL;
1592 if (domain && profile < TOMOYO_MAX_PROFILES 1566 if (domain && profile < TOMOYO_MAX_PROFILES
@@ -1608,6 +1582,8 @@ static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
1608 * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" ) 1582 * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" )
1609 * domainname = $0; } else if ( $1 == "use_profile" ) { 1583 * domainname = $0; } else if ( $1 == "use_profile" ) {
1610 * print $2 " " domainname; domainname = ""; } } ; ' 1584 * print $2 " " domainname; domainname = ""; } } ; '
1585 *
1586 * Caller holds tomoyo_read_lock().
1611 */ 1587 */
1612static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head) 1588static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
1613{ 1589{
@@ -1616,7 +1592,6 @@ static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
1616 1592
1617 if (head->read_eof) 1593 if (head->read_eof)
1618 return 0; 1594 return 0;
1619 down_read(&tomoyo_domain_list_lock);
1620 list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) { 1595 list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) {
1621 struct tomoyo_domain_info *domain; 1596 struct tomoyo_domain_info *domain;
1622 domain = list_entry(pos, struct tomoyo_domain_info, list); 1597 domain = list_entry(pos, struct tomoyo_domain_info, list);
@@ -1627,7 +1602,6 @@ static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
1627 if (!done) 1602 if (!done)
1628 break; 1603 break;
1629 } 1604 }
1630 up_read(&tomoyo_domain_list_lock);
1631 head->read_eof = done; 1605 head->read_eof = done;
1632 return 0; 1606 return 0;
1633} 1607}
@@ -1665,11 +1639,13 @@ static int tomoyo_read_pid(struct tomoyo_io_buffer *head)
1665 const int pid = head->read_step; 1639 const int pid = head->read_step;
1666 struct task_struct *p; 1640 struct task_struct *p;
1667 struct tomoyo_domain_info *domain = NULL; 1641 struct tomoyo_domain_info *domain = NULL;
1642 rcu_read_lock();
1668 read_lock(&tasklist_lock); 1643 read_lock(&tasklist_lock);
1669 p = find_task_by_vpid(pid); 1644 p = find_task_by_vpid(pid);
1670 if (p) 1645 if (p)
1671 domain = tomoyo_real_domain(p); 1646 domain = tomoyo_real_domain(p);
1672 read_unlock(&tasklist_lock); 1647 read_unlock(&tasklist_lock);
1648 rcu_read_unlock();
1673 if (domain) 1649 if (domain)
1674 tomoyo_io_printf(head, "%d %u %s", pid, domain->profile, 1650 tomoyo_io_printf(head, "%d %u %s", pid, domain->profile,
1675 domain->domainname->name); 1651 domain->domainname->name);
@@ -1684,6 +1660,8 @@ static int tomoyo_read_pid(struct tomoyo_io_buffer *head)
1684 * @head: Pointer to "struct tomoyo_io_buffer". 1660 * @head: Pointer to "struct tomoyo_io_buffer".
1685 * 1661 *
1686 * Returns 0 on success, negative value otherwise. 1662 * Returns 0 on success, negative value otherwise.
1663 *
1664 * Caller holds tomoyo_read_lock().
1687 */ 1665 */
1688static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) 1666static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head)
1689{ 1667{
@@ -1718,6 +1696,8 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head)
1718 * @head: Pointer to "struct tomoyo_io_buffer". 1696 * @head: Pointer to "struct tomoyo_io_buffer".
1719 * 1697 *
1720 * Returns 0 on success, -EINVAL otherwise. 1698 * Returns 0 on success, -EINVAL otherwise.
1699 *
1700 * Caller holds tomoyo_read_lock().
1721 */ 1701 */
1722static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head) 1702static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head)
1723{ 1703{
@@ -1847,15 +1827,13 @@ void tomoyo_load_policy(const char *filename)
1847 tomoyo_policy_loaded = true; 1827 tomoyo_policy_loaded = true;
1848 { /* Check all profiles currently assigned to domains are defined. */ 1828 { /* Check all profiles currently assigned to domains are defined. */
1849 struct tomoyo_domain_info *domain; 1829 struct tomoyo_domain_info *domain;
1850 down_read(&tomoyo_domain_list_lock); 1830 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
1851 list_for_each_entry(domain, &tomoyo_domain_list, list) {
1852 const u8 profile = domain->profile; 1831 const u8 profile = domain->profile;
1853 if (tomoyo_profile_ptr[profile]) 1832 if (tomoyo_profile_ptr[profile])
1854 continue; 1833 continue;
1855 panic("Profile %u (used by '%s') not defined.\n", 1834 panic("Profile %u (used by '%s') not defined.\n",
1856 profile, domain->domainname->name); 1835 profile, domain->domainname->name);
1857 } 1836 }
1858 up_read(&tomoyo_domain_list_lock);
1859 } 1837 }
1860} 1838}
1861 1839
@@ -1903,10 +1881,12 @@ static int tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
1903 * @file: Pointer to "struct file". 1881 * @file: Pointer to "struct file".
1904 * 1882 *
1905 * Associates policy handler and returns 0 on success, -ENOMEM otherwise. 1883 * Associates policy handler and returns 0 on success, -ENOMEM otherwise.
1884 *
1885 * Caller acquires tomoyo_read_lock().
1906 */ 1886 */
1907static int tomoyo_open_control(const u8 type, struct file *file) 1887static int tomoyo_open_control(const u8 type, struct file *file)
1908{ 1888{
1909 struct tomoyo_io_buffer *head = tomoyo_alloc(sizeof(*head)); 1889 struct tomoyo_io_buffer *head = kzalloc(sizeof(*head), GFP_KERNEL);
1910 1890
1911 if (!head) 1891 if (!head)
1912 return -ENOMEM; 1892 return -ENOMEM;
@@ -1967,9 +1947,9 @@ static int tomoyo_open_control(const u8 type, struct file *file)
1967 } else { 1947 } else {
1968 if (!head->readbuf_size) 1948 if (!head->readbuf_size)
1969 head->readbuf_size = 4096 * 2; 1949 head->readbuf_size = 4096 * 2;
1970 head->read_buf = tomoyo_alloc(head->readbuf_size); 1950 head->read_buf = kzalloc(head->readbuf_size, GFP_KERNEL);
1971 if (!head->read_buf) { 1951 if (!head->read_buf) {
1972 tomoyo_free(head); 1952 kfree(head);
1973 return -ENOMEM; 1953 return -ENOMEM;
1974 } 1954 }
1975 } 1955 }
@@ -1981,13 +1961,14 @@ static int tomoyo_open_control(const u8 type, struct file *file)
1981 head->write = NULL; 1961 head->write = NULL;
1982 } else if (head->write) { 1962 } else if (head->write) {
1983 head->writebuf_size = 4096 * 2; 1963 head->writebuf_size = 4096 * 2;
1984 head->write_buf = tomoyo_alloc(head->writebuf_size); 1964 head->write_buf = kzalloc(head->writebuf_size, GFP_KERNEL);
1985 if (!head->write_buf) { 1965 if (!head->write_buf) {
1986 tomoyo_free(head->read_buf); 1966 kfree(head->read_buf);
1987 tomoyo_free(head); 1967 kfree(head);
1988 return -ENOMEM; 1968 return -ENOMEM;
1989 } 1969 }
1990 } 1970 }
1971 head->reader_idx = tomoyo_read_lock();
1991 file->private_data = head; 1972 file->private_data = head;
1992 /* 1973 /*
1993 * Call the handler now if the file is 1974 * Call the handler now if the file is
@@ -2009,6 +1990,8 @@ static int tomoyo_open_control(const u8 type, struct file *file)
2009 * @buffer_len: Size of @buffer. 1990 * @buffer_len: Size of @buffer.
2010 * 1991 *
2011 * Returns bytes read on success, negative value otherwise. 1992 * Returns bytes read on success, negative value otherwise.
1993 *
1994 * Caller holds tomoyo_read_lock().
2012 */ 1995 */
2013static int tomoyo_read_control(struct file *file, char __user *buffer, 1996static int tomoyo_read_control(struct file *file, char __user *buffer,
2014 const int buffer_len) 1997 const int buffer_len)
@@ -2052,6 +2035,8 @@ static int tomoyo_read_control(struct file *file, char __user *buffer,
2052 * @buffer_len: Size of @buffer. 2035 * @buffer_len: Size of @buffer.
2053 * 2036 *
2054 * Returns @buffer_len on success, negative value otherwise. 2037 * Returns @buffer_len on success, negative value otherwise.
2038 *
2039 * Caller holds tomoyo_read_lock().
2055 */ 2040 */
2056static int tomoyo_write_control(struct file *file, const char __user *buffer, 2041static int tomoyo_write_control(struct file *file, const char __user *buffer,
2057 const int buffer_len) 2042 const int buffer_len)
@@ -2102,52 +2087,29 @@ static int tomoyo_write_control(struct file *file, const char __user *buffer,
2102 * @file: Pointer to "struct file". 2087 * @file: Pointer to "struct file".
2103 * 2088 *
2104 * Releases memory and returns 0. 2089 * Releases memory and returns 0.
2090 *
2091 * Caller looses tomoyo_read_lock().
2105 */ 2092 */
2106static int tomoyo_close_control(struct file *file) 2093static int tomoyo_close_control(struct file *file)
2107{ 2094{
2108 struct tomoyo_io_buffer *head = file->private_data; 2095 struct tomoyo_io_buffer *head = file->private_data;
2096 const bool is_write = !!head->write_buf;
2109 2097
2098 tomoyo_read_unlock(head->reader_idx);
2110 /* Release memory used for policy I/O. */ 2099 /* Release memory used for policy I/O. */
2111 tomoyo_free(head->read_buf); 2100 kfree(head->read_buf);
2112 head->read_buf = NULL; 2101 head->read_buf = NULL;
2113 tomoyo_free(head->write_buf); 2102 kfree(head->write_buf);
2114 head->write_buf = NULL; 2103 head->write_buf = NULL;
2115 tomoyo_free(head); 2104 kfree(head);
2116 head = NULL; 2105 head = NULL;
2117 file->private_data = NULL; 2106 file->private_data = NULL;
2107 if (is_write)
2108 tomoyo_run_gc();
2118 return 0; 2109 return 0;
2119} 2110}
2120 2111
2121/** 2112/**
2122 * tomoyo_alloc_acl_element - Allocate permanent memory for ACL entry.
2123 *
2124 * @acl_type: Type of ACL entry.
2125 *
2126 * Returns pointer to the ACL entry on success, NULL otherwise.
2127 */
2128void *tomoyo_alloc_acl_element(const u8 acl_type)
2129{
2130 int len;
2131 struct tomoyo_acl_info *ptr;
2132
2133 switch (acl_type) {
2134 case TOMOYO_TYPE_SINGLE_PATH_ACL:
2135 len = sizeof(struct tomoyo_single_path_acl_record);
2136 break;
2137 case TOMOYO_TYPE_DOUBLE_PATH_ACL:
2138 len = sizeof(struct tomoyo_double_path_acl_record);
2139 break;
2140 default:
2141 return NULL;
2142 }
2143 ptr = tomoyo_alloc_element(len);
2144 if (!ptr)
2145 return NULL;
2146 ptr->type = acl_type;
2147 return ptr;
2148}
2149
2150/**
2151 * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface. 2113 * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface.
2152 * 2114 *
2153 * @inode: Pointer to "struct inode". 2115 * @inode: Pointer to "struct inode".
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 31df541911f7..67bd22dd3e68 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -1,12 +1,9 @@
1/* 1/*
2 * security/tomoyo/common.h 2 * security/tomoyo/common.h
3 * 3 *
4 * Common functions for TOMOYO. 4 * Header file for TOMOYO.
5 *
6 * Copyright (C) 2005-2009 NTT DATA CORPORATION
7 *
8 * Version: 2.2.0 2009/04/01
9 * 5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
10 */ 7 */
11 8
12#ifndef _SECURITY_TOMOYO_COMMON_H 9#ifndef _SECURITY_TOMOYO_COMMON_H
@@ -22,9 +19,119 @@
22#include <linux/namei.h> 19#include <linux/namei.h>
23#include <linux/mount.h> 20#include <linux/mount.h>
24#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/cred.h>
23struct linux_binprm;
24
25/********** Constants definitions. **********/
26
27/*
28 * TOMOYO uses this hash only when appending a string into the string
29 * table. Frequency of appending strings is very low. So we don't need
30 * large (e.g. 64k) hash size. 256 will be sufficient.
31 */
32#define TOMOYO_HASH_BITS 8
33#define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS)
34
35/*
36 * This is the max length of a token.
37 *
38 * A token consists of only ASCII printable characters.
39 * Non printable characters in a token is represented in \ooo style
40 * octal string. Thus, \ itself is represented as \\.
41 */
42#define TOMOYO_MAX_PATHNAME_LEN 4000
43
44/* Profile number is an integer between 0 and 255. */
45#define TOMOYO_MAX_PROFILES 256
46
47/* Keywords for ACLs. */
48#define TOMOYO_KEYWORD_ALIAS "alias "
49#define TOMOYO_KEYWORD_ALLOW_READ "allow_read "
50#define TOMOYO_KEYWORD_DELETE "delete "
51#define TOMOYO_KEYWORD_DENY_REWRITE "deny_rewrite "
52#define TOMOYO_KEYWORD_FILE_PATTERN "file_pattern "
53#define TOMOYO_KEYWORD_INITIALIZE_DOMAIN "initialize_domain "
54#define TOMOYO_KEYWORD_KEEP_DOMAIN "keep_domain "
55#define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain "
56#define TOMOYO_KEYWORD_NO_KEEP_DOMAIN "no_keep_domain "
57#define TOMOYO_KEYWORD_SELECT "select "
58#define TOMOYO_KEYWORD_USE_PROFILE "use_profile "
59#define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read"
60/* A domain definition starts with <kernel>. */
61#define TOMOYO_ROOT_NAME "<kernel>"
62#define TOMOYO_ROOT_NAME_LEN (sizeof(TOMOYO_ROOT_NAME) - 1)
63
64/* Index numbers for Access Controls. */
65enum tomoyo_mac_index {
66 TOMOYO_MAC_FOR_FILE, /* domain_policy.conf */
67 TOMOYO_MAX_ACCEPT_ENTRY,
68 TOMOYO_VERBOSE,
69 TOMOYO_MAX_CONTROL_INDEX
70};
71
72/* Index numbers for Access Controls. */
73enum tomoyo_acl_entry_type_index {
74 TOMOYO_TYPE_PATH_ACL,
75 TOMOYO_TYPE_PATH2_ACL,
76};
77
78/* Index numbers for File Controls. */
79
80/*
81 * TYPE_READ_WRITE_ACL is special. TYPE_READ_WRITE_ACL is automatically set
82 * if both TYPE_READ_ACL and TYPE_WRITE_ACL are set. Both TYPE_READ_ACL and
83 * TYPE_WRITE_ACL are automatically set if TYPE_READ_WRITE_ACL is set.
84 * TYPE_READ_WRITE_ACL is automatically cleared if either TYPE_READ_ACL or
85 * TYPE_WRITE_ACL is cleared. Both TYPE_READ_ACL and TYPE_WRITE_ACL are
86 * automatically cleared if TYPE_READ_WRITE_ACL is cleared.
87 */
88
89enum tomoyo_path_acl_index {
90 TOMOYO_TYPE_READ_WRITE,
91 TOMOYO_TYPE_EXECUTE,
92 TOMOYO_TYPE_READ,
93 TOMOYO_TYPE_WRITE,
94 TOMOYO_TYPE_CREATE,
95 TOMOYO_TYPE_UNLINK,
96 TOMOYO_TYPE_MKDIR,
97 TOMOYO_TYPE_RMDIR,
98 TOMOYO_TYPE_MKFIFO,
99 TOMOYO_TYPE_MKSOCK,
100 TOMOYO_TYPE_MKBLOCK,
101 TOMOYO_TYPE_MKCHAR,
102 TOMOYO_TYPE_TRUNCATE,
103 TOMOYO_TYPE_SYMLINK,
104 TOMOYO_TYPE_REWRITE,
105 TOMOYO_TYPE_IOCTL,
106 TOMOYO_TYPE_CHMOD,
107 TOMOYO_TYPE_CHOWN,
108 TOMOYO_TYPE_CHGRP,
109 TOMOYO_TYPE_CHROOT,
110 TOMOYO_TYPE_MOUNT,
111 TOMOYO_TYPE_UMOUNT,
112 TOMOYO_MAX_PATH_OPERATION
113};
25 114
26struct dentry; 115enum tomoyo_path2_acl_index {
27struct vfsmount; 116 TOMOYO_TYPE_LINK,
117 TOMOYO_TYPE_RENAME,
118 TOMOYO_TYPE_PIVOT_ROOT,
119 TOMOYO_MAX_PATH2_OPERATION
120};
121
122enum tomoyo_securityfs_interface_index {
123 TOMOYO_DOMAINPOLICY,
124 TOMOYO_EXCEPTIONPOLICY,
125 TOMOYO_DOMAIN_STATUS,
126 TOMOYO_PROCESS_STATUS,
127 TOMOYO_MEMINFO,
128 TOMOYO_SELFDOMAIN,
129 TOMOYO_VERSION,
130 TOMOYO_PROFILE,
131 TOMOYO_MANAGER
132};
133
134/********** Structure definitions. **********/
28 135
29/* 136/*
30 * tomoyo_page_buffer is a structure which is used for holding a pathname 137 * tomoyo_page_buffer is a structure which is used for holding a pathname
@@ -56,9 +163,6 @@ struct tomoyo_page_buffer {
56 * (5) "is_patterned" is a bool which is true if "name" contains wildcard 163 * (5) "is_patterned" is a bool which is true if "name" contains wildcard
57 * characters, false otherwise. This allows TOMOYO to use "hash" and 164 * characters, false otherwise. This allows TOMOYO to use "hash" and
58 * strcmp() for string comparison if "is_patterned" is false. 165 * strcmp() for string comparison if "is_patterned" is false.
59 * (6) "depth" is calculated using the number of "/" characters in "name".
60 * This allows TOMOYO to avoid comparing two pathnames which never match
61 * (e.g. whether "/var/www/html/index.html" matches "/tmp/sh-thd-\$").
62 */ 166 */
63struct tomoyo_path_info { 167struct tomoyo_path_info {
64 const char *name; 168 const char *name;
@@ -66,17 +170,17 @@ struct tomoyo_path_info {
66 u16 const_len; /* = tomoyo_const_part_length(name) */ 170 u16 const_len; /* = tomoyo_const_part_length(name) */
67 bool is_dir; /* = tomoyo_strendswith(name, "/") */ 171 bool is_dir; /* = tomoyo_strendswith(name, "/") */
68 bool is_patterned; /* = tomoyo_path_contains_pattern(name) */ 172 bool is_patterned; /* = tomoyo_path_contains_pattern(name) */
69 u16 depth; /* = tomoyo_path_depth(name) */
70}; 173};
71 174
72/* 175/*
73 * This is the max length of a token. 176 * tomoyo_name_entry is a structure which is used for linking
74 * 177 * "struct tomoyo_path_info" into tomoyo_name_list .
75 * A token consists of only ASCII printable characters.
76 * Non printable characters in a token is represented in \ooo style
77 * octal string. Thus, \ itself is represented as \\.
78 */ 178 */
79#define TOMOYO_MAX_PATHNAME_LEN 4000 179struct tomoyo_name_entry {
180 struct list_head list;
181 atomic_t users;
182 struct tomoyo_path_info entry;
183};
80 184
81/* 185/*
82 * tomoyo_path_info_with_data is a structure which is used for holding a 186 * tomoyo_path_info_with_data is a structure which is used for holding a
@@ -93,7 +197,7 @@ struct tomoyo_path_info {
93 * "struct tomoyo_path_info_with_data". 197 * "struct tomoyo_path_info_with_data".
94 */ 198 */
95struct tomoyo_path_info_with_data { 199struct tomoyo_path_info_with_data {
96 /* Keep "head" first, for this pointer is passed to tomoyo_free(). */ 200 /* Keep "head" first, for this pointer is passed to kfree(). */
97 struct tomoyo_path_info head; 201 struct tomoyo_path_info head;
98 char barrier1[16]; /* Safeguard for overrun. */ 202 char barrier1[16]; /* Safeguard for overrun. */
99 char body[TOMOYO_MAX_PATHNAME_LEN]; 203 char body[TOMOYO_MAX_PATHNAME_LEN];
@@ -105,30 +209,19 @@ struct tomoyo_path_info_with_data {
105 * 209 *
106 * (1) "list" which is linked to the ->acl_info_list of 210 * (1) "list" which is linked to the ->acl_info_list of
107 * "struct tomoyo_domain_info" 211 * "struct tomoyo_domain_info"
108 * (2) "type" which tells 212 * (2) "type" which tells type of the entry (either
109 * (a) type & 0x7F : type of the entry (either 213 * "struct tomoyo_path_acl" or "struct tomoyo_path2_acl").
110 * "struct tomoyo_single_path_acl_record" or
111 * "struct tomoyo_double_path_acl_record")
112 * (b) type & 0x80 : whether the entry is marked as "deleted".
113 * 214 *
114 * Packing "struct tomoyo_acl_info" allows 215 * Packing "struct tomoyo_acl_info" allows
115 * "struct tomoyo_single_path_acl_record" to embed "u16" and 216 * "struct tomoyo_path_acl" to embed "u8" + "u16" and
116 * "struct tomoyo_double_path_acl_record" to embed "u8" 217 * "struct tomoyo_path2_acl" to embed "u8"
117 * without enlarging their structure size. 218 * without enlarging their structure size.
118 */ 219 */
119struct tomoyo_acl_info { 220struct tomoyo_acl_info {
120 struct list_head list; 221 struct list_head list;
121 /*
122 * Type of this ACL entry.
123 *
124 * MSB is is_deleted flag.
125 */
126 u8 type; 222 u8 type;
127} __packed; 223} __packed;
128 224
129/* This ACL entry is deleted. */
130#define TOMOYO_ACL_DELETED 0x80
131
132/* 225/*
133 * tomoyo_domain_info is a structure which is used for holding permissions 226 * tomoyo_domain_info is a structure which is used for holding permissions
134 * (e.g. "allow_read /lib/libc-2.5.so") given to each domain. 227 * (e.g. "allow_read /lib/libc-2.5.so") given to each domain.
@@ -142,7 +235,17 @@ struct tomoyo_acl_info {
142 * "deleted", false otherwise. 235 * "deleted", false otherwise.
143 * (6) "quota_warned" is a bool which is used for suppressing warning message 236 * (6) "quota_warned" is a bool which is used for suppressing warning message
144 * when learning mode learned too much entries. 237 * when learning mode learned too much entries.
145 * (7) "flags" which remembers this domain's attributes. 238 * (7) "ignore_global_allow_read" is a bool which is true if this domain
239 * should ignore "allow_read" directive in exception policy.
240 * (8) "transition_failed" is a bool which is set to true when this domain was
241 * unable to create a new domain at tomoyo_find_next_domain() because the
242 * name of the domain to be created was too long or it could not allocate
243 * memory. If set to true, more than one process continued execve()
244 * without domain transition.
245 * (9) "users" is an atomic_t that holds how many "struct cred"->security
246 * are referring this "struct tomoyo_domain_info". If is_deleted == true
247 * and users == 0, this struct will be kfree()d upon next garbage
248 * collection.
146 * 249 *
147 * A domain's lifecycle is an analogy of files on / directory. 250 * A domain's lifecycle is an analogy of files on / directory.
148 * Multiple domains with the same domainname cannot be created (as with 251 * Multiple domains with the same domainname cannot be created (as with
@@ -159,25 +262,13 @@ struct tomoyo_domain_info {
159 u8 profile; /* Profile number to use. */ 262 u8 profile; /* Profile number to use. */
160 bool is_deleted; /* Delete flag. */ 263 bool is_deleted; /* Delete flag. */
161 bool quota_warned; /* Quota warnning flag. */ 264 bool quota_warned; /* Quota warnning flag. */
162 /* DOMAIN_FLAGS_*. Use tomoyo_set_domain_flag() to modify. */ 265 bool ignore_global_allow_read; /* Ignore "allow_read" flag. */
163 u8 flags; 266 bool transition_failed; /* Domain transition failed flag. */
267 atomic_t users; /* Number of referring credentials. */
164}; 268};
165 269
166/* Profile number is an integer between 0 and 255. */
167#define TOMOYO_MAX_PROFILES 256
168
169/* Ignore "allow_read" directive in exception policy. */
170#define TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ 1
171/*
172 * This domain was unable to create a new domain at tomoyo_find_next_domain()
173 * because the name of the domain to be created was too long or
174 * it could not allocate memory.
175 * More than one process continued execve() without domain transition.
176 */
177#define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED 2
178
179/* 270/*
180 * tomoyo_single_path_acl_record is a structure which is used for holding an 271 * tomoyo_path_acl is a structure which is used for holding an
181 * entry with one pathname operation (e.g. open(), mkdir()). 272 * entry with one pathname operation (e.g. open(), mkdir()).
182 * It has following fields. 273 * It has following fields.
183 * 274 *
@@ -188,18 +279,21 @@ struct tomoyo_domain_info {
188 * Directives held by this structure are "allow_read/write", "allow_execute", 279 * Directives held by this structure are "allow_read/write", "allow_execute",
189 * "allow_read", "allow_write", "allow_create", "allow_unlink", "allow_mkdir", 280 * "allow_read", "allow_write", "allow_create", "allow_unlink", "allow_mkdir",
190 * "allow_rmdir", "allow_mkfifo", "allow_mksock", "allow_mkblock", 281 * "allow_rmdir", "allow_mkfifo", "allow_mksock", "allow_mkblock",
191 * "allow_mkchar", "allow_truncate", "allow_symlink" and "allow_rewrite". 282 * "allow_mkchar", "allow_truncate", "allow_symlink", "allow_rewrite",
283 * "allow_chmod", "allow_chown", "allow_chgrp", "allow_chroot", "allow_mount"
284 * and "allow_unmount".
192 */ 285 */
193struct tomoyo_single_path_acl_record { 286struct tomoyo_path_acl {
194 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_SINGLE_PATH_ACL */ 287 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_ACL */
288 u8 perm_high;
195 u16 perm; 289 u16 perm;
196 /* Pointer to single pathname. */ 290 /* Pointer to single pathname. */
197 const struct tomoyo_path_info *filename; 291 const struct tomoyo_path_info *filename;
198}; 292};
199 293
200/* 294/*
201 * tomoyo_double_path_acl_record is a structure which is used for holding an 295 * tomoyo_path2_acl is a structure which is used for holding an
202 * entry with two pathnames operation (i.e. link() and rename()). 296 * entry with two pathnames operation (i.e. link(), rename() and pivot_root()).
203 * It has following fields. 297 * It has following fields.
204 * 298 *
205 * (1) "head" which is a "struct tomoyo_acl_info". 299 * (1) "head" which is a "struct tomoyo_acl_info".
@@ -207,10 +301,11 @@ struct tomoyo_single_path_acl_record {
207 * (3) "filename1" is the source/old pathname. 301 * (3) "filename1" is the source/old pathname.
208 * (4) "filename2" is the destination/new pathname. 302 * (4) "filename2" is the destination/new pathname.
209 * 303 *
210 * Directives held by this structure are "allow_rename" and "allow_link". 304 * Directives held by this structure are "allow_rename", "allow_link" and
305 * "allow_pivot_root".
211 */ 306 */
212struct tomoyo_double_path_acl_record { 307struct tomoyo_path2_acl {
213 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_DOUBLE_PATH_ACL */ 308 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH2_ACL */
214 u8 perm; 309 u8 perm;
215 /* Pointer to single pathname. */ 310 /* Pointer to single pathname. */
216 const struct tomoyo_path_info *filename1; 311 const struct tomoyo_path_info *filename1;
@@ -218,29 +313,6 @@ struct tomoyo_double_path_acl_record {
218 const struct tomoyo_path_info *filename2; 313 const struct tomoyo_path_info *filename2;
219}; 314};
220 315
221/* Keywords for ACLs. */
222#define TOMOYO_KEYWORD_ALIAS "alias "
223#define TOMOYO_KEYWORD_ALLOW_READ "allow_read "
224#define TOMOYO_KEYWORD_DELETE "delete "
225#define TOMOYO_KEYWORD_DENY_REWRITE "deny_rewrite "
226#define TOMOYO_KEYWORD_FILE_PATTERN "file_pattern "
227#define TOMOYO_KEYWORD_INITIALIZE_DOMAIN "initialize_domain "
228#define TOMOYO_KEYWORD_KEEP_DOMAIN "keep_domain "
229#define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain "
230#define TOMOYO_KEYWORD_NO_KEEP_DOMAIN "no_keep_domain "
231#define TOMOYO_KEYWORD_SELECT "select "
232#define TOMOYO_KEYWORD_USE_PROFILE "use_profile "
233#define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read"
234/* A domain definition starts with <kernel>. */
235#define TOMOYO_ROOT_NAME "<kernel>"
236#define TOMOYO_ROOT_NAME_LEN (sizeof(TOMOYO_ROOT_NAME) - 1)
237
238/* Index numbers for Access Controls. */
239#define TOMOYO_MAC_FOR_FILE 0 /* domain_policy.conf */
240#define TOMOYO_MAX_ACCEPT_ENTRY 1
241#define TOMOYO_VERBOSE 2
242#define TOMOYO_MAX_CONTROL_INDEX 3
243
244/* 316/*
245 * tomoyo_io_buffer is a structure which is used for reading and modifying 317 * tomoyo_io_buffer is a structure which is used for reading and modifying
246 * configuration via /sys/kernel/security/tomoyo/ interface. 318 * configuration via /sys/kernel/security/tomoyo/ interface.
@@ -269,6 +341,8 @@ struct tomoyo_io_buffer {
269 int (*write) (struct tomoyo_io_buffer *); 341 int (*write) (struct tomoyo_io_buffer *);
270 /* Exclusive lock for this structure. */ 342 /* Exclusive lock for this structure. */
271 struct mutex io_sem; 343 struct mutex io_sem;
344 /* Index returned by tomoyo_read_lock(). */
345 int reader_idx;
272 /* The position currently reading from. */ 346 /* The position currently reading from. */
273 struct list_head *read_var1; 347 struct list_head *read_var1;
274 /* Extra variables for reading. */ 348 /* Extra variables for reading. */
@@ -297,18 +371,159 @@ struct tomoyo_io_buffer {
297 int writebuf_size; 371 int writebuf_size;
298}; 372};
299 373
374/*
375 * tomoyo_globally_readable_file_entry is a structure which is used for holding
376 * "allow_read" entries.
377 * It has following fields.
378 *
379 * (1) "list" which is linked to tomoyo_globally_readable_list .
380 * (2) "filename" is a pathname which is allowed to open(O_RDONLY).
381 * (3) "is_deleted" is a bool which is true if marked as deleted, false
382 * otherwise.
383 */
384struct tomoyo_globally_readable_file_entry {
385 struct list_head list;
386 const struct tomoyo_path_info *filename;
387 bool is_deleted;
388};
389
390/*
391 * tomoyo_pattern_entry is a structure which is used for holding
392 * "tomoyo_pattern_list" entries.
393 * It has following fields.
394 *
395 * (1) "list" which is linked to tomoyo_pattern_list .
396 * (2) "pattern" is a pathname pattern which is used for converting pathnames
397 * to pathname patterns during learning mode.
398 * (3) "is_deleted" is a bool which is true if marked as deleted, false
399 * otherwise.
400 */
401struct tomoyo_pattern_entry {
402 struct list_head list;
403 const struct tomoyo_path_info *pattern;
404 bool is_deleted;
405};
406
407/*
408 * tomoyo_no_rewrite_entry is a structure which is used for holding
409 * "deny_rewrite" entries.
410 * It has following fields.
411 *
412 * (1) "list" which is linked to tomoyo_no_rewrite_list .
413 * (2) "pattern" is a pathname which is by default not permitted to modify
414 * already existing content.
415 * (3) "is_deleted" is a bool which is true if marked as deleted, false
416 * otherwise.
417 */
418struct tomoyo_no_rewrite_entry {
419 struct list_head list;
420 const struct tomoyo_path_info *pattern;
421 bool is_deleted;
422};
423
424/*
425 * tomoyo_domain_initializer_entry is a structure which is used for holding
426 * "initialize_domain" and "no_initialize_domain" entries.
427 * It has following fields.
428 *
429 * (1) "list" which is linked to tomoyo_domain_initializer_list .
430 * (2) "domainname" which is "a domainname" or "the last component of a
431 * domainname". This field is NULL if "from" clause is not specified.
432 * (3) "program" which is a program's pathname.
433 * (4) "is_deleted" is a bool which is true if marked as deleted, false
434 * otherwise.
435 * (5) "is_not" is a bool which is true if "no_initialize_domain", false
436 * otherwise.
437 * (6) "is_last_name" is a bool which is true if "domainname" is "the last
438 * component of a domainname", false otherwise.
439 */
440struct tomoyo_domain_initializer_entry {
441 struct list_head list;
442 const struct tomoyo_path_info *domainname; /* This may be NULL */
443 const struct tomoyo_path_info *program;
444 bool is_deleted;
445 bool is_not; /* True if this entry is "no_initialize_domain". */
446 /* True if the domainname is tomoyo_get_last_name(). */
447 bool is_last_name;
448};
449
450/*
451 * tomoyo_domain_keeper_entry is a structure which is used for holding
452 * "keep_domain" and "no_keep_domain" entries.
453 * It has following fields.
454 *
455 * (1) "list" which is linked to tomoyo_domain_keeper_list .
456 * (2) "domainname" which is "a domainname" or "the last component of a
457 * domainname".
458 * (3) "program" which is a program's pathname.
459 * This field is NULL if "from" clause is not specified.
460 * (4) "is_deleted" is a bool which is true if marked as deleted, false
461 * otherwise.
462 * (5) "is_not" is a bool which is true if "no_initialize_domain", false
463 * otherwise.
464 * (6) "is_last_name" is a bool which is true if "domainname" is "the last
465 * component of a domainname", false otherwise.
466 */
467struct tomoyo_domain_keeper_entry {
468 struct list_head list;
469 const struct tomoyo_path_info *domainname;
470 const struct tomoyo_path_info *program; /* This may be NULL */
471 bool is_deleted;
472 bool is_not; /* True if this entry is "no_keep_domain". */
473 /* True if the domainname is tomoyo_get_last_name(). */
474 bool is_last_name;
475};
476
477/*
478 * tomoyo_alias_entry is a structure which is used for holding "alias" entries.
479 * It has following fields.
480 *
481 * (1) "list" which is linked to tomoyo_alias_list .
482 * (2) "original_name" which is a dereferenced pathname.
483 * (3) "aliased_name" which is a symlink's pathname.
484 * (4) "is_deleted" is a bool which is true if marked as deleted, false
485 * otherwise.
486 */
487struct tomoyo_alias_entry {
488 struct list_head list;
489 const struct tomoyo_path_info *original_name;
490 const struct tomoyo_path_info *aliased_name;
491 bool is_deleted;
492};
493
494/*
495 * tomoyo_policy_manager_entry is a structure which is used for holding list of
496 * domainnames or programs which are permitted to modify configuration via
497 * /sys/kernel/security/tomoyo/ interface.
498 * It has following fields.
499 *
500 * (1) "list" which is linked to tomoyo_policy_manager_list .
501 * (2) "manager" is a domainname or a program's pathname.
502 * (3) "is_domain" is a bool which is true if "manager" is a domainname, false
503 * otherwise.
504 * (4) "is_deleted" is a bool which is true if marked as deleted, false
505 * otherwise.
506 */
507struct tomoyo_policy_manager_entry {
508 struct list_head list;
509 /* A path to program or a domainname. */
510 const struct tomoyo_path_info *manager;
511 bool is_domain; /* True if manager is a domainname. */
512 bool is_deleted; /* True if this entry is deleted. */
513};
514
515/********** Function prototypes. **********/
516
300/* Check whether the domain has too many ACL entries to hold. */ 517/* Check whether the domain has too many ACL entries to hold. */
301bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain); 518bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain);
302/* Transactional sprintf() for policy dump. */ 519/* Transactional sprintf() for policy dump. */
303bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 520bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
304 __attribute__ ((format(printf, 2, 3))); 521 __attribute__ ((format(printf, 2, 3)));
305/* Check whether the domainname is correct. */ 522/* Check whether the domainname is correct. */
306bool tomoyo_is_correct_domain(const unsigned char *domainname, 523bool tomoyo_is_correct_domain(const unsigned char *domainname);
307 const char *function);
308/* Check whether the token is correct. */ 524/* Check whether the token is correct. */
309bool tomoyo_is_correct_path(const char *filename, const s8 start_type, 525bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
310 const s8 pattern_type, const s8 end_type, 526 const s8 pattern_type, const s8 end_type);
311 const char *function);
312/* Check whether the token can be a domainname. */ 527/* Check whether the token can be a domainname. */
313bool tomoyo_is_domain_def(const unsigned char *buffer); 528bool tomoyo_is_domain_def(const unsigned char *buffer);
314/* Check whether the given filename matches the given pattern. */ 529/* Check whether the given filename matches the given pattern. */
@@ -332,13 +547,13 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head);
332/* Write domain policy violation warning message to console? */ 547/* Write domain policy violation warning message to console? */
333bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain); 548bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain);
334/* Convert double path operation to operation name. */ 549/* Convert double path operation to operation name. */
335const char *tomoyo_dp2keyword(const u8 operation); 550const char *tomoyo_path22keyword(const u8 operation);
336/* Get the last component of the given domainname. */ 551/* Get the last component of the given domainname. */
337const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain); 552const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain);
338/* Get warning message. */ 553/* Get warning message. */
339const char *tomoyo_get_msg(const bool is_enforce); 554const char *tomoyo_get_msg(const bool is_enforce);
340/* Convert single path operation to operation name. */ 555/* Convert single path operation to operation name. */
341const char *tomoyo_sp2keyword(const u8 operation); 556const char *tomoyo_path2keyword(const u8 operation);
342/* Create "alias" entry in exception policy. */ 557/* Create "alias" entry in exception policy. */
343int tomoyo_write_alias_policy(char *data, const bool is_delete); 558int tomoyo_write_alias_policy(char *data, const bool is_delete);
344/* 559/*
@@ -374,33 +589,107 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
374/* Check mode for specified functionality. */ 589/* Check mode for specified functionality. */
375unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain, 590unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
376 const u8 index); 591 const u8 index);
377/* Allocate memory for structures. */
378void *tomoyo_alloc_acl_element(const u8 acl_type);
379/* Fill in "struct tomoyo_path_info" members. */ 592/* Fill in "struct tomoyo_path_info" members. */
380void tomoyo_fill_path_info(struct tomoyo_path_info *ptr); 593void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
381/* Run policy loader when /sbin/init starts. */ 594/* Run policy loader when /sbin/init starts. */
382void tomoyo_load_policy(const char *filename); 595void tomoyo_load_policy(const char *filename);
383/* Change "struct tomoyo_domain_info"->flags. */
384void tomoyo_set_domain_flag(struct tomoyo_domain_info *domain,
385 const bool is_delete, const u8 flags);
386 596
387/* strcmp() for "struct tomoyo_path_info" structure. */ 597/* Convert binary string to ascii string. */
388static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a, 598int tomoyo_encode(char *buffer, int buflen, const char *str);
389 const struct tomoyo_path_info *b) 599
600/* Returns realpath(3) of the given pathname but ignores chroot'ed root. */
601int tomoyo_realpath_from_path2(struct path *path, char *newname,
602 int newname_len);
603
604/*
605 * Returns realpath(3) of the given pathname but ignores chroot'ed root.
606 * These functions use kzalloc(), so the caller must call kfree()
607 * if these functions didn't return NULL.
608 */
609char *tomoyo_realpath(const char *pathname);
610/*
611 * Same with tomoyo_realpath() except that it doesn't follow the final symlink.
612 */
613char *tomoyo_realpath_nofollow(const char *pathname);
614/* Same with tomoyo_realpath() except that the pathname is already solved. */
615char *tomoyo_realpath_from_path(struct path *path);
616
617/* Check memory quota. */
618bool tomoyo_memory_ok(void *ptr);
619
620/*
621 * Keep the given name on the RAM.
622 * The RAM is shared, so NEVER try to modify or kfree() the returned name.
623 */
624const struct tomoyo_path_info *tomoyo_get_name(const char *name);
625
626/* Check for memory usage. */
627int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head);
628
629/* Set memory quota. */
630int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head);
631
632/* Initialize realpath related code. */
633void __init tomoyo_realpath_init(void);
634int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain,
635 const struct tomoyo_path_info *filename);
636int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
637 struct path *path, const int flag);
638int tomoyo_path_perm(const u8 operation, struct path *path);
639int tomoyo_path2_perm(const u8 operation, struct path *path1,
640 struct path *path2);
641int tomoyo_check_rewrite_permission(struct file *filp);
642int tomoyo_find_next_domain(struct linux_binprm *bprm);
643
644/* Run garbage collector. */
645void tomoyo_run_gc(void);
646
647void tomoyo_memory_free(void *ptr);
648
649/********** External variable definitions. **********/
650
651/* Lock for GC. */
652extern struct srcu_struct tomoyo_ss;
653
654/* The list for "struct tomoyo_domain_info". */
655extern struct list_head tomoyo_domain_list;
656
657extern struct list_head tomoyo_domain_initializer_list;
658extern struct list_head tomoyo_domain_keeper_list;
659extern struct list_head tomoyo_alias_list;
660extern struct list_head tomoyo_globally_readable_list;
661extern struct list_head tomoyo_pattern_list;
662extern struct list_head tomoyo_no_rewrite_list;
663extern struct list_head tomoyo_policy_manager_list;
664extern struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
665extern struct mutex tomoyo_name_list_lock;
666
667/* Lock for protecting policy. */
668extern struct mutex tomoyo_policy_lock;
669
670/* Has /sbin/init started? */
671extern bool tomoyo_policy_loaded;
672
673/* The kernel's domain. */
674extern struct tomoyo_domain_info tomoyo_kernel_domain;
675
676/********** Inlined functions. **********/
677
678static inline int tomoyo_read_lock(void)
390{ 679{
391 return a->hash != b->hash || strcmp(a->name, b->name); 680 return srcu_read_lock(&tomoyo_ss);
392} 681}
393 682
394/* Get type of an ACL entry. */ 683static inline void tomoyo_read_unlock(int idx)
395static inline u8 tomoyo_acl_type1(struct tomoyo_acl_info *ptr)
396{ 684{
397 return ptr->type & ~TOMOYO_ACL_DELETED; 685 srcu_read_unlock(&tomoyo_ss, idx);
398} 686}
399 687
400/* Get type of an ACL entry. */ 688/* strcmp() for "struct tomoyo_path_info" structure. */
401static inline u8 tomoyo_acl_type2(struct tomoyo_acl_info *ptr) 689static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a,
690 const struct tomoyo_path_info *b)
402{ 691{
403 return ptr->type; 692 return a->hash != b->hash || strcmp(a->name, b->name);
404} 693}
405 694
406/** 695/**
@@ -427,18 +716,25 @@ static inline bool tomoyo_is_invalid(const unsigned char c)
427 return c && (c <= ' ' || c >= 127); 716 return c && (c <= ' ' || c >= 127);
428} 717}
429 718
430/* The list for "struct tomoyo_domain_info". */ 719static inline void tomoyo_put_name(const struct tomoyo_path_info *name)
431extern struct list_head tomoyo_domain_list; 720{
432extern struct rw_semaphore tomoyo_domain_list_lock; 721 if (name) {
433 722 struct tomoyo_name_entry *ptr =
434/* Lock for domain->acl_info_list. */ 723 container_of(name, struct tomoyo_name_entry, entry);
435extern struct rw_semaphore tomoyo_domain_acl_info_list_lock; 724 atomic_dec(&ptr->users);
725 }
726}
436 727
437/* Has /sbin/init started? */ 728static inline struct tomoyo_domain_info *tomoyo_domain(void)
438extern bool tomoyo_policy_loaded; 729{
730 return current_cred()->security;
731}
439 732
440/* The kernel's domain. */ 733static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
441extern struct tomoyo_domain_info tomoyo_kernel_domain; 734 *task)
735{
736 return task_cred_xxx(task, security);
737}
442 738
443/** 739/**
444 * list_for_each_cookie - iterate over a list with cookie. 740 * list_for_each_cookie - iterate over a list with cookie.
@@ -446,16 +742,16 @@ extern struct tomoyo_domain_info tomoyo_kernel_domain;
446 * @cookie: the &struct list_head to use as a cookie. 742 * @cookie: the &struct list_head to use as a cookie.
447 * @head: the head for your list. 743 * @head: the head for your list.
448 * 744 *
449 * Same with list_for_each() except that this primitive uses @cookie 745 * Same with list_for_each_rcu() except that this primitive uses @cookie
450 * so that we can continue iteration. 746 * so that we can continue iteration.
451 * @cookie must be NULL when iteration starts, and @cookie will become 747 * @cookie must be NULL when iteration starts, and @cookie will become
452 * NULL when iteration finishes. 748 * NULL when iteration finishes.
453 */ 749 */
454#define list_for_each_cookie(pos, cookie, head) \ 750#define list_for_each_cookie(pos, cookie, head) \
455 for (({ if (!cookie) \ 751 for (({ if (!cookie) \
456 cookie = head; }), \ 752 cookie = head; }), \
457 pos = (cookie)->next; \ 753 pos = rcu_dereference((cookie)->next); \
458 prefetch(pos->next), pos != (head) || ((cookie) = NULL); \ 754 prefetch(pos->next), pos != (head) || ((cookie) = NULL); \
459 (cookie) = pos, pos = pos->next) 755 (cookie) = pos, pos = rcu_dereference(pos->next))
460 756
461#endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */ 757#endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index fcf52accce2b..acb8c397d5cf 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -10,9 +10,8 @@
10 */ 10 */
11 11
12#include "common.h" 12#include "common.h"
13#include "tomoyo.h"
14#include "realpath.h"
15#include <linux/binfmts.h> 13#include <linux/binfmts.h>
14#include <linux/slab.h>
16 15
17/* Variables definitions.*/ 16/* Variables definitions.*/
18 17
@@ -58,99 +57,6 @@ struct tomoyo_domain_info tomoyo_kernel_domain;
58 * exceptions. 57 * exceptions.
59 */ 58 */
60LIST_HEAD(tomoyo_domain_list); 59LIST_HEAD(tomoyo_domain_list);
61DECLARE_RWSEM(tomoyo_domain_list_lock);
62
63/*
64 * tomoyo_domain_initializer_entry is a structure which is used for holding
65 * "initialize_domain" and "no_initialize_domain" entries.
66 * It has following fields.
67 *
68 * (1) "list" which is linked to tomoyo_domain_initializer_list .
69 * (2) "domainname" which is "a domainname" or "the last component of a
70 * domainname". This field is NULL if "from" clause is not specified.
71 * (3) "program" which is a program's pathname.
72 * (4) "is_deleted" is a bool which is true if marked as deleted, false
73 * otherwise.
74 * (5) "is_not" is a bool which is true if "no_initialize_domain", false
75 * otherwise.
76 * (6) "is_last_name" is a bool which is true if "domainname" is "the last
77 * component of a domainname", false otherwise.
78 */
79struct tomoyo_domain_initializer_entry {
80 struct list_head list;
81 const struct tomoyo_path_info *domainname; /* This may be NULL */
82 const struct tomoyo_path_info *program;
83 bool is_deleted;
84 bool is_not; /* True if this entry is "no_initialize_domain". */
85 /* True if the domainname is tomoyo_get_last_name(). */
86 bool is_last_name;
87};
88
89/*
90 * tomoyo_domain_keeper_entry is a structure which is used for holding
91 * "keep_domain" and "no_keep_domain" entries.
92 * It has following fields.
93 *
94 * (1) "list" which is linked to tomoyo_domain_keeper_list .
95 * (2) "domainname" which is "a domainname" or "the last component of a
96 * domainname".
97 * (3) "program" which is a program's pathname.
98 * This field is NULL if "from" clause is not specified.
99 * (4) "is_deleted" is a bool which is true if marked as deleted, false
100 * otherwise.
101 * (5) "is_not" is a bool which is true if "no_initialize_domain", false
102 * otherwise.
103 * (6) "is_last_name" is a bool which is true if "domainname" is "the last
104 * component of a domainname", false otherwise.
105 */
106struct tomoyo_domain_keeper_entry {
107 struct list_head list;
108 const struct tomoyo_path_info *domainname;
109 const struct tomoyo_path_info *program; /* This may be NULL */
110 bool is_deleted;
111 bool is_not; /* True if this entry is "no_keep_domain". */
112 /* True if the domainname is tomoyo_get_last_name(). */
113 bool is_last_name;
114};
115
116/*
117 * tomoyo_alias_entry is a structure which is used for holding "alias" entries.
118 * It has following fields.
119 *
120 * (1) "list" which is linked to tomoyo_alias_list .
121 * (2) "original_name" which is a dereferenced pathname.
122 * (3) "aliased_name" which is a symlink's pathname.
123 * (4) "is_deleted" is a bool which is true if marked as deleted, false
124 * otherwise.
125 */
126struct tomoyo_alias_entry {
127 struct list_head list;
128 const struct tomoyo_path_info *original_name;
129 const struct tomoyo_path_info *aliased_name;
130 bool is_deleted;
131};
132
133/**
134 * tomoyo_set_domain_flag - Set or clear domain's attribute flags.
135 *
136 * @domain: Pointer to "struct tomoyo_domain_info".
137 * @is_delete: True if it is a delete request.
138 * @flags: Flags to set or clear.
139 *
140 * Returns nothing.
141 */
142void tomoyo_set_domain_flag(struct tomoyo_domain_info *domain,
143 const bool is_delete, const u8 flags)
144{
145 /* We need to serialize because this is bitfield operation. */
146 static DEFINE_SPINLOCK(lock);
147 spin_lock(&lock);
148 if (!is_delete)
149 domain->flags |= flags;
150 else
151 domain->flags &= ~flags;
152 spin_unlock(&lock);
153}
154 60
155/** 61/**
156 * tomoyo_get_last_name - Get last component of a domainname. 62 * tomoyo_get_last_name - Get last component of a domainname.
@@ -205,8 +111,7 @@ const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain)
205 * will cause "/usr/sbin/httpd" to belong to "<kernel> /usr/sbin/httpd" domain 111 * will cause "/usr/sbin/httpd" to belong to "<kernel> /usr/sbin/httpd" domain
206 * unless executed from "<kernel> /etc/rc.d/init.d/httpd" domain. 112 * unless executed from "<kernel> /etc/rc.d/init.d/httpd" domain.
207 */ 113 */
208static LIST_HEAD(tomoyo_domain_initializer_list); 114LIST_HEAD(tomoyo_domain_initializer_list);
209static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock);
210 115
211/** 116/**
212 * tomoyo_update_domain_initializer_entry - Update "struct tomoyo_domain_initializer_entry" list. 117 * tomoyo_update_domain_initializer_entry - Update "struct tomoyo_domain_initializer_entry" list.
@@ -217,59 +122,65 @@ static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock);
217 * @is_delete: True if it is a delete request. 122 * @is_delete: True if it is a delete request.
218 * 123 *
219 * Returns 0 on success, negative value otherwise. 124 * Returns 0 on success, negative value otherwise.
125 *
126 * Caller holds tomoyo_read_lock().
220 */ 127 */
221static int tomoyo_update_domain_initializer_entry(const char *domainname, 128static int tomoyo_update_domain_initializer_entry(const char *domainname,
222 const char *program, 129 const char *program,
223 const bool is_not, 130 const bool is_not,
224 const bool is_delete) 131 const bool is_delete)
225{ 132{
226 struct tomoyo_domain_initializer_entry *new_entry; 133 struct tomoyo_domain_initializer_entry *entry = NULL;
227 struct tomoyo_domain_initializer_entry *ptr; 134 struct tomoyo_domain_initializer_entry *ptr;
228 const struct tomoyo_path_info *saved_program; 135 const struct tomoyo_path_info *saved_program = NULL;
229 const struct tomoyo_path_info *saved_domainname = NULL; 136 const struct tomoyo_path_info *saved_domainname = NULL;
230 int error = -ENOMEM; 137 int error = is_delete ? -ENOENT : -ENOMEM;
231 bool is_last_name = false; 138 bool is_last_name = false;
232 139
233 if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__)) 140 if (!tomoyo_is_correct_path(program, 1, -1, -1))
234 return -EINVAL; /* No patterns allowed. */ 141 return -EINVAL; /* No patterns allowed. */
235 if (domainname) { 142 if (domainname) {
236 if (!tomoyo_is_domain_def(domainname) && 143 if (!tomoyo_is_domain_def(domainname) &&
237 tomoyo_is_correct_path(domainname, 1, -1, -1, __func__)) 144 tomoyo_is_correct_path(domainname, 1, -1, -1))
238 is_last_name = true; 145 is_last_name = true;
239 else if (!tomoyo_is_correct_domain(domainname, __func__)) 146 else if (!tomoyo_is_correct_domain(domainname))
240 return -EINVAL; 147 return -EINVAL;
241 saved_domainname = tomoyo_save_name(domainname); 148 saved_domainname = tomoyo_get_name(domainname);
242 if (!saved_domainname) 149 if (!saved_domainname)
243 return -ENOMEM; 150 goto out;
244 } 151 }
245 saved_program = tomoyo_save_name(program); 152 saved_program = tomoyo_get_name(program);
246 if (!saved_program) 153 if (!saved_program)
247 return -ENOMEM; 154 goto out;
248 down_write(&tomoyo_domain_initializer_list_lock); 155 if (!is_delete)
249 list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) { 156 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
157 mutex_lock(&tomoyo_policy_lock);
158 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) {
250 if (ptr->is_not != is_not || 159 if (ptr->is_not != is_not ||
251 ptr->domainname != saved_domainname || 160 ptr->domainname != saved_domainname ||
252 ptr->program != saved_program) 161 ptr->program != saved_program)
253 continue; 162 continue;
254 ptr->is_deleted = is_delete; 163 ptr->is_deleted = is_delete;
255 error = 0; 164 error = 0;
256 goto out; 165 break;
257 } 166 }
258 if (is_delete) { 167 if (!is_delete && error && tomoyo_memory_ok(entry)) {
259 error = -ENOENT; 168 entry->domainname = saved_domainname;
260 goto out; 169 saved_domainname = NULL;
170 entry->program = saved_program;
171 saved_program = NULL;
172 entry->is_not = is_not;
173 entry->is_last_name = is_last_name;
174 list_add_tail_rcu(&entry->list,
175 &tomoyo_domain_initializer_list);
176 entry = NULL;
177 error = 0;
261 } 178 }
262 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 179 mutex_unlock(&tomoyo_policy_lock);
263 if (!new_entry)
264 goto out;
265 new_entry->domainname = saved_domainname;
266 new_entry->program = saved_program;
267 new_entry->is_not = is_not;
268 new_entry->is_last_name = is_last_name;
269 list_add_tail(&new_entry->list, &tomoyo_domain_initializer_list);
270 error = 0;
271 out: 180 out:
272 up_write(&tomoyo_domain_initializer_list_lock); 181 tomoyo_put_name(saved_domainname);
182 tomoyo_put_name(saved_program);
183 kfree(entry);
273 return error; 184 return error;
274} 185}
275 186
@@ -279,13 +190,14 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
279 * @head: Pointer to "struct tomoyo_io_buffer". 190 * @head: Pointer to "struct tomoyo_io_buffer".
280 * 191 *
281 * Returns true on success, false otherwise. 192 * Returns true on success, false otherwise.
193 *
194 * Caller holds tomoyo_read_lock().
282 */ 195 */
283bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head) 196bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head)
284{ 197{
285 struct list_head *pos; 198 struct list_head *pos;
286 bool done = true; 199 bool done = true;
287 200
288 down_read(&tomoyo_domain_initializer_list_lock);
289 list_for_each_cookie(pos, head->read_var2, 201 list_for_each_cookie(pos, head->read_var2,
290 &tomoyo_domain_initializer_list) { 202 &tomoyo_domain_initializer_list) {
291 const char *no; 203 const char *no;
@@ -308,7 +220,6 @@ bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head)
308 if (!done) 220 if (!done)
309 break; 221 break;
310 } 222 }
311 up_read(&tomoyo_domain_initializer_list_lock);
312 return done; 223 return done;
313} 224}
314 225
@@ -320,6 +231,8 @@ bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head)
320 * @is_delete: True if it is a delete request. 231 * @is_delete: True if it is a delete request.
321 * 232 *
322 * Returns 0 on success, negative value otherwise. 233 * Returns 0 on success, negative value otherwise.
234 *
235 * Caller holds tomoyo_read_lock().
323 */ 236 */
324int tomoyo_write_domain_initializer_policy(char *data, const bool is_not, 237int tomoyo_write_domain_initializer_policy(char *data, const bool is_not,
325 const bool is_delete) 238 const bool is_delete)
@@ -345,6 +258,8 @@ int tomoyo_write_domain_initializer_policy(char *data, const bool is_not,
345 * 258 *
346 * Returns true if executing @program reinitializes domain transition, 259 * Returns true if executing @program reinitializes domain transition,
347 * false otherwise. 260 * false otherwise.
261 *
262 * Caller holds tomoyo_read_lock().
348 */ 263 */
349static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info * 264static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
350 domainname, 265 domainname,
@@ -355,8 +270,7 @@ static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
355 struct tomoyo_domain_initializer_entry *ptr; 270 struct tomoyo_domain_initializer_entry *ptr;
356 bool flag = false; 271 bool flag = false;
357 272
358 down_read(&tomoyo_domain_initializer_list_lock); 273 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) {
359 list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) {
360 if (ptr->is_deleted) 274 if (ptr->is_deleted)
361 continue; 275 continue;
362 if (ptr->domainname) { 276 if (ptr->domainname) {
@@ -376,7 +290,6 @@ static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
376 } 290 }
377 flag = true; 291 flag = true;
378 } 292 }
379 up_read(&tomoyo_domain_initializer_list_lock);
380 return flag; 293 return flag;
381} 294}
382 295
@@ -418,8 +331,7 @@ static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
418 * "<kernel> /usr/sbin/sshd /bin/bash /usr/bin/passwd" domain, unless 331 * "<kernel> /usr/sbin/sshd /bin/bash /usr/bin/passwd" domain, unless
419 * explicitly specified by "initialize_domain". 332 * explicitly specified by "initialize_domain".
420 */ 333 */
421static LIST_HEAD(tomoyo_domain_keeper_list); 334LIST_HEAD(tomoyo_domain_keeper_list);
422static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock);
423 335
424/** 336/**
425 * tomoyo_update_domain_keeper_entry - Update "struct tomoyo_domain_keeper_entry" list. 337 * tomoyo_update_domain_keeper_entry - Update "struct tomoyo_domain_keeper_entry" list.
@@ -430,59 +342,64 @@ static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock);
430 * @is_delete: True if it is a delete request. 342 * @is_delete: True if it is a delete request.
431 * 343 *
432 * Returns 0 on success, negative value otherwise. 344 * Returns 0 on success, negative value otherwise.
345 *
346 * Caller holds tomoyo_read_lock().
433 */ 347 */
434static int tomoyo_update_domain_keeper_entry(const char *domainname, 348static int tomoyo_update_domain_keeper_entry(const char *domainname,
435 const char *program, 349 const char *program,
436 const bool is_not, 350 const bool is_not,
437 const bool is_delete) 351 const bool is_delete)
438{ 352{
439 struct tomoyo_domain_keeper_entry *new_entry; 353 struct tomoyo_domain_keeper_entry *entry = NULL;
440 struct tomoyo_domain_keeper_entry *ptr; 354 struct tomoyo_domain_keeper_entry *ptr;
441 const struct tomoyo_path_info *saved_domainname; 355 const struct tomoyo_path_info *saved_domainname = NULL;
442 const struct tomoyo_path_info *saved_program = NULL; 356 const struct tomoyo_path_info *saved_program = NULL;
443 int error = -ENOMEM; 357 int error = is_delete ? -ENOENT : -ENOMEM;
444 bool is_last_name = false; 358 bool is_last_name = false;
445 359
446 if (!tomoyo_is_domain_def(domainname) && 360 if (!tomoyo_is_domain_def(domainname) &&
447 tomoyo_is_correct_path(domainname, 1, -1, -1, __func__)) 361 tomoyo_is_correct_path(domainname, 1, -1, -1))
448 is_last_name = true; 362 is_last_name = true;
449 else if (!tomoyo_is_correct_domain(domainname, __func__)) 363 else if (!tomoyo_is_correct_domain(domainname))
450 return -EINVAL; 364 return -EINVAL;
451 if (program) { 365 if (program) {
452 if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__)) 366 if (!tomoyo_is_correct_path(program, 1, -1, -1))
453 return -EINVAL; 367 return -EINVAL;
454 saved_program = tomoyo_save_name(program); 368 saved_program = tomoyo_get_name(program);
455 if (!saved_program) 369 if (!saved_program)
456 return -ENOMEM; 370 goto out;
457 } 371 }
458 saved_domainname = tomoyo_save_name(domainname); 372 saved_domainname = tomoyo_get_name(domainname);
459 if (!saved_domainname) 373 if (!saved_domainname)
460 return -ENOMEM; 374 goto out;
461 down_write(&tomoyo_domain_keeper_list_lock); 375 if (!is_delete)
462 list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) { 376 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
377 mutex_lock(&tomoyo_policy_lock);
378 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
463 if (ptr->is_not != is_not || 379 if (ptr->is_not != is_not ||
464 ptr->domainname != saved_domainname || 380 ptr->domainname != saved_domainname ||
465 ptr->program != saved_program) 381 ptr->program != saved_program)
466 continue; 382 continue;
467 ptr->is_deleted = is_delete; 383 ptr->is_deleted = is_delete;
468 error = 0; 384 error = 0;
469 goto out; 385 break;
470 } 386 }
471 if (is_delete) { 387 if (!is_delete && error && tomoyo_memory_ok(entry)) {
472 error = -ENOENT; 388 entry->domainname = saved_domainname;
473 goto out; 389 saved_domainname = NULL;
390 entry->program = saved_program;
391 saved_program = NULL;
392 entry->is_not = is_not;
393 entry->is_last_name = is_last_name;
394 list_add_tail_rcu(&entry->list, &tomoyo_domain_keeper_list);
395 entry = NULL;
396 error = 0;
474 } 397 }
475 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 398 mutex_unlock(&tomoyo_policy_lock);
476 if (!new_entry)
477 goto out;
478 new_entry->domainname = saved_domainname;
479 new_entry->program = saved_program;
480 new_entry->is_not = is_not;
481 new_entry->is_last_name = is_last_name;
482 list_add_tail(&new_entry->list, &tomoyo_domain_keeper_list);
483 error = 0;
484 out: 399 out:
485 up_write(&tomoyo_domain_keeper_list_lock); 400 tomoyo_put_name(saved_domainname);
401 tomoyo_put_name(saved_program);
402 kfree(entry);
486 return error; 403 return error;
487} 404}
488 405
@@ -493,6 +410,7 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
493 * @is_not: True if it is "no_keep_domain" entry. 410 * @is_not: True if it is "no_keep_domain" entry.
494 * @is_delete: True if it is a delete request. 411 * @is_delete: True if it is a delete request.
495 * 412 *
413 * Caller holds tomoyo_read_lock().
496 */ 414 */
497int tomoyo_write_domain_keeper_policy(char *data, const bool is_not, 415int tomoyo_write_domain_keeper_policy(char *data, const bool is_not,
498 const bool is_delete) 416 const bool is_delete)
@@ -513,13 +431,14 @@ int tomoyo_write_domain_keeper_policy(char *data, const bool is_not,
513 * @head: Pointer to "struct tomoyo_io_buffer". 431 * @head: Pointer to "struct tomoyo_io_buffer".
514 * 432 *
515 * Returns true on success, false otherwise. 433 * Returns true on success, false otherwise.
434 *
435 * Caller holds tomoyo_read_lock().
516 */ 436 */
517bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head) 437bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head)
518{ 438{
519 struct list_head *pos; 439 struct list_head *pos;
520 bool done = true; 440 bool done = true;
521 441
522 down_read(&tomoyo_domain_keeper_list_lock);
523 list_for_each_cookie(pos, head->read_var2, 442 list_for_each_cookie(pos, head->read_var2,
524 &tomoyo_domain_keeper_list) { 443 &tomoyo_domain_keeper_list) {
525 struct tomoyo_domain_keeper_entry *ptr; 444 struct tomoyo_domain_keeper_entry *ptr;
@@ -542,7 +461,6 @@ bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head)
542 if (!done) 461 if (!done)
543 break; 462 break;
544 } 463 }
545 up_read(&tomoyo_domain_keeper_list_lock);
546 return done; 464 return done;
547} 465}
548 466
@@ -555,6 +473,8 @@ bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head)
555 * 473 *
556 * Returns true if executing @program supresses domain transition, 474 * Returns true if executing @program supresses domain transition,
557 * false otherwise. 475 * false otherwise.
476 *
477 * Caller holds tomoyo_read_lock().
558 */ 478 */
559static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname, 479static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
560 const struct tomoyo_path_info *program, 480 const struct tomoyo_path_info *program,
@@ -563,8 +483,7 @@ static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
563 struct tomoyo_domain_keeper_entry *ptr; 483 struct tomoyo_domain_keeper_entry *ptr;
564 bool flag = false; 484 bool flag = false;
565 485
566 down_read(&tomoyo_domain_keeper_list_lock); 486 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
567 list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) {
568 if (ptr->is_deleted) 487 if (ptr->is_deleted)
569 continue; 488 continue;
570 if (!ptr->is_last_name) { 489 if (!ptr->is_last_name) {
@@ -582,7 +501,6 @@ static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
582 } 501 }
583 flag = true; 502 flag = true;
584 } 503 }
585 up_read(&tomoyo_domain_keeper_list_lock);
586 return flag; 504 return flag;
587} 505}
588 506
@@ -616,8 +534,7 @@ static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
616 * /bin/busybox and domainname which the current process will belong to after 534 * /bin/busybox and domainname which the current process will belong to after
617 * execve() succeeds is calculated using /bin/cat rather than /bin/busybox . 535 * execve() succeeds is calculated using /bin/cat rather than /bin/busybox .
618 */ 536 */
619static LIST_HEAD(tomoyo_alias_list); 537LIST_HEAD(tomoyo_alias_list);
620static DECLARE_RWSEM(tomoyo_alias_list_lock);
621 538
622/** 539/**
623 * tomoyo_update_alias_entry - Update "struct tomoyo_alias_entry" list. 540 * tomoyo_update_alias_entry - Update "struct tomoyo_alias_entry" list.
@@ -627,46 +544,51 @@ static DECLARE_RWSEM(tomoyo_alias_list_lock);
627 * @is_delete: True if it is a delete request. 544 * @is_delete: True if it is a delete request.
628 * 545 *
629 * Returns 0 on success, negative value otherwise. 546 * Returns 0 on success, negative value otherwise.
547 *
548 * Caller holds tomoyo_read_lock().
630 */ 549 */
631static int tomoyo_update_alias_entry(const char *original_name, 550static int tomoyo_update_alias_entry(const char *original_name,
632 const char *aliased_name, 551 const char *aliased_name,
633 const bool is_delete) 552 const bool is_delete)
634{ 553{
635 struct tomoyo_alias_entry *new_entry; 554 struct tomoyo_alias_entry *entry = NULL;
636 struct tomoyo_alias_entry *ptr; 555 struct tomoyo_alias_entry *ptr;
637 const struct tomoyo_path_info *saved_original_name; 556 const struct tomoyo_path_info *saved_original_name;
638 const struct tomoyo_path_info *saved_aliased_name; 557 const struct tomoyo_path_info *saved_aliased_name;
639 int error = -ENOMEM; 558 int error = is_delete ? -ENOENT : -ENOMEM;
640 559
641 if (!tomoyo_is_correct_path(original_name, 1, -1, -1, __func__) || 560 if (!tomoyo_is_correct_path(original_name, 1, -1, -1) ||
642 !tomoyo_is_correct_path(aliased_name, 1, -1, -1, __func__)) 561 !tomoyo_is_correct_path(aliased_name, 1, -1, -1))
643 return -EINVAL; /* No patterns allowed. */ 562 return -EINVAL; /* No patterns allowed. */
644 saved_original_name = tomoyo_save_name(original_name); 563 saved_original_name = tomoyo_get_name(original_name);
645 saved_aliased_name = tomoyo_save_name(aliased_name); 564 saved_aliased_name = tomoyo_get_name(aliased_name);
646 if (!saved_original_name || !saved_aliased_name) 565 if (!saved_original_name || !saved_aliased_name)
647 return -ENOMEM; 566 goto out;
648 down_write(&tomoyo_alias_list_lock); 567 if (!is_delete)
649 list_for_each_entry(ptr, &tomoyo_alias_list, list) { 568 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
569 mutex_lock(&tomoyo_policy_lock);
570 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
650 if (ptr->original_name != saved_original_name || 571 if (ptr->original_name != saved_original_name ||
651 ptr->aliased_name != saved_aliased_name) 572 ptr->aliased_name != saved_aliased_name)
652 continue; 573 continue;
653 ptr->is_deleted = is_delete; 574 ptr->is_deleted = is_delete;
654 error = 0; 575 error = 0;
655 goto out; 576 break;
656 } 577 }
657 if (is_delete) { 578 if (!is_delete && error && tomoyo_memory_ok(entry)) {
658 error = -ENOENT; 579 entry->original_name = saved_original_name;
659 goto out; 580 saved_original_name = NULL;
581 entry->aliased_name = saved_aliased_name;
582 saved_aliased_name = NULL;
583 list_add_tail_rcu(&entry->list, &tomoyo_alias_list);
584 entry = NULL;
585 error = 0;
660 } 586 }
661 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 587 mutex_unlock(&tomoyo_policy_lock);
662 if (!new_entry)
663 goto out;
664 new_entry->original_name = saved_original_name;
665 new_entry->aliased_name = saved_aliased_name;
666 list_add_tail(&new_entry->list, &tomoyo_alias_list);
667 error = 0;
668 out: 588 out:
669 up_write(&tomoyo_alias_list_lock); 589 tomoyo_put_name(saved_original_name);
590 tomoyo_put_name(saved_aliased_name);
591 kfree(entry);
670 return error; 592 return error;
671} 593}
672 594
@@ -676,13 +598,14 @@ static int tomoyo_update_alias_entry(const char *original_name,
676 * @head: Pointer to "struct tomoyo_io_buffer". 598 * @head: Pointer to "struct tomoyo_io_buffer".
677 * 599 *
678 * Returns true on success, false otherwise. 600 * Returns true on success, false otherwise.
601 *
602 * Caller holds tomoyo_read_lock().
679 */ 603 */
680bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head) 604bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head)
681{ 605{
682 struct list_head *pos; 606 struct list_head *pos;
683 bool done = true; 607 bool done = true;
684 608
685 down_read(&tomoyo_alias_list_lock);
686 list_for_each_cookie(pos, head->read_var2, &tomoyo_alias_list) { 609 list_for_each_cookie(pos, head->read_var2, &tomoyo_alias_list) {
687 struct tomoyo_alias_entry *ptr; 610 struct tomoyo_alias_entry *ptr;
688 611
@@ -695,7 +618,6 @@ bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head)
695 if (!done) 618 if (!done)
696 break; 619 break;
697 } 620 }
698 up_read(&tomoyo_alias_list_lock);
699 return done; 621 return done;
700} 622}
701 623
@@ -706,6 +628,8 @@ bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head)
706 * @is_delete: True if it is a delete request. 628 * @is_delete: True if it is a delete request.
707 * 629 *
708 * Returns 0 on success, negative value otherwise. 630 * Returns 0 on success, negative value otherwise.
631 *
632 * Caller holds tomoyo_read_lock().
709 */ 633 */
710int tomoyo_write_alias_policy(char *data, const bool is_delete) 634int tomoyo_write_alias_policy(char *data, const bool is_delete)
711{ 635{
@@ -724,63 +648,46 @@ int tomoyo_write_alias_policy(char *data, const bool is_delete)
724 * @profile: Profile number to assign if the domain was newly created. 648 * @profile: Profile number to assign if the domain was newly created.
725 * 649 *
726 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise. 650 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise.
651 *
652 * Caller holds tomoyo_read_lock().
727 */ 653 */
728struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * 654struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
729 domainname, 655 domainname,
730 const u8 profile) 656 const u8 profile)
731{ 657{
732 struct tomoyo_domain_info *domain = NULL; 658 struct tomoyo_domain_info *entry;
659 struct tomoyo_domain_info *domain;
733 const struct tomoyo_path_info *saved_domainname; 660 const struct tomoyo_path_info *saved_domainname;
661 bool found = false;
734 662
735 down_write(&tomoyo_domain_list_lock); 663 if (!tomoyo_is_correct_domain(domainname))
736 domain = tomoyo_find_domain(domainname); 664 return NULL;
737 if (domain) 665 saved_domainname = tomoyo_get_name(domainname);
738 goto out;
739 if (!tomoyo_is_correct_domain(domainname, __func__))
740 goto out;
741 saved_domainname = tomoyo_save_name(domainname);
742 if (!saved_domainname) 666 if (!saved_domainname)
743 goto out; 667 return NULL;
744 /* Can I reuse memory of deleted domain? */ 668 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
745 list_for_each_entry(domain, &tomoyo_domain_list, list) { 669 mutex_lock(&tomoyo_policy_lock);
746 struct task_struct *p; 670 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
747 struct tomoyo_acl_info *ptr; 671 if (domain->is_deleted ||
748 bool flag; 672 tomoyo_pathcmp(saved_domainname, domain->domainname))
749 if (!domain->is_deleted ||
750 domain->domainname != saved_domainname)
751 continue; 673 continue;
752 flag = false; 674 found = true;
753 read_lock(&tasklist_lock); 675 break;
754 for_each_process(p) {
755 if (tomoyo_real_domain(p) != domain)
756 continue;
757 flag = true;
758 break;
759 }
760 read_unlock(&tasklist_lock);
761 if (flag)
762 continue;
763 list_for_each_entry(ptr, &domain->acl_info_list, list) {
764 ptr->type |= TOMOYO_ACL_DELETED;
765 }
766 tomoyo_set_domain_flag(domain, true, domain->flags);
767 domain->profile = profile;
768 domain->quota_warned = false;
769 mb(); /* Avoid out-of-order execution. */
770 domain->is_deleted = false;
771 goto out;
772 } 676 }
773 /* No memory reusable. Create using new memory. */ 677 if (!found && tomoyo_memory_ok(entry)) {
774 domain = tomoyo_alloc_element(sizeof(*domain)); 678 INIT_LIST_HEAD(&entry->acl_info_list);
775 if (domain) { 679 entry->domainname = saved_domainname;
776 INIT_LIST_HEAD(&domain->acl_info_list); 680 saved_domainname = NULL;
777 domain->domainname = saved_domainname; 681 entry->profile = profile;
778 domain->profile = profile; 682 list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
779 list_add_tail(&domain->list, &tomoyo_domain_list); 683 domain = entry;
684 entry = NULL;
685 found = true;
780 } 686 }
781 out: 687 mutex_unlock(&tomoyo_policy_lock);
782 up_write(&tomoyo_domain_list_lock); 688 tomoyo_put_name(saved_domainname);
783 return domain; 689 kfree(entry);
690 return found ? domain : NULL;
784} 691}
785 692
786/** 693/**
@@ -789,6 +696,8 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
789 * @bprm: Pointer to "struct linux_binprm". 696 * @bprm: Pointer to "struct linux_binprm".
790 * 697 *
791 * Returns 0 on success, negative value otherwise. 698 * Returns 0 on success, negative value otherwise.
699 *
700 * Caller holds tomoyo_read_lock().
792 */ 701 */
793int tomoyo_find_next_domain(struct linux_binprm *bprm) 702int tomoyo_find_next_domain(struct linux_binprm *bprm)
794{ 703{
@@ -796,7 +705,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
796 * This function assumes that the size of buffer returned by 705 * This function assumes that the size of buffer returned by
797 * tomoyo_realpath() = TOMOYO_MAX_PATHNAME_LEN. 706 * tomoyo_realpath() = TOMOYO_MAX_PATHNAME_LEN.
798 */ 707 */
799 struct tomoyo_page_buffer *tmp = tomoyo_alloc(sizeof(*tmp)); 708 struct tomoyo_page_buffer *tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
800 struct tomoyo_domain_info *old_domain = tomoyo_domain(); 709 struct tomoyo_domain_info *old_domain = tomoyo_domain();
801 struct tomoyo_domain_info *domain = NULL; 710 struct tomoyo_domain_info *domain = NULL;
802 const char *old_domain_name = old_domain->domainname->name; 711 const char *old_domain_name = old_domain->domainname->name;
@@ -849,8 +758,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
849 if (tomoyo_pathcmp(&r, &s)) { 758 if (tomoyo_pathcmp(&r, &s)) {
850 struct tomoyo_alias_entry *ptr; 759 struct tomoyo_alias_entry *ptr;
851 /* Is this program allowed to be called via symbolic links? */ 760 /* Is this program allowed to be called via symbolic links? */
852 down_read(&tomoyo_alias_list_lock); 761 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
853 list_for_each_entry(ptr, &tomoyo_alias_list, list) {
854 if (ptr->is_deleted || 762 if (ptr->is_deleted ||
855 tomoyo_pathcmp(&r, ptr->original_name) || 763 tomoyo_pathcmp(&r, ptr->original_name) ||
856 tomoyo_pathcmp(&s, ptr->aliased_name)) 764 tomoyo_pathcmp(&s, ptr->aliased_name))
@@ -861,7 +769,6 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
861 tomoyo_fill_path_info(&r); 769 tomoyo_fill_path_info(&r);
862 break; 770 break;
863 } 771 }
864 up_read(&tomoyo_alias_list_lock);
865 } 772 }
866 773
867 /* Check execute permission. */ 774 /* Check execute permission. */
@@ -892,9 +799,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
892 } 799 }
893 if (domain || strlen(new_domain_name) >= TOMOYO_MAX_PATHNAME_LEN) 800 if (domain || strlen(new_domain_name) >= TOMOYO_MAX_PATHNAME_LEN)
894 goto done; 801 goto done;
895 down_read(&tomoyo_domain_list_lock);
896 domain = tomoyo_find_domain(new_domain_name); 802 domain = tomoyo_find_domain(new_domain_name);
897 up_read(&tomoyo_domain_list_lock);
898 if (domain) 803 if (domain)
899 goto done; 804 goto done;
900 if (is_enforce) 805 if (is_enforce)
@@ -909,14 +814,15 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
909 if (is_enforce) 814 if (is_enforce)
910 retval = -EPERM; 815 retval = -EPERM;
911 else 816 else
912 tomoyo_set_domain_flag(old_domain, false, 817 old_domain->transition_failed = true;
913 TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED);
914 out: 818 out:
915 if (!domain) 819 if (!domain)
916 domain = old_domain; 820 domain = old_domain;
821 /* Update reference count on "struct tomoyo_domain_info". */
822 atomic_inc(&domain->users);
917 bprm->cred->security = domain; 823 bprm->cred->security = domain;
918 tomoyo_free(real_program_name); 824 kfree(real_program_name);
919 tomoyo_free(symlink_program_name); 825 kfree(symlink_program_name);
920 tomoyo_free(tmp); 826 kfree(tmp);
921 return retval; 827 return retval;
922} 828}
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 5ae3a571559f..6f3fe76a1fde 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -10,109 +10,65 @@
10 */ 10 */
11 11
12#include "common.h" 12#include "common.h"
13#include "tomoyo.h" 13#include <linux/slab.h>
14#include "realpath.h"
15#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
16
17/*
18 * tomoyo_globally_readable_file_entry is a structure which is used for holding
19 * "allow_read" entries.
20 * It has following fields.
21 *
22 * (1) "list" which is linked to tomoyo_globally_readable_list .
23 * (2) "filename" is a pathname which is allowed to open(O_RDONLY).
24 * (3) "is_deleted" is a bool which is true if marked as deleted, false
25 * otherwise.
26 */
27struct tomoyo_globally_readable_file_entry {
28 struct list_head list;
29 const struct tomoyo_path_info *filename;
30 bool is_deleted;
31};
32
33/*
34 * tomoyo_pattern_entry is a structure which is used for holding
35 * "tomoyo_pattern_list" entries.
36 * It has following fields.
37 *
38 * (1) "list" which is linked to tomoyo_pattern_list .
39 * (2) "pattern" is a pathname pattern which is used for converting pathnames
40 * to pathname patterns during learning mode.
41 * (3) "is_deleted" is a bool which is true if marked as deleted, false
42 * otherwise.
43 */
44struct tomoyo_pattern_entry {
45 struct list_head list;
46 const struct tomoyo_path_info *pattern;
47 bool is_deleted;
48};
49
50/*
51 * tomoyo_no_rewrite_entry is a structure which is used for holding
52 * "deny_rewrite" entries.
53 * It has following fields.
54 *
55 * (1) "list" which is linked to tomoyo_no_rewrite_list .
56 * (2) "pattern" is a pathname which is by default not permitted to modify
57 * already existing content.
58 * (3) "is_deleted" is a bool which is true if marked as deleted, false
59 * otherwise.
60 */
61struct tomoyo_no_rewrite_entry {
62 struct list_head list;
63 const struct tomoyo_path_info *pattern;
64 bool is_deleted;
65};
66 14
67/* Keyword array for single path operations. */ 15/* Keyword array for single path operations. */
68static const char *tomoyo_sp_keyword[TOMOYO_MAX_SINGLE_PATH_OPERATION] = { 16static const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = {
69 [TOMOYO_TYPE_READ_WRITE_ACL] = "read/write", 17 [TOMOYO_TYPE_READ_WRITE] = "read/write",
70 [TOMOYO_TYPE_EXECUTE_ACL] = "execute", 18 [TOMOYO_TYPE_EXECUTE] = "execute",
71 [TOMOYO_TYPE_READ_ACL] = "read", 19 [TOMOYO_TYPE_READ] = "read",
72 [TOMOYO_TYPE_WRITE_ACL] = "write", 20 [TOMOYO_TYPE_WRITE] = "write",
73 [TOMOYO_TYPE_CREATE_ACL] = "create", 21 [TOMOYO_TYPE_CREATE] = "create",
74 [TOMOYO_TYPE_UNLINK_ACL] = "unlink", 22 [TOMOYO_TYPE_UNLINK] = "unlink",
75 [TOMOYO_TYPE_MKDIR_ACL] = "mkdir", 23 [TOMOYO_TYPE_MKDIR] = "mkdir",
76 [TOMOYO_TYPE_RMDIR_ACL] = "rmdir", 24 [TOMOYO_TYPE_RMDIR] = "rmdir",
77 [TOMOYO_TYPE_MKFIFO_ACL] = "mkfifo", 25 [TOMOYO_TYPE_MKFIFO] = "mkfifo",
78 [TOMOYO_TYPE_MKSOCK_ACL] = "mksock", 26 [TOMOYO_TYPE_MKSOCK] = "mksock",
79 [TOMOYO_TYPE_MKBLOCK_ACL] = "mkblock", 27 [TOMOYO_TYPE_MKBLOCK] = "mkblock",
80 [TOMOYO_TYPE_MKCHAR_ACL] = "mkchar", 28 [TOMOYO_TYPE_MKCHAR] = "mkchar",
81 [TOMOYO_TYPE_TRUNCATE_ACL] = "truncate", 29 [TOMOYO_TYPE_TRUNCATE] = "truncate",
82 [TOMOYO_TYPE_SYMLINK_ACL] = "symlink", 30 [TOMOYO_TYPE_SYMLINK] = "symlink",
83 [TOMOYO_TYPE_REWRITE_ACL] = "rewrite", 31 [TOMOYO_TYPE_REWRITE] = "rewrite",
32 [TOMOYO_TYPE_IOCTL] = "ioctl",
33 [TOMOYO_TYPE_CHMOD] = "chmod",
34 [TOMOYO_TYPE_CHOWN] = "chown",
35 [TOMOYO_TYPE_CHGRP] = "chgrp",
36 [TOMOYO_TYPE_CHROOT] = "chroot",
37 [TOMOYO_TYPE_MOUNT] = "mount",
38 [TOMOYO_TYPE_UMOUNT] = "unmount",
84}; 39};
85 40
86/* Keyword array for double path operations. */ 41/* Keyword array for double path operations. */
87static const char *tomoyo_dp_keyword[TOMOYO_MAX_DOUBLE_PATH_OPERATION] = { 42static const char *tomoyo_path2_keyword[TOMOYO_MAX_PATH2_OPERATION] = {
88 [TOMOYO_TYPE_LINK_ACL] = "link", 43 [TOMOYO_TYPE_LINK] = "link",
89 [TOMOYO_TYPE_RENAME_ACL] = "rename", 44 [TOMOYO_TYPE_RENAME] = "rename",
45 [TOMOYO_TYPE_PIVOT_ROOT] = "pivot_root",
90}; 46};
91 47
92/** 48/**
93 * tomoyo_sp2keyword - Get the name of single path operation. 49 * tomoyo_path2keyword - Get the name of single path operation.
94 * 50 *
95 * @operation: Type of operation. 51 * @operation: Type of operation.
96 * 52 *
97 * Returns the name of single path operation. 53 * Returns the name of single path operation.
98 */ 54 */
99const char *tomoyo_sp2keyword(const u8 operation) 55const char *tomoyo_path2keyword(const u8 operation)
100{ 56{
101 return (operation < TOMOYO_MAX_SINGLE_PATH_OPERATION) 57 return (operation < TOMOYO_MAX_PATH_OPERATION)
102 ? tomoyo_sp_keyword[operation] : NULL; 58 ? tomoyo_path_keyword[operation] : NULL;
103} 59}
104 60
105/** 61/**
106 * tomoyo_dp2keyword - Get the name of double path operation. 62 * tomoyo_path22keyword - Get the name of double path operation.
107 * 63 *
108 * @operation: Type of operation. 64 * @operation: Type of operation.
109 * 65 *
110 * Returns the name of double path operation. 66 * Returns the name of double path operation.
111 */ 67 */
112const char *tomoyo_dp2keyword(const u8 operation) 68const char *tomoyo_path22keyword(const u8 operation)
113{ 69{
114 return (operation < TOMOYO_MAX_DOUBLE_PATH_OPERATION) 70 return (operation < TOMOYO_MAX_PATH2_OPERATION)
115 ? tomoyo_dp_keyword[operation] : NULL; 71 ? tomoyo_path2_keyword[operation] : NULL;
116} 72}
117 73
118/** 74/**
@@ -143,7 +99,8 @@ static bool tomoyo_strendswith(const char *name, const char *tail)
143static struct tomoyo_path_info *tomoyo_get_path(struct path *path) 99static struct tomoyo_path_info *tomoyo_get_path(struct path *path)
144{ 100{
145 int error; 101 int error;
146 struct tomoyo_path_info_with_data *buf = tomoyo_alloc(sizeof(*buf)); 102 struct tomoyo_path_info_with_data *buf = kzalloc(sizeof(*buf),
103 GFP_KERNEL);
147 104
148 if (!buf) 105 if (!buf)
149 return NULL; 106 return NULL;
@@ -155,20 +112,17 @@ static struct tomoyo_path_info *tomoyo_get_path(struct path *path)
155 tomoyo_fill_path_info(&buf->head); 112 tomoyo_fill_path_info(&buf->head);
156 return &buf->head; 113 return &buf->head;
157 } 114 }
158 tomoyo_free(buf); 115 kfree(buf);
159 return NULL; 116 return NULL;
160} 117}
161 118
162/* Lock for domain->acl_info_list. */ 119static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
163DECLARE_RWSEM(tomoyo_domain_acl_info_list_lock); 120 const char *filename2,
164 121 struct tomoyo_domain_info *const domain,
165static int tomoyo_update_double_path_acl(const u8 type, const char *filename1, 122 const bool is_delete);
166 const char *filename2, 123static int tomoyo_update_path_acl(const u8 type, const char *filename,
167 struct tomoyo_domain_info * 124 struct tomoyo_domain_info *const domain,
168 const domain, const bool is_delete); 125 const bool is_delete);
169static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
170 struct tomoyo_domain_info *
171 const domain, const bool is_delete);
172 126
173/* 127/*
174 * tomoyo_globally_readable_list is used for holding list of pathnames which 128 * tomoyo_globally_readable_list is used for holding list of pathnames which
@@ -195,8 +149,7 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
195 * given "allow_read /lib/libc-2.5.so" to the domain which current process 149 * given "allow_read /lib/libc-2.5.so" to the domain which current process
196 * belongs to. 150 * belongs to.
197 */ 151 */
198static LIST_HEAD(tomoyo_globally_readable_list); 152LIST_HEAD(tomoyo_globally_readable_list);
199static DECLARE_RWSEM(tomoyo_globally_readable_list_lock);
200 153
201/** 154/**
202 * tomoyo_update_globally_readable_entry - Update "struct tomoyo_globally_readable_file_entry" list. 155 * tomoyo_update_globally_readable_entry - Update "struct tomoyo_globally_readable_file_entry" list.
@@ -205,40 +158,42 @@ static DECLARE_RWSEM(tomoyo_globally_readable_list_lock);
205 * @is_delete: True if it is a delete request. 158 * @is_delete: True if it is a delete request.
206 * 159 *
207 * Returns 0 on success, negative value otherwise. 160 * Returns 0 on success, negative value otherwise.
161 *
162 * Caller holds tomoyo_read_lock().
208 */ 163 */
209static int tomoyo_update_globally_readable_entry(const char *filename, 164static int tomoyo_update_globally_readable_entry(const char *filename,
210 const bool is_delete) 165 const bool is_delete)
211{ 166{
212 struct tomoyo_globally_readable_file_entry *new_entry; 167 struct tomoyo_globally_readable_file_entry *entry = NULL;
213 struct tomoyo_globally_readable_file_entry *ptr; 168 struct tomoyo_globally_readable_file_entry *ptr;
214 const struct tomoyo_path_info *saved_filename; 169 const struct tomoyo_path_info *saved_filename;
215 int error = -ENOMEM; 170 int error = is_delete ? -ENOENT : -ENOMEM;
216 171
217 if (!tomoyo_is_correct_path(filename, 1, 0, -1, __func__)) 172 if (!tomoyo_is_correct_path(filename, 1, 0, -1))
218 return -EINVAL; 173 return -EINVAL;
219 saved_filename = tomoyo_save_name(filename); 174 saved_filename = tomoyo_get_name(filename);
220 if (!saved_filename) 175 if (!saved_filename)
221 return -ENOMEM; 176 return -ENOMEM;
222 down_write(&tomoyo_globally_readable_list_lock); 177 if (!is_delete)
223 list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) { 178 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
179 mutex_lock(&tomoyo_policy_lock);
180 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
224 if (ptr->filename != saved_filename) 181 if (ptr->filename != saved_filename)
225 continue; 182 continue;
226 ptr->is_deleted = is_delete; 183 ptr->is_deleted = is_delete;
227 error = 0; 184 error = 0;
228 goto out; 185 break;
229 } 186 }
230 if (is_delete) { 187 if (!is_delete && error && tomoyo_memory_ok(entry)) {
231 error = -ENOENT; 188 entry->filename = saved_filename;
232 goto out; 189 saved_filename = NULL;
190 list_add_tail_rcu(&entry->list, &tomoyo_globally_readable_list);
191 entry = NULL;
192 error = 0;
233 } 193 }
234 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 194 mutex_unlock(&tomoyo_policy_lock);
235 if (!new_entry) 195 tomoyo_put_name(saved_filename);
236 goto out; 196 kfree(entry);
237 new_entry->filename = saved_filename;
238 list_add_tail(&new_entry->list, &tomoyo_globally_readable_list);
239 error = 0;
240 out:
241 up_write(&tomoyo_globally_readable_list_lock);
242 return error; 197 return error;
243} 198}
244 199
@@ -248,21 +203,22 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
248 * @filename: The filename to check. 203 * @filename: The filename to check.
249 * 204 *
250 * Returns true if any domain can open @filename for reading, false otherwise. 205 * Returns true if any domain can open @filename for reading, false otherwise.
206 *
207 * Caller holds tomoyo_read_lock().
251 */ 208 */
252static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info * 209static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info *
253 filename) 210 filename)
254{ 211{
255 struct tomoyo_globally_readable_file_entry *ptr; 212 struct tomoyo_globally_readable_file_entry *ptr;
256 bool found = false; 213 bool found = false;
257 down_read(&tomoyo_globally_readable_list_lock); 214
258 list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) { 215 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
259 if (!ptr->is_deleted && 216 if (!ptr->is_deleted &&
260 tomoyo_path_matches_pattern(filename, ptr->filename)) { 217 tomoyo_path_matches_pattern(filename, ptr->filename)) {
261 found = true; 218 found = true;
262 break; 219 break;
263 } 220 }
264 } 221 }
265 up_read(&tomoyo_globally_readable_list_lock);
266 return found; 222 return found;
267} 223}
268 224
@@ -273,6 +229,8 @@ static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info *
273 * @is_delete: True if it is a delete request. 229 * @is_delete: True if it is a delete request.
274 * 230 *
275 * Returns 0 on success, negative value otherwise. 231 * Returns 0 on success, negative value otherwise.
232 *
233 * Caller holds tomoyo_read_lock().
276 */ 234 */
277int tomoyo_write_globally_readable_policy(char *data, const bool is_delete) 235int tomoyo_write_globally_readable_policy(char *data, const bool is_delete)
278{ 236{
@@ -285,13 +243,14 @@ int tomoyo_write_globally_readable_policy(char *data, const bool is_delete)
285 * @head: Pointer to "struct tomoyo_io_buffer". 243 * @head: Pointer to "struct tomoyo_io_buffer".
286 * 244 *
287 * Returns true on success, false otherwise. 245 * Returns true on success, false otherwise.
246 *
247 * Caller holds tomoyo_read_lock().
288 */ 248 */
289bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head) 249bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
290{ 250{
291 struct list_head *pos; 251 struct list_head *pos;
292 bool done = true; 252 bool done = true;
293 253
294 down_read(&tomoyo_globally_readable_list_lock);
295 list_for_each_cookie(pos, head->read_var2, 254 list_for_each_cookie(pos, head->read_var2,
296 &tomoyo_globally_readable_list) { 255 &tomoyo_globally_readable_list) {
297 struct tomoyo_globally_readable_file_entry *ptr; 256 struct tomoyo_globally_readable_file_entry *ptr;
@@ -305,7 +264,6 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
305 if (!done) 264 if (!done)
306 break; 265 break;
307 } 266 }
308 up_read(&tomoyo_globally_readable_list_lock);
309 return done; 267 return done;
310} 268}
311 269
@@ -338,8 +296,7 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
338 * which pretends as if /proc/self/ is not a symlink; so that we can forbid 296 * which pretends as if /proc/self/ is not a symlink; so that we can forbid
339 * current process from accessing other process's information. 297 * current process from accessing other process's information.
340 */ 298 */
341static LIST_HEAD(tomoyo_pattern_list); 299LIST_HEAD(tomoyo_pattern_list);
342static DECLARE_RWSEM(tomoyo_pattern_list_lock);
343 300
344/** 301/**
345 * tomoyo_update_file_pattern_entry - Update "struct tomoyo_pattern_entry" list. 302 * tomoyo_update_file_pattern_entry - Update "struct tomoyo_pattern_entry" list.
@@ -348,40 +305,43 @@ static DECLARE_RWSEM(tomoyo_pattern_list_lock);
348 * @is_delete: True if it is a delete request. 305 * @is_delete: True if it is a delete request.
349 * 306 *
350 * Returns 0 on success, negative value otherwise. 307 * Returns 0 on success, negative value otherwise.
308 *
309 * Caller holds tomoyo_read_lock().
351 */ 310 */
352static int tomoyo_update_file_pattern_entry(const char *pattern, 311static int tomoyo_update_file_pattern_entry(const char *pattern,
353 const bool is_delete) 312 const bool is_delete)
354{ 313{
355 struct tomoyo_pattern_entry *new_entry; 314 struct tomoyo_pattern_entry *entry = NULL;
356 struct tomoyo_pattern_entry *ptr; 315 struct tomoyo_pattern_entry *ptr;
357 const struct tomoyo_path_info *saved_pattern; 316 const struct tomoyo_path_info *saved_pattern;
358 int error = -ENOMEM; 317 int error = is_delete ? -ENOENT : -ENOMEM;
359 318
360 if (!tomoyo_is_correct_path(pattern, 0, 1, 0, __func__)) 319 saved_pattern = tomoyo_get_name(pattern);
361 return -EINVAL;
362 saved_pattern = tomoyo_save_name(pattern);
363 if (!saved_pattern) 320 if (!saved_pattern)
364 return -ENOMEM; 321 return error;
365 down_write(&tomoyo_pattern_list_lock); 322 if (!saved_pattern->is_patterned)
366 list_for_each_entry(ptr, &tomoyo_pattern_list, list) { 323 goto out;
324 if (!is_delete)
325 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
326 mutex_lock(&tomoyo_policy_lock);
327 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
367 if (saved_pattern != ptr->pattern) 328 if (saved_pattern != ptr->pattern)
368 continue; 329 continue;
369 ptr->is_deleted = is_delete; 330 ptr->is_deleted = is_delete;
370 error = 0; 331 error = 0;
371 goto out; 332 break;
372 } 333 }
373 if (is_delete) { 334 if (!is_delete && error && tomoyo_memory_ok(entry)) {
374 error = -ENOENT; 335 entry->pattern = saved_pattern;
375 goto out; 336 saved_pattern = NULL;
337 list_add_tail_rcu(&entry->list, &tomoyo_pattern_list);
338 entry = NULL;
339 error = 0;
376 } 340 }
377 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 341 mutex_unlock(&tomoyo_policy_lock);
378 if (!new_entry)
379 goto out;
380 new_entry->pattern = saved_pattern;
381 list_add_tail(&new_entry->list, &tomoyo_pattern_list);
382 error = 0;
383 out: 342 out:
384 up_write(&tomoyo_pattern_list_lock); 343 kfree(entry);
344 tomoyo_put_name(saved_pattern);
385 return error; 345 return error;
386} 346}
387 347
@@ -391,6 +351,8 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
391 * @filename: The filename to find patterned pathname. 351 * @filename: The filename to find patterned pathname.
392 * 352 *
393 * Returns pointer to pathname pattern if matched, @filename otherwise. 353 * Returns pointer to pathname pattern if matched, @filename otherwise.
354 *
355 * Caller holds tomoyo_read_lock().
394 */ 356 */
395static const struct tomoyo_path_info * 357static const struct tomoyo_path_info *
396tomoyo_get_file_pattern(const struct tomoyo_path_info *filename) 358tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
@@ -398,8 +360,7 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
398 struct tomoyo_pattern_entry *ptr; 360 struct tomoyo_pattern_entry *ptr;
399 const struct tomoyo_path_info *pattern = NULL; 361 const struct tomoyo_path_info *pattern = NULL;
400 362
401 down_read(&tomoyo_pattern_list_lock); 363 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
402 list_for_each_entry(ptr, &tomoyo_pattern_list, list) {
403 if (ptr->is_deleted) 364 if (ptr->is_deleted)
404 continue; 365 continue;
405 if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) 366 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
@@ -412,7 +373,6 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
412 break; 373 break;
413 } 374 }
414 } 375 }
415 up_read(&tomoyo_pattern_list_lock);
416 if (pattern) 376 if (pattern)
417 filename = pattern; 377 filename = pattern;
418 return filename; 378 return filename;
@@ -425,6 +385,8 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
425 * @is_delete: True if it is a delete request. 385 * @is_delete: True if it is a delete request.
426 * 386 *
427 * Returns 0 on success, negative value otherwise. 387 * Returns 0 on success, negative value otherwise.
388 *
389 * Caller holds tomoyo_read_lock().
428 */ 390 */
429int tomoyo_write_pattern_policy(char *data, const bool is_delete) 391int tomoyo_write_pattern_policy(char *data, const bool is_delete)
430{ 392{
@@ -437,13 +399,14 @@ int tomoyo_write_pattern_policy(char *data, const bool is_delete)
437 * @head: Pointer to "struct tomoyo_io_buffer". 399 * @head: Pointer to "struct tomoyo_io_buffer".
438 * 400 *
439 * Returns true on success, false otherwise. 401 * Returns true on success, false otherwise.
402 *
403 * Caller holds tomoyo_read_lock().
440 */ 404 */
441bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head) 405bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
442{ 406{
443 struct list_head *pos; 407 struct list_head *pos;
444 bool done = true; 408 bool done = true;
445 409
446 down_read(&tomoyo_pattern_list_lock);
447 list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) { 410 list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) {
448 struct tomoyo_pattern_entry *ptr; 411 struct tomoyo_pattern_entry *ptr;
449 ptr = list_entry(pos, struct tomoyo_pattern_entry, list); 412 ptr = list_entry(pos, struct tomoyo_pattern_entry, list);
@@ -454,7 +417,6 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
454 if (!done) 417 if (!done)
455 break; 418 break;
456 } 419 }
457 up_read(&tomoyo_pattern_list_lock);
458 return done; 420 return done;
459} 421}
460 422
@@ -487,8 +449,7 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
487 * " (deleted)" suffix if the file is already unlink()ed; so that we don't 449 * " (deleted)" suffix if the file is already unlink()ed; so that we don't
488 * need to worry whether the file is already unlink()ed or not. 450 * need to worry whether the file is already unlink()ed or not.
489 */ 451 */
490static LIST_HEAD(tomoyo_no_rewrite_list); 452LIST_HEAD(tomoyo_no_rewrite_list);
491static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock);
492 453
493/** 454/**
494 * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite_entry" list. 455 * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite_entry" list.
@@ -497,39 +458,42 @@ static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock);
497 * @is_delete: True if it is a delete request. 458 * @is_delete: True if it is a delete request.
498 * 459 *
499 * Returns 0 on success, negative value otherwise. 460 * Returns 0 on success, negative value otherwise.
461 *
462 * Caller holds tomoyo_read_lock().
500 */ 463 */
501static int tomoyo_update_no_rewrite_entry(const char *pattern, 464static int tomoyo_update_no_rewrite_entry(const char *pattern,
502 const bool is_delete) 465 const bool is_delete)
503{ 466{
504 struct tomoyo_no_rewrite_entry *new_entry, *ptr; 467 struct tomoyo_no_rewrite_entry *entry = NULL;
468 struct tomoyo_no_rewrite_entry *ptr;
505 const struct tomoyo_path_info *saved_pattern; 469 const struct tomoyo_path_info *saved_pattern;
506 int error = -ENOMEM; 470 int error = is_delete ? -ENOENT : -ENOMEM;
507 471
508 if (!tomoyo_is_correct_path(pattern, 0, 0, 0, __func__)) 472 if (!tomoyo_is_correct_path(pattern, 0, 0, 0))
509 return -EINVAL; 473 return -EINVAL;
510 saved_pattern = tomoyo_save_name(pattern); 474 saved_pattern = tomoyo_get_name(pattern);
511 if (!saved_pattern) 475 if (!saved_pattern)
512 return -ENOMEM; 476 return error;
513 down_write(&tomoyo_no_rewrite_list_lock); 477 if (!is_delete)
514 list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) { 478 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
479 mutex_lock(&tomoyo_policy_lock);
480 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
515 if (ptr->pattern != saved_pattern) 481 if (ptr->pattern != saved_pattern)
516 continue; 482 continue;
517 ptr->is_deleted = is_delete; 483 ptr->is_deleted = is_delete;
518 error = 0; 484 error = 0;
519 goto out; 485 break;
520 } 486 }
521 if (is_delete) { 487 if (!is_delete && error && tomoyo_memory_ok(entry)) {
522 error = -ENOENT; 488 entry->pattern = saved_pattern;
523 goto out; 489 saved_pattern = NULL;
490 list_add_tail_rcu(&entry->list, &tomoyo_no_rewrite_list);
491 entry = NULL;
492 error = 0;
524 } 493 }
525 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 494 mutex_unlock(&tomoyo_policy_lock);
526 if (!new_entry) 495 tomoyo_put_name(saved_pattern);
527 goto out; 496 kfree(entry);
528 new_entry->pattern = saved_pattern;
529 list_add_tail(&new_entry->list, &tomoyo_no_rewrite_list);
530 error = 0;
531 out:
532 up_write(&tomoyo_no_rewrite_list_lock);
533 return error; 497 return error;
534} 498}
535 499
@@ -540,14 +504,15 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
540 * 504 *
541 * Returns true if @filename is specified by "deny_rewrite" directive, 505 * Returns true if @filename is specified by "deny_rewrite" directive,
542 * false otherwise. 506 * false otherwise.
507 *
508 * Caller holds tomoyo_read_lock().
543 */ 509 */
544static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename) 510static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
545{ 511{
546 struct tomoyo_no_rewrite_entry *ptr; 512 struct tomoyo_no_rewrite_entry *ptr;
547 bool found = false; 513 bool found = false;
548 514
549 down_read(&tomoyo_no_rewrite_list_lock); 515 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
550 list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) {
551 if (ptr->is_deleted) 516 if (ptr->is_deleted)
552 continue; 517 continue;
553 if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) 518 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
@@ -555,7 +520,6 @@ static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
555 found = true; 520 found = true;
556 break; 521 break;
557 } 522 }
558 up_read(&tomoyo_no_rewrite_list_lock);
559 return found; 523 return found;
560} 524}
561 525
@@ -566,6 +530,8 @@ static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
566 * @is_delete: True if it is a delete request. 530 * @is_delete: True if it is a delete request.
567 * 531 *
568 * Returns 0 on success, negative value otherwise. 532 * Returns 0 on success, negative value otherwise.
533 *
534 * Caller holds tomoyo_read_lock().
569 */ 535 */
570int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete) 536int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete)
571{ 537{
@@ -578,13 +544,14 @@ int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete)
578 * @head: Pointer to "struct tomoyo_io_buffer". 544 * @head: Pointer to "struct tomoyo_io_buffer".
579 * 545 *
580 * Returns true on success, false otherwise. 546 * Returns true on success, false otherwise.
547 *
548 * Caller holds tomoyo_read_lock().
581 */ 549 */
582bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head) 550bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
583{ 551{
584 struct list_head *pos; 552 struct list_head *pos;
585 bool done = true; 553 bool done = true;
586 554
587 down_read(&tomoyo_no_rewrite_list_lock);
588 list_for_each_cookie(pos, head->read_var2, &tomoyo_no_rewrite_list) { 555 list_for_each_cookie(pos, head->read_var2, &tomoyo_no_rewrite_list) {
589 struct tomoyo_no_rewrite_entry *ptr; 556 struct tomoyo_no_rewrite_entry *ptr;
590 ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list); 557 ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list);
@@ -595,7 +562,6 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
595 if (!done) 562 if (!done)
596 break; 563 break;
597 } 564 }
598 up_read(&tomoyo_no_rewrite_list_lock);
599 return done; 565 return done;
600} 566}
601 567
@@ -613,6 +579,8 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
613 * Current policy syntax uses "allow_read/write" instead of "6", 579 * Current policy syntax uses "allow_read/write" instead of "6",
614 * "allow_read" instead of "4", "allow_write" instead of "2", 580 * "allow_read" instead of "4", "allow_write" instead of "2",
615 * "allow_execute" instead of "1". 581 * "allow_execute" instead of "1".
582 *
583 * Caller holds tomoyo_read_lock().
616 */ 584 */
617static int tomoyo_update_file_acl(const char *filename, u8 perm, 585static int tomoyo_update_file_acl(const char *filename, u8 perm,
618 struct tomoyo_domain_info * const domain, 586 struct tomoyo_domain_info * const domain,
@@ -630,19 +598,19 @@ static int tomoyo_update_file_acl(const char *filename, u8 perm,
630 */ 598 */
631 return 0; 599 return 0;
632 if (perm & 4) 600 if (perm & 4)
633 tomoyo_update_single_path_acl(TOMOYO_TYPE_READ_ACL, filename, 601 tomoyo_update_path_acl(TOMOYO_TYPE_READ, filename, domain,
634 domain, is_delete); 602 is_delete);
635 if (perm & 2) 603 if (perm & 2)
636 tomoyo_update_single_path_acl(TOMOYO_TYPE_WRITE_ACL, filename, 604 tomoyo_update_path_acl(TOMOYO_TYPE_WRITE, filename, domain,
637 domain, is_delete); 605 is_delete);
638 if (perm & 1) 606 if (perm & 1)
639 tomoyo_update_single_path_acl(TOMOYO_TYPE_EXECUTE_ACL, 607 tomoyo_update_path_acl(TOMOYO_TYPE_EXECUTE, filename, domain,
640 filename, domain, is_delete); 608 is_delete);
641 return 0; 609 return 0;
642} 610}
643 611
644/** 612/**
645 * tomoyo_check_single_path_acl2 - Check permission for single path operation. 613 * tomoyo_path_acl2 - Check permission for single path operation.
646 * 614 *
647 * @domain: Pointer to "struct tomoyo_domain_info". 615 * @domain: Pointer to "struct tomoyo_domain_info".
648 * @filename: Filename to check. 616 * @filename: Filename to check.
@@ -650,26 +618,28 @@ static int tomoyo_update_file_acl(const char *filename, u8 perm,
650 * @may_use_pattern: True if patterned ACL is permitted. 618 * @may_use_pattern: True if patterned ACL is permitted.
651 * 619 *
652 * Returns 0 on success, -EPERM otherwise. 620 * Returns 0 on success, -EPERM otherwise.
621 *
622 * Caller holds tomoyo_read_lock().
653 */ 623 */
654static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info * 624static int tomoyo_path_acl2(const struct tomoyo_domain_info *domain,
655 domain, 625 const struct tomoyo_path_info *filename,
656 const struct tomoyo_path_info * 626 const u32 perm, const bool may_use_pattern)
657 filename,
658 const u16 perm,
659 const bool may_use_pattern)
660{ 627{
661 struct tomoyo_acl_info *ptr; 628 struct tomoyo_acl_info *ptr;
662 int error = -EPERM; 629 int error = -EPERM;
663 630
664 down_read(&tomoyo_domain_acl_info_list_lock); 631 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
665 list_for_each_entry(ptr, &domain->acl_info_list, list) { 632 struct tomoyo_path_acl *acl;
666 struct tomoyo_single_path_acl_record *acl; 633 if (ptr->type != TOMOYO_TYPE_PATH_ACL)
667 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL)
668 continue;
669 acl = container_of(ptr, struct tomoyo_single_path_acl_record,
670 head);
671 if (!(acl->perm & perm))
672 continue; 634 continue;
635 acl = container_of(ptr, struct tomoyo_path_acl, head);
636 if (perm <= 0xFFFF) {
637 if (!(acl->perm & perm))
638 continue;
639 } else {
640 if (!(acl->perm_high & (perm >> 16)))
641 continue;
642 }
673 if (may_use_pattern || !acl->filename->is_patterned) { 643 if (may_use_pattern || !acl->filename->is_patterned) {
674 if (!tomoyo_path_matches_pattern(filename, 644 if (!tomoyo_path_matches_pattern(filename,
675 acl->filename)) 645 acl->filename))
@@ -680,7 +650,6 @@ static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info *
680 error = 0; 650 error = 0;
681 break; 651 break;
682 } 652 }
683 up_read(&tomoyo_domain_acl_info_list_lock);
684 return error; 653 return error;
685} 654}
686 655
@@ -692,27 +661,28 @@ static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info *
692 * @operation: Mode ("read" or "write" or "read/write" or "execute"). 661 * @operation: Mode ("read" or "write" or "read/write" or "execute").
693 * 662 *
694 * Returns 0 on success, -EPERM otherwise. 663 * Returns 0 on success, -EPERM otherwise.
664 *
665 * Caller holds tomoyo_read_lock().
695 */ 666 */
696static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain, 667static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain,
697 const struct tomoyo_path_info *filename, 668 const struct tomoyo_path_info *filename,
698 const u8 operation) 669 const u8 operation)
699{ 670{
700 u16 perm = 0; 671 u32 perm = 0;
701 672
702 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) 673 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
703 return 0; 674 return 0;
704 if (operation == 6) 675 if (operation == 6)
705 perm = 1 << TOMOYO_TYPE_READ_WRITE_ACL; 676 perm = 1 << TOMOYO_TYPE_READ_WRITE;
706 else if (operation == 4) 677 else if (operation == 4)
707 perm = 1 << TOMOYO_TYPE_READ_ACL; 678 perm = 1 << TOMOYO_TYPE_READ;
708 else if (operation == 2) 679 else if (operation == 2)
709 perm = 1 << TOMOYO_TYPE_WRITE_ACL; 680 perm = 1 << TOMOYO_TYPE_WRITE;
710 else if (operation == 1) 681 else if (operation == 1)
711 perm = 1 << TOMOYO_TYPE_EXECUTE_ACL; 682 perm = 1 << TOMOYO_TYPE_EXECUTE;
712 else 683 else
713 BUG(); 684 BUG();
714 return tomoyo_check_single_path_acl2(domain, filename, perm, 685 return tomoyo_path_acl2(domain, filename, perm, operation != 1);
715 operation != 1);
716} 686}
717 687
718/** 688/**
@@ -725,6 +695,8 @@ static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain,
725 * @mode: Access control mode. 695 * @mode: Access control mode.
726 * 696 *
727 * Returns 0 on success, negative value otherwise. 697 * Returns 0 on success, negative value otherwise.
698 *
699 * Caller holds tomoyo_read_lock().
728 */ 700 */
729static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain, 701static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
730 const struct tomoyo_path_info *filename, 702 const struct tomoyo_path_info *filename,
@@ -738,18 +710,17 @@ static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
738 if (!filename) 710 if (!filename)
739 return 0; 711 return 0;
740 error = tomoyo_check_file_acl(domain, filename, perm); 712 error = tomoyo_check_file_acl(domain, filename, perm);
741 if (error && perm == 4 && 713 if (error && perm == 4 && !domain->ignore_global_allow_read
742 (domain->flags & TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ) == 0
743 && tomoyo_is_globally_readable_file(filename)) 714 && tomoyo_is_globally_readable_file(filename))
744 error = 0; 715 error = 0;
745 if (perm == 6) 716 if (perm == 6)
746 msg = tomoyo_sp2keyword(TOMOYO_TYPE_READ_WRITE_ACL); 717 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ_WRITE);
747 else if (perm == 4) 718 else if (perm == 4)
748 msg = tomoyo_sp2keyword(TOMOYO_TYPE_READ_ACL); 719 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ);
749 else if (perm == 2) 720 else if (perm == 2)
750 msg = tomoyo_sp2keyword(TOMOYO_TYPE_WRITE_ACL); 721 msg = tomoyo_path2keyword(TOMOYO_TYPE_WRITE);
751 else if (perm == 1) 722 else if (perm == 1)
752 msg = tomoyo_sp2keyword(TOMOYO_TYPE_EXECUTE_ACL); 723 msg = tomoyo_path2keyword(TOMOYO_TYPE_EXECUTE);
753 else 724 else
754 BUG(); 725 BUG();
755 if (!error) 726 if (!error)
@@ -778,6 +749,8 @@ static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
778 * @is_delete: True if it is a delete request. 749 * @is_delete: True if it is a delete request.
779 * 750 *
780 * Returns 0 on success, negative value otherwise. 751 * Returns 0 on success, negative value otherwise.
752 *
753 * Caller holds tomoyo_read_lock().
781 */ 754 */
782int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain, 755int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
783 const bool is_delete) 756 const bool is_delete)
@@ -796,28 +769,28 @@ int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
796 if (strncmp(data, "allow_", 6)) 769 if (strncmp(data, "allow_", 6))
797 goto out; 770 goto out;
798 data += 6; 771 data += 6;
799 for (type = 0; type < TOMOYO_MAX_SINGLE_PATH_OPERATION; type++) { 772 for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++) {
800 if (strcmp(data, tomoyo_sp_keyword[type])) 773 if (strcmp(data, tomoyo_path_keyword[type]))
801 continue; 774 continue;
802 return tomoyo_update_single_path_acl(type, filename, 775 return tomoyo_update_path_acl(type, filename, domain,
803 domain, is_delete); 776 is_delete);
804 } 777 }
805 filename2 = strchr(filename, ' '); 778 filename2 = strchr(filename, ' ');
806 if (!filename2) 779 if (!filename2)
807 goto out; 780 goto out;
808 *filename2++ = '\0'; 781 *filename2++ = '\0';
809 for (type = 0; type < TOMOYO_MAX_DOUBLE_PATH_OPERATION; type++) { 782 for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++) {
810 if (strcmp(data, tomoyo_dp_keyword[type])) 783 if (strcmp(data, tomoyo_path2_keyword[type]))
811 continue; 784 continue;
812 return tomoyo_update_double_path_acl(type, filename, filename2, 785 return tomoyo_update_path2_acl(type, filename, filename2,
813 domain, is_delete); 786 domain, is_delete);
814 } 787 }
815 out: 788 out:
816 return -EINVAL; 789 return -EINVAL;
817} 790}
818 791
819/** 792/**
820 * tomoyo_update_single_path_acl - Update "struct tomoyo_single_path_acl_record" list. 793 * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list.
821 * 794 *
822 * @type: Type of operation. 795 * @type: Type of operation.
823 * @filename: Filename. 796 * @filename: Filename.
@@ -825,85 +798,82 @@ int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
825 * @is_delete: True if it is a delete request. 798 * @is_delete: True if it is a delete request.
826 * 799 *
827 * Returns 0 on success, negative value otherwise. 800 * Returns 0 on success, negative value otherwise.
801 *
802 * Caller holds tomoyo_read_lock().
828 */ 803 */
829static int tomoyo_update_single_path_acl(const u8 type, const char *filename, 804static int tomoyo_update_path_acl(const u8 type, const char *filename,
830 struct tomoyo_domain_info * 805 struct tomoyo_domain_info *const domain,
831 const domain, const bool is_delete) 806 const bool is_delete)
832{ 807{
833 static const u16 rw_mask = 808 static const u32 rw_mask =
834 (1 << TOMOYO_TYPE_READ_ACL) | (1 << TOMOYO_TYPE_WRITE_ACL); 809 (1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE);
835 const struct tomoyo_path_info *saved_filename; 810 const struct tomoyo_path_info *saved_filename;
836 struct tomoyo_acl_info *ptr; 811 struct tomoyo_acl_info *ptr;
837 struct tomoyo_single_path_acl_record *acl; 812 struct tomoyo_path_acl *entry = NULL;
838 int error = -ENOMEM; 813 int error = is_delete ? -ENOENT : -ENOMEM;
839 const u16 perm = 1 << type; 814 const u32 perm = 1 << type;
840 815
841 if (!domain) 816 if (!domain)
842 return -EINVAL; 817 return -EINVAL;
843 if (!tomoyo_is_correct_path(filename, 0, 0, 0, __func__)) 818 if (!tomoyo_is_correct_path(filename, 0, 0, 0))
844 return -EINVAL; 819 return -EINVAL;
845 saved_filename = tomoyo_save_name(filename); 820 saved_filename = tomoyo_get_name(filename);
846 if (!saved_filename) 821 if (!saved_filename)
847 return -ENOMEM; 822 return -ENOMEM;
848 down_write(&tomoyo_domain_acl_info_list_lock); 823 if (!is_delete)
849 if (is_delete) 824 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
850 goto delete; 825 mutex_lock(&tomoyo_policy_lock);
851 list_for_each_entry(ptr, &domain->acl_info_list, list) { 826 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
852 if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL) 827 struct tomoyo_path_acl *acl =
828 container_of(ptr, struct tomoyo_path_acl, head);
829 if (ptr->type != TOMOYO_TYPE_PATH_ACL)
853 continue; 830 continue;
854 acl = container_of(ptr, struct tomoyo_single_path_acl_record,
855 head);
856 if (acl->filename != saved_filename) 831 if (acl->filename != saved_filename)
857 continue; 832 continue;
858 /* Special case. Clear all bits if marked as deleted. */ 833 if (is_delete) {
859 if (ptr->type & TOMOYO_ACL_DELETED) 834 if (perm <= 0xFFFF)
860 acl->perm = 0; 835 acl->perm &= ~perm;
861 acl->perm |= perm; 836 else
862 if ((acl->perm & rw_mask) == rw_mask) 837 acl->perm_high &= ~(perm >> 16);
863 acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE_ACL; 838 if ((acl->perm & rw_mask) != rw_mask)
864 else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)) 839 acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE);
865 acl->perm |= rw_mask; 840 else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE)))
866 ptr->type &= ~TOMOYO_ACL_DELETED; 841 acl->perm &= ~rw_mask;
842 } else {
843 if (perm <= 0xFFFF)
844 acl->perm |= perm;
845 else
846 acl->perm_high |= (perm >> 16);
847 if ((acl->perm & rw_mask) == rw_mask)
848 acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE;
849 else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE))
850 acl->perm |= rw_mask;
851 }
867 error = 0; 852 error = 0;
868 goto out; 853 break;
869 } 854 }
870 /* Not found. Append it to the tail. */ 855 if (!is_delete && error && tomoyo_memory_ok(entry)) {
871 acl = tomoyo_alloc_acl_element(TOMOYO_TYPE_SINGLE_PATH_ACL); 856 entry->head.type = TOMOYO_TYPE_PATH_ACL;
872 if (!acl) 857 if (perm <= 0xFFFF)
873 goto out; 858 entry->perm = perm;
874 acl->perm = perm; 859 else
875 if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL)) 860 entry->perm_high = (perm >> 16);
876 acl->perm |= rw_mask; 861 if (perm == (1 << TOMOYO_TYPE_READ_WRITE))
877 acl->filename = saved_filename; 862 entry->perm |= rw_mask;
878 list_add_tail(&acl->head.list, &domain->acl_info_list); 863 entry->filename = saved_filename;
879 error = 0; 864 saved_filename = NULL;
880 goto out; 865 list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
881 delete: 866 entry = NULL;
882 error = -ENOENT;
883 list_for_each_entry(ptr, &domain->acl_info_list, list) {
884 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL)
885 continue;
886 acl = container_of(ptr, struct tomoyo_single_path_acl_record,
887 head);
888 if (acl->filename != saved_filename)
889 continue;
890 acl->perm &= ~perm;
891 if ((acl->perm & rw_mask) != rw_mask)
892 acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE_ACL);
893 else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)))
894 acl->perm &= ~rw_mask;
895 if (!acl->perm)
896 ptr->type |= TOMOYO_ACL_DELETED;
897 error = 0; 867 error = 0;
898 break;
899 } 868 }
900 out: 869 mutex_unlock(&tomoyo_policy_lock);
901 up_write(&tomoyo_domain_acl_info_list_lock); 870 kfree(entry);
871 tomoyo_put_name(saved_filename);
902 return error; 872 return error;
903} 873}
904 874
905/** 875/**
906 * tomoyo_update_double_path_acl - Update "struct tomoyo_double_path_acl_record" list. 876 * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list.
907 * 877 *
908 * @type: Type of operation. 878 * @type: Type of operation.
909 * @filename1: First filename. 879 * @filename1: First filename.
@@ -912,98 +882,88 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
912 * @is_delete: True if it is a delete request. 882 * @is_delete: True if it is a delete request.
913 * 883 *
914 * Returns 0 on success, negative value otherwise. 884 * Returns 0 on success, negative value otherwise.
885 *
886 * Caller holds tomoyo_read_lock().
915 */ 887 */
916static int tomoyo_update_double_path_acl(const u8 type, const char *filename1, 888static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
917 const char *filename2, 889 const char *filename2,
918 struct tomoyo_domain_info * 890 struct tomoyo_domain_info *const domain,
919 const domain, const bool is_delete) 891 const bool is_delete)
920{ 892{
921 const struct tomoyo_path_info *saved_filename1; 893 const struct tomoyo_path_info *saved_filename1;
922 const struct tomoyo_path_info *saved_filename2; 894 const struct tomoyo_path_info *saved_filename2;
923 struct tomoyo_acl_info *ptr; 895 struct tomoyo_acl_info *ptr;
924 struct tomoyo_double_path_acl_record *acl; 896 struct tomoyo_path2_acl *entry = NULL;
925 int error = -ENOMEM; 897 int error = is_delete ? -ENOENT : -ENOMEM;
926 const u8 perm = 1 << type; 898 const u8 perm = 1 << type;
927 899
928 if (!domain) 900 if (!domain)
929 return -EINVAL; 901 return -EINVAL;
930 if (!tomoyo_is_correct_path(filename1, 0, 0, 0, __func__) || 902 if (!tomoyo_is_correct_path(filename1, 0, 0, 0) ||
931 !tomoyo_is_correct_path(filename2, 0, 0, 0, __func__)) 903 !tomoyo_is_correct_path(filename2, 0, 0, 0))
932 return -EINVAL; 904 return -EINVAL;
933 saved_filename1 = tomoyo_save_name(filename1); 905 saved_filename1 = tomoyo_get_name(filename1);
934 saved_filename2 = tomoyo_save_name(filename2); 906 saved_filename2 = tomoyo_get_name(filename2);
935 if (!saved_filename1 || !saved_filename2) 907 if (!saved_filename1 || !saved_filename2)
936 return -ENOMEM;
937 down_write(&tomoyo_domain_acl_info_list_lock);
938 if (is_delete)
939 goto delete;
940 list_for_each_entry(ptr, &domain->acl_info_list, list) {
941 if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
942 continue;
943 acl = container_of(ptr, struct tomoyo_double_path_acl_record,
944 head);
945 if (acl->filename1 != saved_filename1 ||
946 acl->filename2 != saved_filename2)
947 continue;
948 /* Special case. Clear all bits if marked as deleted. */
949 if (ptr->type & TOMOYO_ACL_DELETED)
950 acl->perm = 0;
951 acl->perm |= perm;
952 ptr->type &= ~TOMOYO_ACL_DELETED;
953 error = 0;
954 goto out; 908 goto out;
955 } 909 if (!is_delete)
956 /* Not found. Append it to the tail. */ 910 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
957 acl = tomoyo_alloc_acl_element(TOMOYO_TYPE_DOUBLE_PATH_ACL); 911 mutex_lock(&tomoyo_policy_lock);
958 if (!acl) 912 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
959 goto out; 913 struct tomoyo_path2_acl *acl =
960 acl->perm = perm; 914 container_of(ptr, struct tomoyo_path2_acl, head);
961 acl->filename1 = saved_filename1; 915 if (ptr->type != TOMOYO_TYPE_PATH2_ACL)
962 acl->filename2 = saved_filename2;
963 list_add_tail(&acl->head.list, &domain->acl_info_list);
964 error = 0;
965 goto out;
966 delete:
967 error = -ENOENT;
968 list_for_each_entry(ptr, &domain->acl_info_list, list) {
969 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
970 continue; 916 continue;
971 acl = container_of(ptr, struct tomoyo_double_path_acl_record,
972 head);
973 if (acl->filename1 != saved_filename1 || 917 if (acl->filename1 != saved_filename1 ||
974 acl->filename2 != saved_filename2) 918 acl->filename2 != saved_filename2)
975 continue; 919 continue;
976 acl->perm &= ~perm; 920 if (is_delete)
977 if (!acl->perm) 921 acl->perm &= ~perm;
978 ptr->type |= TOMOYO_ACL_DELETED; 922 else
923 acl->perm |= perm;
979 error = 0; 924 error = 0;
980 break; 925 break;
981 } 926 }
927 if (!is_delete && error && tomoyo_memory_ok(entry)) {
928 entry->head.type = TOMOYO_TYPE_PATH2_ACL;
929 entry->perm = perm;
930 entry->filename1 = saved_filename1;
931 saved_filename1 = NULL;
932 entry->filename2 = saved_filename2;
933 saved_filename2 = NULL;
934 list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
935 entry = NULL;
936 error = 0;
937 }
938 mutex_unlock(&tomoyo_policy_lock);
982 out: 939 out:
983 up_write(&tomoyo_domain_acl_info_list_lock); 940 tomoyo_put_name(saved_filename1);
941 tomoyo_put_name(saved_filename2);
942 kfree(entry);
984 return error; 943 return error;
985} 944}
986 945
987/** 946/**
988 * tomoyo_check_single_path_acl - Check permission for single path operation. 947 * tomoyo_path_acl - Check permission for single path operation.
989 * 948 *
990 * @domain: Pointer to "struct tomoyo_domain_info". 949 * @domain: Pointer to "struct tomoyo_domain_info".
991 * @type: Type of operation. 950 * @type: Type of operation.
992 * @filename: Filename to check. 951 * @filename: Filename to check.
993 * 952 *
994 * Returns 0 on success, negative value otherwise. 953 * Returns 0 on success, negative value otherwise.
954 *
955 * Caller holds tomoyo_read_lock().
995 */ 956 */
996static int tomoyo_check_single_path_acl(struct tomoyo_domain_info *domain, 957static int tomoyo_path_acl(struct tomoyo_domain_info *domain, const u8 type,
997 const u8 type, 958 const struct tomoyo_path_info *filename)
998 const struct tomoyo_path_info *filename)
999{ 959{
1000 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) 960 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
1001 return 0; 961 return 0;
1002 return tomoyo_check_single_path_acl2(domain, filename, 1 << type, 1); 962 return tomoyo_path_acl2(domain, filename, 1 << type, 1);
1003} 963}
1004 964
1005/** 965/**
1006 * tomoyo_check_double_path_acl - Check permission for double path operation. 966 * tomoyo_path2_acl - Check permission for double path operation.
1007 * 967 *
1008 * @domain: Pointer to "struct tomoyo_domain_info". 968 * @domain: Pointer to "struct tomoyo_domain_info".
1009 * @type: Type of operation. 969 * @type: Type of operation.
@@ -1011,13 +971,13 @@ static int tomoyo_check_single_path_acl(struct tomoyo_domain_info *domain,
1011 * @filename2: Second filename to check. 971 * @filename2: Second filename to check.
1012 * 972 *
1013 * Returns 0 on success, -EPERM otherwise. 973 * Returns 0 on success, -EPERM otherwise.
974 *
975 * Caller holds tomoyo_read_lock().
1014 */ 976 */
1015static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain, 977static int tomoyo_path2_acl(const struct tomoyo_domain_info *domain,
1016 const u8 type, 978 const u8 type,
1017 const struct tomoyo_path_info * 979 const struct tomoyo_path_info *filename1,
1018 filename1, 980 const struct tomoyo_path_info *filename2)
1019 const struct tomoyo_path_info *
1020 filename2)
1021{ 981{
1022 struct tomoyo_acl_info *ptr; 982 struct tomoyo_acl_info *ptr;
1023 const u8 perm = 1 << type; 983 const u8 perm = 1 << type;
@@ -1025,13 +985,11 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
1025 985
1026 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) 986 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
1027 return 0; 987 return 0;
1028 down_read(&tomoyo_domain_acl_info_list_lock); 988 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
1029 list_for_each_entry(ptr, &domain->acl_info_list, list) { 989 struct tomoyo_path2_acl *acl;
1030 struct tomoyo_double_path_acl_record *acl; 990 if (ptr->type != TOMOYO_TYPE_PATH2_ACL)
1031 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
1032 continue; 991 continue;
1033 acl = container_of(ptr, struct tomoyo_double_path_acl_record, 992 acl = container_of(ptr, struct tomoyo_path2_acl, head);
1034 head);
1035 if (!(acl->perm & perm)) 993 if (!(acl->perm & perm))
1036 continue; 994 continue;
1037 if (!tomoyo_path_matches_pattern(filename1, acl->filename1)) 995 if (!tomoyo_path_matches_pattern(filename1, acl->filename1))
@@ -1041,12 +999,11 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
1041 error = 0; 999 error = 0;
1042 break; 1000 break;
1043 } 1001 }
1044 up_read(&tomoyo_domain_acl_info_list_lock);
1045 return error; 1002 return error;
1046} 1003}
1047 1004
1048/** 1005/**
1049 * tomoyo_check_single_path_permission2 - Check permission for single path operation. 1006 * tomoyo_path_permission2 - Check permission for single path operation.
1050 * 1007 *
1051 * @domain: Pointer to "struct tomoyo_domain_info". 1008 * @domain: Pointer to "struct tomoyo_domain_info".
1052 * @operation: Type of operation. 1009 * @operation: Type of operation.
@@ -1054,11 +1011,13 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
1054 * @mode: Access control mode. 1011 * @mode: Access control mode.
1055 * 1012 *
1056 * Returns 0 on success, negative value otherwise. 1013 * Returns 0 on success, negative value otherwise.
1014 *
1015 * Caller holds tomoyo_read_lock().
1057 */ 1016 */
1058static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info * 1017static int tomoyo_path_permission2(struct tomoyo_domain_info *const domain,
1059 const domain, u8 operation, 1018 u8 operation,
1060 const struct tomoyo_path_info * 1019 const struct tomoyo_path_info *filename,
1061 filename, const u8 mode) 1020 const u8 mode)
1062{ 1021{
1063 const char *msg; 1022 const char *msg;
1064 int error; 1023 int error;
@@ -1067,8 +1026,8 @@ static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info *
1067 if (!mode) 1026 if (!mode)
1068 return 0; 1027 return 0;
1069 next: 1028 next:
1070 error = tomoyo_check_single_path_acl(domain, operation, filename); 1029 error = tomoyo_path_acl(domain, operation, filename);
1071 msg = tomoyo_sp2keyword(operation); 1030 msg = tomoyo_path2keyword(operation);
1072 if (!error) 1031 if (!error)
1073 goto ok; 1032 goto ok;
1074 if (tomoyo_verbose_mode(domain)) 1033 if (tomoyo_verbose_mode(domain))
@@ -1077,7 +1036,7 @@ static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info *
1077 tomoyo_get_last_name(domain)); 1036 tomoyo_get_last_name(domain));
1078 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) { 1037 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) {
1079 const char *name = tomoyo_get_file_pattern(filename)->name; 1038 const char *name = tomoyo_get_file_pattern(filename)->name;
1080 tomoyo_update_single_path_acl(operation, name, domain, false); 1039 tomoyo_update_path_acl(operation, name, domain, false);
1081 } 1040 }
1082 if (!is_enforce) 1041 if (!is_enforce)
1083 error = 0; 1042 error = 0;
@@ -1087,42 +1046,23 @@ static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info *
1087 * we need to check "allow_rewrite" permission if the filename is 1046 * we need to check "allow_rewrite" permission if the filename is
1088 * specified by "deny_rewrite" keyword. 1047 * specified by "deny_rewrite" keyword.
1089 */ 1048 */
1090 if (!error && operation == TOMOYO_TYPE_TRUNCATE_ACL && 1049 if (!error && operation == TOMOYO_TYPE_TRUNCATE &&
1091 tomoyo_is_no_rewrite_file(filename)) { 1050 tomoyo_is_no_rewrite_file(filename)) {
1092 operation = TOMOYO_TYPE_REWRITE_ACL; 1051 operation = TOMOYO_TYPE_REWRITE;
1093 goto next; 1052 goto next;
1094 } 1053 }
1095 return error; 1054 return error;
1096} 1055}
1097 1056
1098/** 1057/**
1099 * tomoyo_check_file_perm - Check permission for sysctl()'s "read" and "write".
1100 *
1101 * @domain: Pointer to "struct tomoyo_domain_info".
1102 * @filename: Filename to check.
1103 * @perm: Mode ("read" or "write" or "read/write").
1104 * Returns 0 on success, negative value otherwise.
1105 */
1106int tomoyo_check_file_perm(struct tomoyo_domain_info *domain,
1107 const char *filename, const u8 perm)
1108{
1109 struct tomoyo_path_info name;
1110 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1111
1112 if (!mode)
1113 return 0;
1114 name.name = filename;
1115 tomoyo_fill_path_info(&name);
1116 return tomoyo_check_file_perm2(domain, &name, perm, "sysctl", mode);
1117}
1118
1119/**
1120 * tomoyo_check_exec_perm - Check permission for "execute". 1058 * tomoyo_check_exec_perm - Check permission for "execute".
1121 * 1059 *
1122 * @domain: Pointer to "struct tomoyo_domain_info". 1060 * @domain: Pointer to "struct tomoyo_domain_info".
1123 * @filename: Check permission for "execute". 1061 * @filename: Check permission for "execute".
1124 * 1062 *
1125 * Returns 0 on success, negativevalue otherwise. 1063 * Returns 0 on success, negativevalue otherwise.
1064 *
1065 * Caller holds tomoyo_read_lock().
1126 */ 1066 */
1127int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, 1067int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain,
1128 const struct tomoyo_path_info *filename) 1068 const struct tomoyo_path_info *filename)
@@ -1151,6 +1091,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1151 struct tomoyo_path_info *buf; 1091 struct tomoyo_path_info *buf;
1152 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1092 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1153 const bool is_enforce = (mode == 3); 1093 const bool is_enforce = (mode == 3);
1094 int idx;
1154 1095
1155 if (!mode || !path->mnt) 1096 if (!mode || !path->mnt)
1156 return 0; 1097 return 0;
@@ -1162,6 +1103,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1162 * don't call me. 1103 * don't call me.
1163 */ 1104 */
1164 return 0; 1105 return 0;
1106 idx = tomoyo_read_lock();
1165 buf = tomoyo_get_path(path); 1107 buf = tomoyo_get_path(path);
1166 if (!buf) 1108 if (!buf)
1167 goto out; 1109 goto out;
@@ -1174,49 +1116,50 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1174 if ((acc_mode & MAY_WRITE) && 1116 if ((acc_mode & MAY_WRITE) &&
1175 ((flag & O_TRUNC) || !(flag & O_APPEND)) && 1117 ((flag & O_TRUNC) || !(flag & O_APPEND)) &&
1176 (tomoyo_is_no_rewrite_file(buf))) { 1118 (tomoyo_is_no_rewrite_file(buf))) {
1177 error = tomoyo_check_single_path_permission2(domain, 1119 error = tomoyo_path_permission2(domain, TOMOYO_TYPE_REWRITE,
1178 TOMOYO_TYPE_REWRITE_ACL, 1120 buf, mode);
1179 buf, mode);
1180 } 1121 }
1181 if (!error) 1122 if (!error)
1182 error = tomoyo_check_file_perm2(domain, buf, acc_mode, "open", 1123 error = tomoyo_check_file_perm2(domain, buf, acc_mode, "open",
1183 mode); 1124 mode);
1184 if (!error && (flag & O_TRUNC)) 1125 if (!error && (flag & O_TRUNC))
1185 error = tomoyo_check_single_path_permission2(domain, 1126 error = tomoyo_path_permission2(domain, TOMOYO_TYPE_TRUNCATE,
1186 TOMOYO_TYPE_TRUNCATE_ACL, 1127 buf, mode);
1187 buf, mode);
1188 out: 1128 out:
1189 tomoyo_free(buf); 1129 kfree(buf);
1130 tomoyo_read_unlock(idx);
1190 if (!is_enforce) 1131 if (!is_enforce)
1191 error = 0; 1132 error = 0;
1192 return error; 1133 return error;
1193} 1134}
1194 1135
1195/** 1136/**
1196 * tomoyo_check_1path_perm - Check permission for "create", "unlink", "mkdir", "rmdir", "mkfifo", "mksock", "mkblock", "mkchar", "truncate" and "symlink". 1137 * tomoyo_path_perm - Check permission for "create", "unlink", "mkdir", "rmdir", "mkfifo", "mksock", "mkblock", "mkchar", "truncate", "symlink", "ioctl", "chmod", "chown", "chgrp", "chroot", "mount" and "unmount".
1197 * 1138 *
1198 * @domain: Pointer to "struct tomoyo_domain_info".
1199 * @operation: Type of operation. 1139 * @operation: Type of operation.
1200 * @path: Pointer to "struct path". 1140 * @path: Pointer to "struct path".
1201 * 1141 *
1202 * Returns 0 on success, negative value otherwise. 1142 * Returns 0 on success, negative value otherwise.
1203 */ 1143 */
1204int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain, 1144int tomoyo_path_perm(const u8 operation, struct path *path)
1205 const u8 operation, struct path *path)
1206{ 1145{
1207 int error = -ENOMEM; 1146 int error = -ENOMEM;
1208 struct tomoyo_path_info *buf; 1147 struct tomoyo_path_info *buf;
1148 struct tomoyo_domain_info *domain = tomoyo_domain();
1209 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1149 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1210 const bool is_enforce = (mode == 3); 1150 const bool is_enforce = (mode == 3);
1151 int idx;
1211 1152
1212 if (!mode || !path->mnt) 1153 if (!mode || !path->mnt)
1213 return 0; 1154 return 0;
1155 idx = tomoyo_read_lock();
1214 buf = tomoyo_get_path(path); 1156 buf = tomoyo_get_path(path);
1215 if (!buf) 1157 if (!buf)
1216 goto out; 1158 goto out;
1217 switch (operation) { 1159 switch (operation) {
1218 case TOMOYO_TYPE_MKDIR_ACL: 1160 case TOMOYO_TYPE_MKDIR:
1219 case TOMOYO_TYPE_RMDIR_ACL: 1161 case TOMOYO_TYPE_RMDIR:
1162 case TOMOYO_TYPE_CHROOT:
1220 if (!buf->is_dir) { 1163 if (!buf->is_dir) {
1221 /* 1164 /*
1222 * tomoyo_get_path() reserves space for appending "/." 1165 * tomoyo_get_path() reserves space for appending "/."
@@ -1225,10 +1168,10 @@ int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain,
1225 tomoyo_fill_path_info(buf); 1168 tomoyo_fill_path_info(buf);
1226 } 1169 }
1227 } 1170 }
1228 error = tomoyo_check_single_path_permission2(domain, operation, buf, 1171 error = tomoyo_path_permission2(domain, operation, buf, mode);
1229 mode);
1230 out: 1172 out:
1231 tomoyo_free(buf); 1173 kfree(buf);
1174 tomoyo_read_unlock(idx);
1232 if (!is_enforce) 1175 if (!is_enforce)
1233 error = 0; 1176 error = 0;
1234 return error; 1177 return error;
@@ -1237,21 +1180,23 @@ int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain,
1237/** 1180/**
1238 * tomoyo_check_rewrite_permission - Check permission for "rewrite". 1181 * tomoyo_check_rewrite_permission - Check permission for "rewrite".
1239 * 1182 *
1240 * @domain: Pointer to "struct tomoyo_domain_info".
1241 * @filp: Pointer to "struct file". 1183 * @filp: Pointer to "struct file".
1242 * 1184 *
1243 * Returns 0 on success, negative value otherwise. 1185 * Returns 0 on success, negative value otherwise.
1244 */ 1186 */
1245int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain, 1187int tomoyo_check_rewrite_permission(struct file *filp)
1246 struct file *filp)
1247{ 1188{
1248 int error = -ENOMEM; 1189 int error = -ENOMEM;
1190 struct tomoyo_domain_info *domain = tomoyo_domain();
1249 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1191 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1250 const bool is_enforce = (mode == 3); 1192 const bool is_enforce = (mode == 3);
1251 struct tomoyo_path_info *buf; 1193 struct tomoyo_path_info *buf;
1194 int idx;
1252 1195
1253 if (!mode || !filp->f_path.mnt) 1196 if (!mode || !filp->f_path.mnt)
1254 return 0; 1197 return 0;
1198
1199 idx = tomoyo_read_lock();
1255 buf = tomoyo_get_path(&filp->f_path); 1200 buf = tomoyo_get_path(&filp->f_path);
1256 if (!buf) 1201 if (!buf)
1257 goto out; 1202 goto out;
@@ -1259,38 +1204,38 @@ int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain,
1259 error = 0; 1204 error = 0;
1260 goto out; 1205 goto out;
1261 } 1206 }
1262 error = tomoyo_check_single_path_permission2(domain, 1207 error = tomoyo_path_permission2(domain, TOMOYO_TYPE_REWRITE, buf, mode);
1263 TOMOYO_TYPE_REWRITE_ACL,
1264 buf, mode);
1265 out: 1208 out:
1266 tomoyo_free(buf); 1209 kfree(buf);
1210 tomoyo_read_unlock(idx);
1267 if (!is_enforce) 1211 if (!is_enforce)
1268 error = 0; 1212 error = 0;
1269 return error; 1213 return error;
1270} 1214}
1271 1215
1272/** 1216/**
1273 * tomoyo_check_2path_perm - Check permission for "rename" and "link". 1217 * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root".
1274 * 1218 *
1275 * @domain: Pointer to "struct tomoyo_domain_info".
1276 * @operation: Type of operation. 1219 * @operation: Type of operation.
1277 * @path1: Pointer to "struct path". 1220 * @path1: Pointer to "struct path".
1278 * @path2: Pointer to "struct path". 1221 * @path2: Pointer to "struct path".
1279 * 1222 *
1280 * Returns 0 on success, negative value otherwise. 1223 * Returns 0 on success, negative value otherwise.
1281 */ 1224 */
1282int tomoyo_check_2path_perm(struct tomoyo_domain_info * const domain, 1225int tomoyo_path2_perm(const u8 operation, struct path *path1,
1283 const u8 operation, struct path *path1, 1226 struct path *path2)
1284 struct path *path2)
1285{ 1227{
1286 int error = -ENOMEM; 1228 int error = -ENOMEM;
1287 struct tomoyo_path_info *buf1, *buf2; 1229 struct tomoyo_path_info *buf1, *buf2;
1230 struct tomoyo_domain_info *domain = tomoyo_domain();
1288 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1231 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1289 const bool is_enforce = (mode == 3); 1232 const bool is_enforce = (mode == 3);
1290 const char *msg; 1233 const char *msg;
1234 int idx;
1291 1235
1292 if (!mode || !path1->mnt || !path2->mnt) 1236 if (!mode || !path1->mnt || !path2->mnt)
1293 return 0; 1237 return 0;
1238 idx = tomoyo_read_lock();
1294 buf1 = tomoyo_get_path(path1); 1239 buf1 = tomoyo_get_path(path1);
1295 buf2 = tomoyo_get_path(path2); 1240 buf2 = tomoyo_get_path(path2);
1296 if (!buf1 || !buf2) 1241 if (!buf1 || !buf2)
@@ -1311,8 +1256,8 @@ int tomoyo_check_2path_perm(struct tomoyo_domain_info * const domain,
1311 } 1256 }
1312 } 1257 }
1313 } 1258 }
1314 error = tomoyo_check_double_path_acl(domain, operation, buf1, buf2); 1259 error = tomoyo_path2_acl(domain, operation, buf1, buf2);
1315 msg = tomoyo_dp2keyword(operation); 1260 msg = tomoyo_path22keyword(operation);
1316 if (!error) 1261 if (!error)
1317 goto out; 1262 goto out;
1318 if (tomoyo_verbose_mode(domain)) 1263 if (tomoyo_verbose_mode(domain))
@@ -1323,12 +1268,13 @@ int tomoyo_check_2path_perm(struct tomoyo_domain_info * const domain,
1323 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) { 1268 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) {
1324 const char *name1 = tomoyo_get_file_pattern(buf1)->name; 1269 const char *name1 = tomoyo_get_file_pattern(buf1)->name;
1325 const char *name2 = tomoyo_get_file_pattern(buf2)->name; 1270 const char *name2 = tomoyo_get_file_pattern(buf2)->name;
1326 tomoyo_update_double_path_acl(operation, name1, name2, domain, 1271 tomoyo_update_path2_acl(operation, name1, name2, domain,
1327 false); 1272 false);
1328 } 1273 }
1329 out: 1274 out:
1330 tomoyo_free(buf1); 1275 kfree(buf1);
1331 tomoyo_free(buf2); 1276 kfree(buf2);
1277 tomoyo_read_unlock(idx);
1332 if (!is_enforce) 1278 if (!is_enforce)
1333 error = 0; 1279 error = 0;
1334 return error; 1280 return error;
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c
new file mode 100644
index 000000000000..d9ad35bc7fa8
--- /dev/null
+++ b/security/tomoyo/gc.c
@@ -0,0 +1,371 @@
1/*
2 * security/tomoyo/gc.c
3 *
4 * Implementation of the Domain-Based Mandatory Access Control.
5 *
6 * Copyright (C) 2005-2010 NTT DATA CORPORATION
7 *
8 */
9
10#include "common.h"
11#include <linux/kthread.h>
12#include <linux/slab.h>
13
14enum tomoyo_gc_id {
15 TOMOYO_ID_DOMAIN_INITIALIZER,
16 TOMOYO_ID_DOMAIN_KEEPER,
17 TOMOYO_ID_ALIAS,
18 TOMOYO_ID_GLOBALLY_READABLE,
19 TOMOYO_ID_PATTERN,
20 TOMOYO_ID_NO_REWRITE,
21 TOMOYO_ID_MANAGER,
22 TOMOYO_ID_NAME,
23 TOMOYO_ID_ACL,
24 TOMOYO_ID_DOMAIN
25};
26
27struct tomoyo_gc_entry {
28 struct list_head list;
29 int type;
30 void *element;
31};
32static LIST_HEAD(tomoyo_gc_queue);
33static DEFINE_MUTEX(tomoyo_gc_mutex);
34
35/* Caller holds tomoyo_policy_lock mutex. */
36static bool tomoyo_add_to_gc(const int type, void *element)
37{
38 struct tomoyo_gc_entry *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
39 if (!entry)
40 return false;
41 entry->type = type;
42 entry->element = element;
43 list_add(&entry->list, &tomoyo_gc_queue);
44 return true;
45}
46
47static void tomoyo_del_allow_read
48(struct tomoyo_globally_readable_file_entry *ptr)
49{
50 tomoyo_put_name(ptr->filename);
51}
52
53static void tomoyo_del_file_pattern(struct tomoyo_pattern_entry *ptr)
54{
55 tomoyo_put_name(ptr->pattern);
56}
57
58static void tomoyo_del_no_rewrite(struct tomoyo_no_rewrite_entry *ptr)
59{
60 tomoyo_put_name(ptr->pattern);
61}
62
63static void tomoyo_del_domain_initializer
64(struct tomoyo_domain_initializer_entry *ptr)
65{
66 tomoyo_put_name(ptr->domainname);
67 tomoyo_put_name(ptr->program);
68}
69
70static void tomoyo_del_domain_keeper(struct tomoyo_domain_keeper_entry *ptr)
71{
72 tomoyo_put_name(ptr->domainname);
73 tomoyo_put_name(ptr->program);
74}
75
76static void tomoyo_del_alias(struct tomoyo_alias_entry *ptr)
77{
78 tomoyo_put_name(ptr->original_name);
79 tomoyo_put_name(ptr->aliased_name);
80}
81
82static void tomoyo_del_manager(struct tomoyo_policy_manager_entry *ptr)
83{
84 tomoyo_put_name(ptr->manager);
85}
86
87static void tomoyo_del_acl(struct tomoyo_acl_info *acl)
88{
89 switch (acl->type) {
90 case TOMOYO_TYPE_PATH_ACL:
91 {
92 struct tomoyo_path_acl *entry
93 = container_of(acl, typeof(*entry), head);
94 tomoyo_put_name(entry->filename);
95 }
96 break;
97 case TOMOYO_TYPE_PATH2_ACL:
98 {
99 struct tomoyo_path2_acl *entry
100 = container_of(acl, typeof(*entry), head);
101 tomoyo_put_name(entry->filename1);
102 tomoyo_put_name(entry->filename2);
103 }
104 break;
105 default:
106 printk(KERN_WARNING "Unknown type\n");
107 break;
108 }
109}
110
111static bool tomoyo_del_domain(struct tomoyo_domain_info *domain)
112{
113 struct tomoyo_acl_info *acl;
114 struct tomoyo_acl_info *tmp;
115 /*
116 * Since we don't protect whole execve() operation using SRCU,
117 * we need to recheck domain->users at this point.
118 *
119 * (1) Reader starts SRCU section upon execve().
120 * (2) Reader traverses tomoyo_domain_list and finds this domain.
121 * (3) Writer marks this domain as deleted.
122 * (4) Garbage collector removes this domain from tomoyo_domain_list
123 * because this domain is marked as deleted and used by nobody.
124 * (5) Reader saves reference to this domain into
125 * "struct linux_binprm"->cred->security .
126 * (6) Reader finishes SRCU section, although execve() operation has
127 * not finished yet.
128 * (7) Garbage collector waits for SRCU synchronization.
129 * (8) Garbage collector kfree() this domain because this domain is
130 * used by nobody.
131 * (9) Reader finishes execve() operation and restores this domain from
132 * "struct linux_binprm"->cred->security.
133 *
134 * By updating domain->users at (5), we can solve this race problem
135 * by rechecking domain->users at (8).
136 */
137 if (atomic_read(&domain->users))
138 return false;
139 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
140 tomoyo_del_acl(acl);
141 tomoyo_memory_free(acl);
142 }
143 tomoyo_put_name(domain->domainname);
144 return true;
145}
146
147
148static void tomoyo_del_name(const struct tomoyo_name_entry *ptr)
149{
150}
151
152static void tomoyo_collect_entry(void)
153{
154 mutex_lock(&tomoyo_policy_lock);
155 {
156 struct tomoyo_globally_readable_file_entry *ptr;
157 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list,
158 list) {
159 if (!ptr->is_deleted)
160 continue;
161 if (tomoyo_add_to_gc(TOMOYO_ID_GLOBALLY_READABLE, ptr))
162 list_del_rcu(&ptr->list);
163 else
164 break;
165 }
166 }
167 {
168 struct tomoyo_pattern_entry *ptr;
169 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
170 if (!ptr->is_deleted)
171 continue;
172 if (tomoyo_add_to_gc(TOMOYO_ID_PATTERN, ptr))
173 list_del_rcu(&ptr->list);
174 else
175 break;
176 }
177 }
178 {
179 struct tomoyo_no_rewrite_entry *ptr;
180 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
181 if (!ptr->is_deleted)
182 continue;
183 if (tomoyo_add_to_gc(TOMOYO_ID_NO_REWRITE, ptr))
184 list_del_rcu(&ptr->list);
185 else
186 break;
187 }
188 }
189 {
190 struct tomoyo_domain_initializer_entry *ptr;
191 list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list,
192 list) {
193 if (!ptr->is_deleted)
194 continue;
195 if (tomoyo_add_to_gc(TOMOYO_ID_DOMAIN_INITIALIZER, ptr))
196 list_del_rcu(&ptr->list);
197 else
198 break;
199 }
200 }
201 {
202 struct tomoyo_domain_keeper_entry *ptr;
203 list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
204 if (!ptr->is_deleted)
205 continue;
206 if (tomoyo_add_to_gc(TOMOYO_ID_DOMAIN_KEEPER, ptr))
207 list_del_rcu(&ptr->list);
208 else
209 break;
210 }
211 }
212 {
213 struct tomoyo_alias_entry *ptr;
214 list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
215 if (!ptr->is_deleted)
216 continue;
217 if (tomoyo_add_to_gc(TOMOYO_ID_ALIAS, ptr))
218 list_del_rcu(&ptr->list);
219 else
220 break;
221 }
222 }
223 {
224 struct tomoyo_policy_manager_entry *ptr;
225 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list,
226 list) {
227 if (!ptr->is_deleted)
228 continue;
229 if (tomoyo_add_to_gc(TOMOYO_ID_MANAGER, ptr))
230 list_del_rcu(&ptr->list);
231 else
232 break;
233 }
234 }
235 {
236 struct tomoyo_domain_info *domain;
237 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
238 struct tomoyo_acl_info *acl;
239 list_for_each_entry_rcu(acl, &domain->acl_info_list,
240 list) {
241 switch (acl->type) {
242 case TOMOYO_TYPE_PATH_ACL:
243 if (container_of(acl,
244 struct tomoyo_path_acl,
245 head)->perm ||
246 container_of(acl,
247 struct tomoyo_path_acl,
248 head)->perm_high)
249 continue;
250 break;
251 case TOMOYO_TYPE_PATH2_ACL:
252 if (container_of(acl,
253 struct tomoyo_path2_acl,
254 head)->perm)
255 continue;
256 break;
257 default:
258 continue;
259 }
260 if (tomoyo_add_to_gc(TOMOYO_ID_ACL, acl))
261 list_del_rcu(&acl->list);
262 else
263 break;
264 }
265 if (!domain->is_deleted || atomic_read(&domain->users))
266 continue;
267 /*
268 * Nobody is referring this domain. But somebody may
269 * refer this domain after successful execve().
270 * We recheck domain->users after SRCU synchronization.
271 */
272 if (tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, domain))
273 list_del_rcu(&domain->list);
274 else
275 break;
276 }
277 }
278 mutex_unlock(&tomoyo_policy_lock);
279 mutex_lock(&tomoyo_name_list_lock);
280 {
281 int i;
282 for (i = 0; i < TOMOYO_MAX_HASH; i++) {
283 struct tomoyo_name_entry *ptr;
284 list_for_each_entry_rcu(ptr, &tomoyo_name_list[i],
285 list) {
286 if (atomic_read(&ptr->users))
287 continue;
288 if (tomoyo_add_to_gc(TOMOYO_ID_NAME, ptr))
289 list_del_rcu(&ptr->list);
290 else {
291 i = TOMOYO_MAX_HASH;
292 break;
293 }
294 }
295 }
296 }
297 mutex_unlock(&tomoyo_name_list_lock);
298}
299
300static void tomoyo_kfree_entry(void)
301{
302 struct tomoyo_gc_entry *p;
303 struct tomoyo_gc_entry *tmp;
304
305 list_for_each_entry_safe(p, tmp, &tomoyo_gc_queue, list) {
306 switch (p->type) {
307 case TOMOYO_ID_DOMAIN_INITIALIZER:
308 tomoyo_del_domain_initializer(p->element);
309 break;
310 case TOMOYO_ID_DOMAIN_KEEPER:
311 tomoyo_del_domain_keeper(p->element);
312 break;
313 case TOMOYO_ID_ALIAS:
314 tomoyo_del_alias(p->element);
315 break;
316 case TOMOYO_ID_GLOBALLY_READABLE:
317 tomoyo_del_allow_read(p->element);
318 break;
319 case TOMOYO_ID_PATTERN:
320 tomoyo_del_file_pattern(p->element);
321 break;
322 case TOMOYO_ID_NO_REWRITE:
323 tomoyo_del_no_rewrite(p->element);
324 break;
325 case TOMOYO_ID_MANAGER:
326 tomoyo_del_manager(p->element);
327 break;
328 case TOMOYO_ID_NAME:
329 tomoyo_del_name(p->element);
330 break;
331 case TOMOYO_ID_ACL:
332 tomoyo_del_acl(p->element);
333 break;
334 case TOMOYO_ID_DOMAIN:
335 if (!tomoyo_del_domain(p->element))
336 continue;
337 break;
338 default:
339 printk(KERN_WARNING "Unknown type\n");
340 break;
341 }
342 tomoyo_memory_free(p->element);
343 list_del(&p->list);
344 kfree(p);
345 }
346}
347
348static int tomoyo_gc_thread(void *unused)
349{
350 daemonize("GC for TOMOYO");
351 if (mutex_trylock(&tomoyo_gc_mutex)) {
352 int i;
353 for (i = 0; i < 10; i++) {
354 tomoyo_collect_entry();
355 if (list_empty(&tomoyo_gc_queue))
356 break;
357 synchronize_srcu(&tomoyo_ss);
358 tomoyo_kfree_entry();
359 }
360 mutex_unlock(&tomoyo_gc_mutex);
361 }
362 do_exit(0);
363}
364
365void tomoyo_run_gc(void)
366{
367 struct task_struct *task = kthread_create(tomoyo_gc_thread, NULL,
368 "GC for TOMOYO");
369 if (!IS_ERR(task))
370 wake_up_process(task);
371}
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 5f2e33263371..c225c65ce426 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -13,8 +13,10 @@
13#include <linux/mount.h> 13#include <linux/mount.h>
14#include <linux/mnt_namespace.h> 14#include <linux/mnt_namespace.h>
15#include <linux/fs_struct.h> 15#include <linux/fs_struct.h>
16#include <linux/hash.h>
17#include <linux/magic.h>
18#include <linux/slab.h>
16#include "common.h" 19#include "common.h"
17#include "realpath.h"
18 20
19/** 21/**
20 * tomoyo_encode: Convert binary string to ascii string. 22 * tomoyo_encode: Convert binary string to ascii string.
@@ -87,27 +89,21 @@ int tomoyo_realpath_from_path2(struct path *path, char *newname,
87 sp = dentry->d_op->d_dname(dentry, newname + offset, 89 sp = dentry->d_op->d_dname(dentry, newname + offset,
88 newname_len - offset); 90 newname_len - offset);
89 } else { 91 } else {
90 /* Taken from d_namespace_path(). */ 92 struct path ns_root = {.mnt = NULL, .dentry = NULL};
91 struct path root;
92 struct path ns_root = { };
93 struct path tmp;
94 93
95 read_lock(&current->fs->lock);
96 root = current->fs->root;
97 path_get(&root);
98 read_unlock(&current->fs->lock);
99 spin_lock(&vfsmount_lock);
100 if (root.mnt && root.mnt->mnt_ns)
101 ns_root.mnt = mntget(root.mnt->mnt_ns->root);
102 if (ns_root.mnt)
103 ns_root.dentry = dget(ns_root.mnt->mnt_root);
104 spin_unlock(&vfsmount_lock);
105 spin_lock(&dcache_lock); 94 spin_lock(&dcache_lock);
106 tmp = ns_root; 95 /* go to whatever namespace root we are under */
107 sp = __d_path(path, &tmp, newname, newname_len); 96 sp = __d_path(path, &ns_root, newname, newname_len);
108 spin_unlock(&dcache_lock); 97 spin_unlock(&dcache_lock);
109 path_put(&root); 98 /* Prepend "/proc" prefix if using internal proc vfs mount. */
110 path_put(&ns_root); 99 if (!IS_ERR(sp) && (path->mnt->mnt_flags & MNT_INTERNAL) &&
100 (path->mnt->mnt_sb->s_magic == PROC_SUPER_MAGIC)) {
101 sp -= 5;
102 if (sp >= newname)
103 memcpy(sp, "/proc", 5);
104 else
105 sp = ERR_PTR(-ENOMEM);
106 }
111 } 107 }
112 if (IS_ERR(sp)) 108 if (IS_ERR(sp))
113 error = PTR_ERR(sp); 109 error = PTR_ERR(sp);
@@ -138,12 +134,12 @@ int tomoyo_realpath_from_path2(struct path *path, char *newname,
138 * 134 *
139 * Returns the realpath of the given @path on success, NULL otherwise. 135 * Returns the realpath of the given @path on success, NULL otherwise.
140 * 136 *
141 * These functions use tomoyo_alloc(), so the caller must call tomoyo_free() 137 * These functions use kzalloc(), so the caller must call kfree()
142 * if these functions didn't return NULL. 138 * if these functions didn't return NULL.
143 */ 139 */
144char *tomoyo_realpath_from_path(struct path *path) 140char *tomoyo_realpath_from_path(struct path *path)
145{ 141{
146 char *buf = tomoyo_alloc(sizeof(struct tomoyo_page_buffer)); 142 char *buf = kzalloc(sizeof(struct tomoyo_page_buffer), GFP_KERNEL);
147 143
148 BUILD_BUG_ON(sizeof(struct tomoyo_page_buffer) 144 BUILD_BUG_ON(sizeof(struct tomoyo_page_buffer)
149 <= TOMOYO_MAX_PATHNAME_LEN - 1); 145 <= TOMOYO_MAX_PATHNAME_LEN - 1);
@@ -152,7 +148,7 @@ char *tomoyo_realpath_from_path(struct path *path)
152 if (tomoyo_realpath_from_path2(path, buf, 148 if (tomoyo_realpath_from_path2(path, buf,
153 TOMOYO_MAX_PATHNAME_LEN - 1) == 0) 149 TOMOYO_MAX_PATHNAME_LEN - 1) == 0)
154 return buf; 150 return buf;
155 tomoyo_free(buf); 151 kfree(buf);
156 return NULL; 152 return NULL;
157} 153}
158 154
@@ -195,97 +191,47 @@ char *tomoyo_realpath_nofollow(const char *pathname)
195} 191}
196 192
197/* Memory allocated for non-string data. */ 193/* Memory allocated for non-string data. */
198static unsigned int tomoyo_allocated_memory_for_elements; 194static atomic_t tomoyo_policy_memory_size;
199/* Quota for holding non-string data. */ 195/* Quota for holding policy. */
200static unsigned int tomoyo_quota_for_elements; 196static unsigned int tomoyo_quota_for_policy;
201 197
202/** 198/**
203 * tomoyo_alloc_element - Allocate permanent memory for structures. 199 * tomoyo_memory_ok - Check memory quota.
204 * 200 *
205 * @size: Size in bytes. 201 * @ptr: Pointer to allocated memory.
206 * 202 *
207 * Returns pointer to allocated memory on success, NULL otherwise. 203 * Returns true on success, false otherwise.
208 * 204 *
209 * Memory has to be zeroed. 205 * Caller holds tomoyo_policy_lock.
210 * The RAM is chunked, so NEVER try to kfree() the returned pointer. 206 * Memory pointed by @ptr will be zeroed on success.
211 */ 207 */
212void *tomoyo_alloc_element(const unsigned int size) 208bool tomoyo_memory_ok(void *ptr)
213{ 209{
214 static char *buf; 210 int allocated_len = ptr ? ksize(ptr) : 0;
215 static DEFINE_MUTEX(lock); 211 atomic_add(allocated_len, &tomoyo_policy_memory_size);
216 static unsigned int buf_used_len = PATH_MAX; 212 if (ptr && (!tomoyo_quota_for_policy ||
217 char *ptr = NULL; 213 atomic_read(&tomoyo_policy_memory_size)
218 /*Assumes sizeof(void *) >= sizeof(long) is true. */ 214 <= tomoyo_quota_for_policy)) {
219 const unsigned int word_aligned_size 215 memset(ptr, 0, allocated_len);
220 = roundup(size, max(sizeof(void *), sizeof(long))); 216 return true;
221 if (word_aligned_size > PATH_MAX)
222 return NULL;
223 mutex_lock(&lock);
224 if (buf_used_len + word_aligned_size > PATH_MAX) {
225 if (!tomoyo_quota_for_elements ||
226 tomoyo_allocated_memory_for_elements
227 + PATH_MAX <= tomoyo_quota_for_elements)
228 ptr = kzalloc(PATH_MAX, GFP_KERNEL);
229 if (!ptr) {
230 printk(KERN_WARNING "ERROR: Out of memory "
231 "for tomoyo_alloc_element().\n");
232 if (!tomoyo_policy_loaded)
233 panic("MAC Initialization failed.\n");
234 } else {
235 buf = ptr;
236 tomoyo_allocated_memory_for_elements += PATH_MAX;
237 buf_used_len = word_aligned_size;
238 ptr = buf;
239 }
240 } else if (word_aligned_size) {
241 int i;
242 ptr = buf + buf_used_len;
243 buf_used_len += word_aligned_size;
244 for (i = 0; i < word_aligned_size; i++) {
245 if (!ptr[i])
246 continue;
247 printk(KERN_ERR "WARNING: Reserved memory was tainted! "
248 "The system might go wrong.\n");
249 ptr[i] = '\0';
250 }
251 } 217 }
252 mutex_unlock(&lock); 218 printk(KERN_WARNING "ERROR: Out of memory "
253 return ptr; 219 "for tomoyo_alloc_element().\n");
220 if (!tomoyo_policy_loaded)
221 panic("MAC Initialization failed.\n");
222 return false;
254} 223}
255 224
256/* Memory allocated for string data in bytes. */ 225/**
257static unsigned int tomoyo_allocated_memory_for_savename; 226 * tomoyo_memory_free - Free memory for elements.
258/* Quota for holding string data in bytes. */
259static unsigned int tomoyo_quota_for_savename;
260
261/*
262 * TOMOYO uses this hash only when appending a string into the string
263 * table. Frequency of appending strings is very low. So we don't need
264 * large (e.g. 64k) hash size. 256 will be sufficient.
265 */
266#define TOMOYO_MAX_HASH 256
267
268/*
269 * tomoyo_name_entry is a structure which is used for linking
270 * "struct tomoyo_path_info" into tomoyo_name_list .
271 * 227 *
272 * Since tomoyo_name_list manages a list of strings which are shared by 228 * @ptr: Pointer to allocated memory.
273 * multiple processes (whereas "struct tomoyo_path_info" inside
274 * "struct tomoyo_path_info_with_data" is not shared), a reference counter will
275 * be added to "struct tomoyo_name_entry" rather than "struct tomoyo_path_info"
276 * when TOMOYO starts supporting garbage collector.
277 */ 229 */
278struct tomoyo_name_entry { 230void tomoyo_memory_free(void *ptr)
279 struct list_head list; 231{
280 struct tomoyo_path_info entry; 232 atomic_sub(ksize(ptr), &tomoyo_policy_memory_size);
281}; 233 kfree(ptr);
282 234}
283/* Structure for available memory region. */
284struct tomoyo_free_memory_block_list {
285 struct list_head list;
286 char *ptr; /* Pointer to a free area. */
287 int len; /* Length of the area. */
288};
289 235
290/* 236/*
291 * tomoyo_name_list is used for holding string data used by TOMOYO. 237 * tomoyo_name_list is used for holding string data used by TOMOYO.
@@ -293,85 +239,58 @@ struct tomoyo_free_memory_block_list {
293 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of 239 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of
294 * "const struct tomoyo_path_info *". 240 * "const struct tomoyo_path_info *".
295 */ 241 */
296static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; 242struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
243/* Lock for protecting tomoyo_name_list . */
244DEFINE_MUTEX(tomoyo_name_list_lock);
297 245
298/** 246/**
299 * tomoyo_save_name - Allocate permanent memory for string data. 247 * tomoyo_get_name - Allocate permanent memory for string data.
300 * 248 *
301 * @name: The string to store into the permernent memory. 249 * @name: The string to store into the permernent memory.
302 * 250 *
303 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. 251 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
304 *
305 * The RAM is shared, so NEVER try to modify or kfree() the returned name.
306 */ 252 */
307const struct tomoyo_path_info *tomoyo_save_name(const char *name) 253const struct tomoyo_path_info *tomoyo_get_name(const char *name)
308{ 254{
309 static LIST_HEAD(fmb_list);
310 static DEFINE_MUTEX(lock);
311 struct tomoyo_name_entry *ptr; 255 struct tomoyo_name_entry *ptr;
312 unsigned int hash; 256 unsigned int hash;
313 /* fmb contains available size in bytes.
314 fmb is removed from the fmb_list when fmb->len becomes 0. */
315 struct tomoyo_free_memory_block_list *fmb;
316 int len; 257 int len;
317 char *cp; 258 int allocated_len;
259 struct list_head *head;
318 260
319 if (!name) 261 if (!name)
320 return NULL; 262 return NULL;
321 len = strlen(name) + 1; 263 len = strlen(name) + 1;
322 if (len > TOMOYO_MAX_PATHNAME_LEN) {
323 printk(KERN_WARNING "ERROR: Name too long "
324 "for tomoyo_save_name().\n");
325 return NULL;
326 }
327 hash = full_name_hash((const unsigned char *) name, len - 1); 264 hash = full_name_hash((const unsigned char *) name, len - 1);
328 mutex_lock(&lock); 265 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
329 list_for_each_entry(ptr, &tomoyo_name_list[hash % TOMOYO_MAX_HASH], 266 mutex_lock(&tomoyo_name_list_lock);
330 list) { 267 list_for_each_entry(ptr, head, list) {
331 if (hash == ptr->entry.hash && !strcmp(name, ptr->entry.name)) 268 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
332 goto out; 269 continue;
333 } 270 atomic_inc(&ptr->users);
334 list_for_each_entry(fmb, &fmb_list, list) { 271 goto out;
335 if (len <= fmb->len)
336 goto ready;
337 } 272 }
338 if (!tomoyo_quota_for_savename || 273 ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL);
339 tomoyo_allocated_memory_for_savename + PATH_MAX 274 allocated_len = ptr ? ksize(ptr) : 0;
340 <= tomoyo_quota_for_savename) 275 if (!ptr || (tomoyo_quota_for_policy &&
341 cp = kzalloc(PATH_MAX, GFP_KERNEL); 276 atomic_read(&tomoyo_policy_memory_size) + allocated_len
342 else 277 > tomoyo_quota_for_policy)) {
343 cp = NULL; 278 kfree(ptr);
344 fmb = kzalloc(sizeof(*fmb), GFP_KERNEL);
345 if (!cp || !fmb) {
346 kfree(cp);
347 kfree(fmb);
348 printk(KERN_WARNING "ERROR: Out of memory " 279 printk(KERN_WARNING "ERROR: Out of memory "
349 "for tomoyo_save_name().\n"); 280 "for tomoyo_get_name().\n");
350 if (!tomoyo_policy_loaded) 281 if (!tomoyo_policy_loaded)
351 panic("MAC Initialization failed.\n"); 282 panic("MAC Initialization failed.\n");
352 ptr = NULL; 283 ptr = NULL;
353 goto out; 284 goto out;
354 } 285 }
355 tomoyo_allocated_memory_for_savename += PATH_MAX; 286 atomic_add(allocated_len, &tomoyo_policy_memory_size);
356 list_add(&fmb->list, &fmb_list); 287 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
357 fmb->ptr = cp; 288 memmove((char *) ptr->entry.name, name, len);
358 fmb->len = PATH_MAX; 289 atomic_set(&ptr->users, 1);
359 ready:
360 ptr = tomoyo_alloc_element(sizeof(*ptr));
361 if (!ptr)
362 goto out;
363 ptr->entry.name = fmb->ptr;
364 memmove(fmb->ptr, name, len);
365 tomoyo_fill_path_info(&ptr->entry); 290 tomoyo_fill_path_info(&ptr->entry);
366 fmb->ptr += len; 291 list_add_tail(&ptr->list, head);
367 fmb->len -= len;
368 list_add_tail(&ptr->list, &tomoyo_name_list[hash % TOMOYO_MAX_HASH]);
369 if (fmb->len == 0) {
370 list_del(&fmb->list);
371 kfree(fmb);
372 }
373 out: 292 out:
374 mutex_unlock(&lock); 293 mutex_unlock(&tomoyo_name_list_lock);
375 return ptr ? &ptr->entry : NULL; 294 return ptr ? &ptr->entry : NULL;
376} 295}
377 296
@@ -386,45 +305,14 @@ void __init tomoyo_realpath_init(void)
386 for (i = 0; i < TOMOYO_MAX_HASH; i++) 305 for (i = 0; i < TOMOYO_MAX_HASH; i++)
387 INIT_LIST_HEAD(&tomoyo_name_list[i]); 306 INIT_LIST_HEAD(&tomoyo_name_list[i]);
388 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list); 307 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list);
389 tomoyo_kernel_domain.domainname = tomoyo_save_name(TOMOYO_ROOT_NAME); 308 tomoyo_kernel_domain.domainname = tomoyo_get_name(TOMOYO_ROOT_NAME);
390 list_add_tail(&tomoyo_kernel_domain.list, &tomoyo_domain_list); 309 /*
391 down_read(&tomoyo_domain_list_lock); 310 * tomoyo_read_lock() is not needed because this function is
311 * called before the first "delete" request.
312 */
313 list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list);
392 if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain) 314 if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain)
393 panic("Can't register tomoyo_kernel_domain"); 315 panic("Can't register tomoyo_kernel_domain");
394 up_read(&tomoyo_domain_list_lock);
395}
396
397/* Memory allocated for temporary purpose. */
398static atomic_t tomoyo_dynamic_memory_size;
399
400/**
401 * tomoyo_alloc - Allocate memory for temporary purpose.
402 *
403 * @size: Size in bytes.
404 *
405 * Returns pointer to allocated memory on success, NULL otherwise.
406 */
407void *tomoyo_alloc(const size_t size)
408{
409 void *p = kzalloc(size, GFP_KERNEL);
410 if (p)
411 atomic_add(ksize(p), &tomoyo_dynamic_memory_size);
412 return p;
413}
414
415/**
416 * tomoyo_free - Release memory allocated by tomoyo_alloc().
417 *
418 * @p: Pointer returned by tomoyo_alloc(). May be NULL.
419 *
420 * Returns nothing.
421 */
422void tomoyo_free(const void *p)
423{
424 if (p) {
425 atomic_sub(ksize(p), &tomoyo_dynamic_memory_size);
426 kfree(p);
427 }
428} 316}
429 317
430/** 318/**
@@ -437,32 +325,19 @@ void tomoyo_free(const void *p)
437int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head) 325int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head)
438{ 326{
439 if (!head->read_eof) { 327 if (!head->read_eof) {
440 const unsigned int shared 328 const unsigned int policy
441 = tomoyo_allocated_memory_for_savename; 329 = atomic_read(&tomoyo_policy_memory_size);
442 const unsigned int private
443 = tomoyo_allocated_memory_for_elements;
444 const unsigned int dynamic
445 = atomic_read(&tomoyo_dynamic_memory_size);
446 char buffer[64]; 330 char buffer[64];
447 331
448 memset(buffer, 0, sizeof(buffer)); 332 memset(buffer, 0, sizeof(buffer));
449 if (tomoyo_quota_for_savename) 333 if (tomoyo_quota_for_policy)
450 snprintf(buffer, sizeof(buffer) - 1,
451 " (Quota: %10u)",
452 tomoyo_quota_for_savename);
453 else
454 buffer[0] = '\0';
455 tomoyo_io_printf(head, "Shared: %10u%s\n", shared, buffer);
456 if (tomoyo_quota_for_elements)
457 snprintf(buffer, sizeof(buffer) - 1, 334 snprintf(buffer, sizeof(buffer) - 1,
458 " (Quota: %10u)", 335 " (Quota: %10u)",
459 tomoyo_quota_for_elements); 336 tomoyo_quota_for_policy);
460 else 337 else
461 buffer[0] = '\0'; 338 buffer[0] = '\0';
462 tomoyo_io_printf(head, "Private: %10u%s\n", private, buffer); 339 tomoyo_io_printf(head, "Policy: %10u%s\n", policy, buffer);
463 tomoyo_io_printf(head, "Dynamic: %10u\n", dynamic); 340 tomoyo_io_printf(head, "Total: %10u\n", policy);
464 tomoyo_io_printf(head, "Total: %10u\n",
465 shared + private + dynamic);
466 head->read_eof = true; 341 head->read_eof = true;
467 } 342 }
468 return 0; 343 return 0;
@@ -480,9 +355,7 @@ int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head)
480 char *data = head->write_buf; 355 char *data = head->write_buf;
481 unsigned int size; 356 unsigned int size;
482 357
483 if (sscanf(data, "Shared: %u", &size) == 1) 358 if (sscanf(data, "Policy: %u", &size) == 1)
484 tomoyo_quota_for_savename = size; 359 tomoyo_quota_for_policy = size;
485 else if (sscanf(data, "Private: %u", &size) == 1)
486 tomoyo_quota_for_elements = size;
487 return 0; 360 return 0;
488} 361}
diff --git a/security/tomoyo/realpath.h b/security/tomoyo/realpath.h
deleted file mode 100644
index 78217a37960b..000000000000
--- a/security/tomoyo/realpath.h
+++ /dev/null
@@ -1,66 +0,0 @@
1/*
2 * security/tomoyo/realpath.h
3 *
4 * Get the canonicalized absolute pathnames. The basis for TOMOYO.
5 *
6 * Copyright (C) 2005-2009 NTT DATA CORPORATION
7 *
8 * Version: 2.2.0 2009/04/01
9 *
10 */
11
12#ifndef _SECURITY_TOMOYO_REALPATH_H
13#define _SECURITY_TOMOYO_REALPATH_H
14
15struct path;
16struct tomoyo_path_info;
17struct tomoyo_io_buffer;
18
19/* Convert binary string to ascii string. */
20int tomoyo_encode(char *buffer, int buflen, const char *str);
21
22/* Returns realpath(3) of the given pathname but ignores chroot'ed root. */
23int tomoyo_realpath_from_path2(struct path *path, char *newname,
24 int newname_len);
25
26/*
27 * Returns realpath(3) of the given pathname but ignores chroot'ed root.
28 * These functions use tomoyo_alloc(), so the caller must call tomoyo_free()
29 * if these functions didn't return NULL.
30 */
31char *tomoyo_realpath(const char *pathname);
32/*
33 * Same with tomoyo_realpath() except that it doesn't follow the final symlink.
34 */
35char *tomoyo_realpath_nofollow(const char *pathname);
36/* Same with tomoyo_realpath() except that the pathname is already solved. */
37char *tomoyo_realpath_from_path(struct path *path);
38
39/*
40 * Allocate memory for ACL entry.
41 * The RAM is chunked, so NEVER try to kfree() the returned pointer.
42 */
43void *tomoyo_alloc_element(const unsigned int size);
44
45/*
46 * Keep the given name on the RAM.
47 * The RAM is shared, so NEVER try to modify or kfree() the returned name.
48 */
49const struct tomoyo_path_info *tomoyo_save_name(const char *name);
50
51/* Allocate memory for temporary use (e.g. permission checks). */
52void *tomoyo_alloc(const size_t size);
53
54/* Free memory allocated by tomoyo_alloc(). */
55void tomoyo_free(const void *p);
56
57/* Check for memory usage. */
58int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head);
59
60/* Set memory quota. */
61int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head);
62
63/* Initialize realpath related code. */
64void __init tomoyo_realpath_init(void);
65
66#endif /* !defined(_SECURITY_TOMOYO_REALPATH_H) */
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index 9548a0984cc4..dedd97d0c163 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -11,8 +11,6 @@
11 11
12#include <linux/security.h> 12#include <linux/security.h>
13#include "common.h" 13#include "common.h"
14#include "tomoyo.h"
15#include "realpath.h"
16 14
17static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp) 15static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
18{ 16{
@@ -23,21 +21,23 @@ static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
23static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, 21static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
24 gfp_t gfp) 22 gfp_t gfp)
25{ 23{
26 /* 24 struct tomoyo_domain_info *domain = old->security;
27 * Since "struct tomoyo_domain_info *" is a sharable pointer, 25 new->security = domain;
28 * we don't need to duplicate. 26 if (domain)
29 */ 27 atomic_inc(&domain->users);
30 new->security = old->security;
31 return 0; 28 return 0;
32} 29}
33 30
34static void tomoyo_cred_transfer(struct cred *new, const struct cred *old) 31static void tomoyo_cred_transfer(struct cred *new, const struct cred *old)
35{ 32{
36 /* 33 tomoyo_cred_prepare(new, old, 0);
37 * Since "struct tomoyo_domain_info *" is a sharable pointer, 34}
38 * we don't need to duplicate. 35
39 */ 36static void tomoyo_cred_free(struct cred *cred)
40 new->security = old->security; 37{
38 struct tomoyo_domain_info *domain = cred->security;
39 if (domain)
40 atomic_dec(&domain->users);
41} 41}
42 42
43static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) 43static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
@@ -61,6 +61,14 @@ static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
61 if (!tomoyo_policy_loaded) 61 if (!tomoyo_policy_loaded)
62 tomoyo_load_policy(bprm->filename); 62 tomoyo_load_policy(bprm->filename);
63 /* 63 /*
64 * Release reference to "struct tomoyo_domain_info" stored inside
65 * "bprm->cred->security". New reference to "struct tomoyo_domain_info"
66 * stored inside "bprm->cred->security" will be acquired later inside
67 * tomoyo_find_next_domain().
68 */
69 atomic_dec(&((struct tomoyo_domain_info *)
70 bprm->cred->security)->users);
71 /*
64 * Tell tomoyo_bprm_check_security() is called for the first time of an 72 * Tell tomoyo_bprm_check_security() is called for the first time of an
65 * execve operation. 73 * execve operation.
66 */ 74 */
@@ -76,156 +84,71 @@ static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
76 * Execute permission is checked against pathname passed to do_execve() 84 * Execute permission is checked against pathname passed to do_execve()
77 * using current domain. 85 * using current domain.
78 */ 86 */
79 if (!domain) 87 if (!domain) {
80 return tomoyo_find_next_domain(bprm); 88 const int idx = tomoyo_read_lock();
89 const int err = tomoyo_find_next_domain(bprm);
90 tomoyo_read_unlock(idx);
91 return err;
92 }
81 /* 93 /*
82 * Read permission is checked against interpreters using next domain. 94 * Read permission is checked against interpreters using next domain.
83 * '1' is the result of open_to_namei_flags(O_RDONLY).
84 */ 95 */
85 return tomoyo_check_open_permission(domain, &bprm->file->f_path, 1); 96 return tomoyo_check_open_permission(domain, &bprm->file->f_path, O_RDONLY);
86}
87
88#ifdef CONFIG_SYSCTL
89
90static int tomoyo_prepend(char **buffer, int *buflen, const char *str)
91{
92 int namelen = strlen(str);
93
94 if (*buflen < namelen)
95 return -ENOMEM;
96 *buflen -= namelen;
97 *buffer -= namelen;
98 memcpy(*buffer, str, namelen);
99 return 0;
100}
101
102/**
103 * tomoyo_sysctl_path - return the realpath of a ctl_table.
104 * @table: pointer to "struct ctl_table".
105 *
106 * Returns realpath(3) of the @table on success.
107 * Returns NULL on failure.
108 *
109 * This function uses tomoyo_alloc(), so the caller must call tomoyo_free()
110 * if this function didn't return NULL.
111 */
112static char *tomoyo_sysctl_path(struct ctl_table *table)
113{
114 int buflen = TOMOYO_MAX_PATHNAME_LEN;
115 char *buf = tomoyo_alloc(buflen);
116 char *end = buf + buflen;
117 int error = -ENOMEM;
118
119 if (!buf)
120 return NULL;
121
122 *--end = '\0';
123 buflen--;
124 while (table) {
125 char num[32];
126 const char *sp = table->procname;
127
128 if (!sp) {
129 memset(num, 0, sizeof(num));
130 snprintf(num, sizeof(num) - 1, "=%d=", table->ctl_name);
131 sp = num;
132 }
133 if (tomoyo_prepend(&end, &buflen, sp) ||
134 tomoyo_prepend(&end, &buflen, "/"))
135 goto out;
136 table = table->parent;
137 }
138 if (tomoyo_prepend(&end, &buflen, "/proc/sys"))
139 goto out;
140 error = tomoyo_encode(buf, end - buf, end);
141 out:
142 if (!error)
143 return buf;
144 tomoyo_free(buf);
145 return NULL;
146}
147
148static int tomoyo_sysctl(struct ctl_table *table, int op)
149{
150 int error;
151 char *name;
152
153 op &= MAY_READ | MAY_WRITE;
154 if (!op)
155 return 0;
156 name = tomoyo_sysctl_path(table);
157 if (!name)
158 return -ENOMEM;
159 error = tomoyo_check_file_perm(tomoyo_domain(), name, op);
160 tomoyo_free(name);
161 return error;
162} 97}
163#endif
164 98
165static int tomoyo_path_truncate(struct path *path, loff_t length, 99static int tomoyo_path_truncate(struct path *path, loff_t length,
166 unsigned int time_attrs) 100 unsigned int time_attrs)
167{ 101{
168 return tomoyo_check_1path_perm(tomoyo_domain(), 102 return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path);
169 TOMOYO_TYPE_TRUNCATE_ACL,
170 path);
171} 103}
172 104
173static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry) 105static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry)
174{ 106{
175 struct path path = { parent->mnt, dentry }; 107 struct path path = { parent->mnt, dentry };
176 return tomoyo_check_1path_perm(tomoyo_domain(), 108 return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path);
177 TOMOYO_TYPE_UNLINK_ACL,
178 &path);
179} 109}
180 110
181static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry, 111static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry,
182 int mode) 112 int mode)
183{ 113{
184 struct path path = { parent->mnt, dentry }; 114 struct path path = { parent->mnt, dentry };
185 return tomoyo_check_1path_perm(tomoyo_domain(), 115 return tomoyo_path_perm(TOMOYO_TYPE_MKDIR, &path);
186 TOMOYO_TYPE_MKDIR_ACL,
187 &path);
188} 116}
189 117
190static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry) 118static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry)
191{ 119{
192 struct path path = { parent->mnt, dentry }; 120 struct path path = { parent->mnt, dentry };
193 return tomoyo_check_1path_perm(tomoyo_domain(), 121 return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path);
194 TOMOYO_TYPE_RMDIR_ACL,
195 &path);
196} 122}
197 123
198static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry, 124static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry,
199 const char *old_name) 125 const char *old_name)
200{ 126{
201 struct path path = { parent->mnt, dentry }; 127 struct path path = { parent->mnt, dentry };
202 return tomoyo_check_1path_perm(tomoyo_domain(), 128 return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path);
203 TOMOYO_TYPE_SYMLINK_ACL,
204 &path);
205} 129}
206 130
207static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry, 131static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry,
208 int mode, unsigned int dev) 132 int mode, unsigned int dev)
209{ 133{
210 struct path path = { parent->mnt, dentry }; 134 struct path path = { parent->mnt, dentry };
211 int type = TOMOYO_TYPE_CREATE_ACL; 135 int type = TOMOYO_TYPE_CREATE;
212 136
213 switch (mode & S_IFMT) { 137 switch (mode & S_IFMT) {
214 case S_IFCHR: 138 case S_IFCHR:
215 type = TOMOYO_TYPE_MKCHAR_ACL; 139 type = TOMOYO_TYPE_MKCHAR;
216 break; 140 break;
217 case S_IFBLK: 141 case S_IFBLK:
218 type = TOMOYO_TYPE_MKBLOCK_ACL; 142 type = TOMOYO_TYPE_MKBLOCK;
219 break; 143 break;
220 case S_IFIFO: 144 case S_IFIFO:
221 type = TOMOYO_TYPE_MKFIFO_ACL; 145 type = TOMOYO_TYPE_MKFIFO;
222 break; 146 break;
223 case S_IFSOCK: 147 case S_IFSOCK:
224 type = TOMOYO_TYPE_MKSOCK_ACL; 148 type = TOMOYO_TYPE_MKSOCK;
225 break; 149 break;
226 } 150 }
227 return tomoyo_check_1path_perm(tomoyo_domain(), 151 return tomoyo_path_perm(type, &path);
228 type, &path);
229} 152}
230 153
231static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir, 154static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir,
@@ -233,9 +156,7 @@ static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir,
233{ 156{
234 struct path path1 = { new_dir->mnt, old_dentry }; 157 struct path path1 = { new_dir->mnt, old_dentry };
235 struct path path2 = { new_dir->mnt, new_dentry }; 158 struct path path2 = { new_dir->mnt, new_dentry };
236 return tomoyo_check_2path_perm(tomoyo_domain(), 159 return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2);
237 TOMOYO_TYPE_LINK_ACL,
238 &path1, &path2);
239} 160}
240 161
241static int tomoyo_path_rename(struct path *old_parent, 162static int tomoyo_path_rename(struct path *old_parent,
@@ -245,32 +166,71 @@ static int tomoyo_path_rename(struct path *old_parent,
245{ 166{
246 struct path path1 = { old_parent->mnt, old_dentry }; 167 struct path path1 = { old_parent->mnt, old_dentry };
247 struct path path2 = { new_parent->mnt, new_dentry }; 168 struct path path2 = { new_parent->mnt, new_dentry };
248 return tomoyo_check_2path_perm(tomoyo_domain(), 169 return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2);
249 TOMOYO_TYPE_RENAME_ACL,
250 &path1, &path2);
251} 170}
252 171
253static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, 172static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
254 unsigned long arg) 173 unsigned long arg)
255{ 174{
256 if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)) 175 if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND))
257 return tomoyo_check_rewrite_permission(tomoyo_domain(), file); 176 return tomoyo_check_rewrite_permission(file);
258 return 0; 177 return 0;
259} 178}
260 179
261static int tomoyo_dentry_open(struct file *f, const struct cred *cred) 180static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
262{ 181{
263 int flags = f->f_flags; 182 int flags = f->f_flags;
264
265 if ((flags + 1) & O_ACCMODE)
266 flags++;
267 flags |= f->f_flags & (O_APPEND | O_TRUNC);
268 /* Don't check read permission here if called from do_execve(). */ 183 /* Don't check read permission here if called from do_execve(). */
269 if (current->in_execve) 184 if (current->in_execve)
270 return 0; 185 return 0;
271 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags); 186 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags);
272} 187}
273 188
189static int tomoyo_file_ioctl(struct file *file, unsigned int cmd,
190 unsigned long arg)
191{
192 return tomoyo_path_perm(TOMOYO_TYPE_IOCTL, &file->f_path);
193}
194
195static int tomoyo_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
196 mode_t mode)
197{
198 struct path path = { mnt, dentry };
199 return tomoyo_path_perm(TOMOYO_TYPE_CHMOD, &path);
200}
201
202static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid)
203{
204 int error = 0;
205 if (uid != (uid_t) -1)
206 error = tomoyo_path_perm(TOMOYO_TYPE_CHOWN, path);
207 if (!error && gid != (gid_t) -1)
208 error = tomoyo_path_perm(TOMOYO_TYPE_CHGRP, path);
209 return error;
210}
211
212static int tomoyo_path_chroot(struct path *path)
213{
214 return tomoyo_path_perm(TOMOYO_TYPE_CHROOT, path);
215}
216
217static int tomoyo_sb_mount(char *dev_name, struct path *path,
218 char *type, unsigned long flags, void *data)
219{
220 return tomoyo_path_perm(TOMOYO_TYPE_MOUNT, path);
221}
222
223static int tomoyo_sb_umount(struct vfsmount *mnt, int flags)
224{
225 struct path path = { mnt, mnt->mnt_root };
226 return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path);
227}
228
229static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path)
230{
231 return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path);
232}
233
274/* 234/*
275 * tomoyo_security_ops is a "struct security_operations" which is used for 235 * tomoyo_security_ops is a "struct security_operations" which is used for
276 * registering TOMOYO. 236 * registering TOMOYO.
@@ -280,11 +240,9 @@ static struct security_operations tomoyo_security_ops = {
280 .cred_alloc_blank = tomoyo_cred_alloc_blank, 240 .cred_alloc_blank = tomoyo_cred_alloc_blank,
281 .cred_prepare = tomoyo_cred_prepare, 241 .cred_prepare = tomoyo_cred_prepare,
282 .cred_transfer = tomoyo_cred_transfer, 242 .cred_transfer = tomoyo_cred_transfer,
243 .cred_free = tomoyo_cred_free,
283 .bprm_set_creds = tomoyo_bprm_set_creds, 244 .bprm_set_creds = tomoyo_bprm_set_creds,
284 .bprm_check_security = tomoyo_bprm_check_security, 245 .bprm_check_security = tomoyo_bprm_check_security,
285#ifdef CONFIG_SYSCTL
286 .sysctl = tomoyo_sysctl,
287#endif
288 .file_fcntl = tomoyo_file_fcntl, 246 .file_fcntl = tomoyo_file_fcntl,
289 .dentry_open = tomoyo_dentry_open, 247 .dentry_open = tomoyo_dentry_open,
290 .path_truncate = tomoyo_path_truncate, 248 .path_truncate = tomoyo_path_truncate,
@@ -295,8 +253,18 @@ static struct security_operations tomoyo_security_ops = {
295 .path_mknod = tomoyo_path_mknod, 253 .path_mknod = tomoyo_path_mknod,
296 .path_link = tomoyo_path_link, 254 .path_link = tomoyo_path_link,
297 .path_rename = tomoyo_path_rename, 255 .path_rename = tomoyo_path_rename,
256 .file_ioctl = tomoyo_file_ioctl,
257 .path_chmod = tomoyo_path_chmod,
258 .path_chown = tomoyo_path_chown,
259 .path_chroot = tomoyo_path_chroot,
260 .sb_mount = tomoyo_sb_mount,
261 .sb_umount = tomoyo_sb_umount,
262 .sb_pivotroot = tomoyo_sb_pivotroot,
298}; 263};
299 264
265/* Lock for GC. */
266struct srcu_struct tomoyo_ss;
267
300static int __init tomoyo_init(void) 268static int __init tomoyo_init(void)
301{ 269{
302 struct cred *cred = (struct cred *) current_cred(); 270 struct cred *cred = (struct cred *) current_cred();
@@ -304,7 +272,8 @@ static int __init tomoyo_init(void)
304 if (!security_module_enable(&tomoyo_security_ops)) 272 if (!security_module_enable(&tomoyo_security_ops))
305 return 0; 273 return 0;
306 /* register ourselves with the security framework */ 274 /* register ourselves with the security framework */
307 if (register_security(&tomoyo_security_ops)) 275 if (register_security(&tomoyo_security_ops) ||
276 init_srcu_struct(&tomoyo_ss))
308 panic("Failure registering TOMOYO Linux"); 277 panic("Failure registering TOMOYO Linux");
309 printk(KERN_INFO "TOMOYO Linux initialized\n"); 278 printk(KERN_INFO "TOMOYO Linux initialized\n");
310 cred->security = &tomoyo_kernel_domain; 279 cred->security = &tomoyo_kernel_domain;
diff --git a/security/tomoyo/tomoyo.h b/security/tomoyo/tomoyo.h
deleted file mode 100644
index cd6ba0bf7069..000000000000
--- a/security/tomoyo/tomoyo.h
+++ /dev/null
@@ -1,96 +0,0 @@
1/*
2 * security/tomoyo/tomoyo.h
3 *
4 * Implementation of the Domain-Based Mandatory Access Control.
5 *
6 * Copyright (C) 2005-2009 NTT DATA CORPORATION
7 *
8 * Version: 2.2.0 2009/04/01
9 *
10 */
11
12#ifndef _SECURITY_TOMOYO_TOMOYO_H
13#define _SECURITY_TOMOYO_TOMOYO_H
14
15struct tomoyo_path_info;
16struct path;
17struct inode;
18struct linux_binprm;
19struct pt_regs;
20
21int tomoyo_check_file_perm(struct tomoyo_domain_info *domain,
22 const char *filename, const u8 perm);
23int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain,
24 const struct tomoyo_path_info *filename);
25int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
26 struct path *path, const int flag);
27int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain,
28 const u8 operation, struct path *path);
29int tomoyo_check_2path_perm(struct tomoyo_domain_info *domain,
30 const u8 operation, struct path *path1,
31 struct path *path2);
32int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain,
33 struct file *filp);
34int tomoyo_find_next_domain(struct linux_binprm *bprm);
35
36/* Index numbers for Access Controls. */
37
38#define TOMOYO_TYPE_SINGLE_PATH_ACL 0
39#define TOMOYO_TYPE_DOUBLE_PATH_ACL 1
40
41/* Index numbers for File Controls. */
42
43/*
44 * TYPE_READ_WRITE_ACL is special. TYPE_READ_WRITE_ACL is automatically set
45 * if both TYPE_READ_ACL and TYPE_WRITE_ACL are set. Both TYPE_READ_ACL and
46 * TYPE_WRITE_ACL are automatically set if TYPE_READ_WRITE_ACL is set.
47 * TYPE_READ_WRITE_ACL is automatically cleared if either TYPE_READ_ACL or
48 * TYPE_WRITE_ACL is cleared. Both TYPE_READ_ACL and TYPE_WRITE_ACL are
49 * automatically cleared if TYPE_READ_WRITE_ACL is cleared.
50 */
51
52#define TOMOYO_TYPE_READ_WRITE_ACL 0
53#define TOMOYO_TYPE_EXECUTE_ACL 1
54#define TOMOYO_TYPE_READ_ACL 2
55#define TOMOYO_TYPE_WRITE_ACL 3
56#define TOMOYO_TYPE_CREATE_ACL 4
57#define TOMOYO_TYPE_UNLINK_ACL 5
58#define TOMOYO_TYPE_MKDIR_ACL 6
59#define TOMOYO_TYPE_RMDIR_ACL 7
60#define TOMOYO_TYPE_MKFIFO_ACL 8
61#define TOMOYO_TYPE_MKSOCK_ACL 9
62#define TOMOYO_TYPE_MKBLOCK_ACL 10
63#define TOMOYO_TYPE_MKCHAR_ACL 11
64#define TOMOYO_TYPE_TRUNCATE_ACL 12
65#define TOMOYO_TYPE_SYMLINK_ACL 13
66#define TOMOYO_TYPE_REWRITE_ACL 14
67#define TOMOYO_MAX_SINGLE_PATH_OPERATION 15
68
69#define TOMOYO_TYPE_LINK_ACL 0
70#define TOMOYO_TYPE_RENAME_ACL 1
71#define TOMOYO_MAX_DOUBLE_PATH_OPERATION 2
72
73#define TOMOYO_DOMAINPOLICY 0
74#define TOMOYO_EXCEPTIONPOLICY 1
75#define TOMOYO_DOMAIN_STATUS 2
76#define TOMOYO_PROCESS_STATUS 3
77#define TOMOYO_MEMINFO 4
78#define TOMOYO_SELFDOMAIN 5
79#define TOMOYO_VERSION 6
80#define TOMOYO_PROFILE 7
81#define TOMOYO_MANAGER 8
82
83extern struct tomoyo_domain_info tomoyo_kernel_domain;
84
85static inline struct tomoyo_domain_info *tomoyo_domain(void)
86{
87 return current_cred()->security;
88}
89
90static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
91 *task)
92{
93 return task_cred_xxx(task, security);
94}
95
96#endif /* !defined(_SECURITY_TOMOYO_TOMOYO_H) */