aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/capability.c4
-rw-r--r--security/commoncap.c9
-rw-r--r--security/device_cgroup.c1
-rw-r--r--security/inode.c15
-rw-r--r--security/integrity/ima/ima.h3
-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.c13
-rw-r--r--security/integrity/ima/ima_init.c1
-rw-r--r--security/integrity/ima/ima_main.c240
-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/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/user_defined.c3
-rw-r--r--security/lsm_audit.c1
-rw-r--r--security/security.c51
-rw-r--r--security/selinux/avc.c28
-rw-r--r--security/selinux/hooks.c41
-rw-r--r--security/selinux/include/security.h13
-rw-r--r--security/selinux/netif.c1
-rw-r--r--security/selinux/netlabel.c1
-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.c12
-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.c48
-rw-r--r--security/selinux/ss/mls.h2
-rw-r--r--security/selinux/ss/mls_types.h7
-rw-r--r--security/selinux/ss/policydb.c127
-rw-r--r--security/selinux/ss/policydb.h10
-rw-r--r--security/selinux/ss/services.c273
-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.c7
-rw-r--r--security/smack/smackfs.c1
-rw-r--r--security/tomoyo/Makefile2
-rw-r--r--security/tomoyo/common.c376
-rw-r--r--security/tomoyo/common.h530
-rw-r--r--security/tomoyo/domain.c392
-rw-r--r--security/tomoyo/file.c732
-rw-r--r--security/tomoyo/gc.c371
-rw-r--r--security/tomoyo/realpath.c293
-rw-r--r--security/tomoyo/realpath.h66
-rw-r--r--security/tomoyo/tomoyo.c142
-rw-r--r--security/tomoyo/tomoyo.h94
55 files changed, 2132 insertions, 1896 deletions
diff --git a/security/capability.c b/security/capability.c
index 5c700e1a4fd..4875142b858 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -906,10 +906,6 @@ static void cap_audit_rule_free(void *lsmrule)
906} 906}
907#endif /* CONFIG_AUDIT */ 907#endif /* CONFIG_AUDIT */
908 908
909struct security_operations default_security_ops = {
910 .name = "default",
911};
912
913#define set_to_cap_if_null(ops, function) \ 909#define set_to_cap_if_null(ops, function) \
914 do { \ 910 do { \
915 if (!ops->function) { \ 911 if (!ops->function) { \
diff --git a/security/commoncap.c b/security/commoncap.c
index f800fdb3de9..61669730da9 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -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
@@ -888,13 +889,17 @@ error:
888/** 889/**
889 * cap_syslog - Determine whether syslog function is permitted 890 * cap_syslog - Determine whether syslog function is permitted
890 * @type: Function requested 891 * @type: Function requested
892 * @from_file: Whether this request came from an open file (i.e. /proc)
891 * 893 *
892 * Determine whether the current process is permitted to use a particular 894 * Determine whether the current process is permitted to use a particular
893 * syslog function, returning 0 if permission is granted, -ve if not. 895 * syslog function, returning 0 if permission is granted, -ve if not.
894 */ 896 */
895int cap_syslog(int type) 897int cap_syslog(int type, bool from_file)
896{ 898{
897 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))
898 return -EPERM; 903 return -EPERM;
899 return 0; 904 return 0;
900} 905}
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 6cf8fd2b79e..f77c6042399 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 f7496c6a022..1c812e87450 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/ima.h b/security/integrity/ima/ima.h
index c41afe6639a..47fb65d1fcb 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);
@@ -131,7 +130,7 @@ void iint_free(struct kref *kref);
131void iint_rcu_free(struct rcu_head *rcu); 130void iint_rcu_free(struct rcu_head *rcu);
132 131
133/* IMA policy related functions */ 132/* IMA policy related functions */
134enum ima_hooks { PATH_CHECK = 1, FILE_MMAP, BPRM_CHECK }; 133enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK };
135 134
136int 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);
137void 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 3cd58b60afd..52015d098fd 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 ff513ff737f..5af76340470 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 46642a19bc7..952e51373f5 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 0c72c9c3895..07cb9c338cc 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 fa592ff1ac1..2c744d48801 100644
--- a/security/integrity/ima/ima_iint.c
+++ b/security/integrity/ima/ima_iint.c
@@ -14,6 +14,7 @@
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>
@@ -52,9 +53,6 @@ int ima_inode_alloc(struct inode *inode)
52 struct ima_iint_cache *iint = NULL; 53 struct ima_iint_cache *iint = NULL;
53 int rc = 0; 54 int rc = 0;
54 55
55 if (!ima_initialized)
56 return 0;
57
58 iint = kmem_cache_alloc(iint_cache, GFP_NOFS); 56 iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
59 if (!iint) 57 if (!iint)
60 return -ENOMEM; 58 return -ENOMEM;
@@ -66,12 +64,11 @@ int ima_inode_alloc(struct inode *inode)
66 spin_lock(&ima_iint_lock); 64 spin_lock(&ima_iint_lock);
67 rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint); 65 rc = radix_tree_insert(&ima_iint_store, (unsigned long)inode, iint);
68 spin_unlock(&ima_iint_lock); 66 spin_unlock(&ima_iint_lock);
67 radix_tree_preload_end();
69out: 68out:
70 if (rc < 0) 69 if (rc < 0)
71 kmem_cache_free(iint_cache, iint); 70 kmem_cache_free(iint_cache, iint);
72 71
73 radix_tree_preload_end();
74
75 return rc; 72 return rc;
76} 73}
77 74
@@ -118,8 +115,6 @@ void ima_inode_free(struct inode *inode)
118{ 115{
119 struct ima_iint_cache *iint; 116 struct ima_iint_cache *iint;
120 117
121 if (!ima_initialized)
122 return;
123 spin_lock(&ima_iint_lock); 118 spin_lock(&ima_iint_lock);
124 iint = radix_tree_delete(&ima_iint_store, (unsigned long)inode); 119 iint = radix_tree_delete(&ima_iint_store, (unsigned long)inode);
125 spin_unlock(&ima_iint_lock); 120 spin_unlock(&ima_iint_lock);
@@ -141,9 +136,11 @@ static void init_once(void *foo)
141 kref_set(&iint->refcount, 1); 136 kref_set(&iint->refcount, 1);
142} 137}
143 138
144void __init ima_iintcache_init(void) 139static int __init ima_iintcache_init(void)
145{ 140{
146 iint_cache = 141 iint_cache =
147 kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0, 142 kmem_cache_create("iint_cache", sizeof(struct ima_iint_cache), 0,
148 SLAB_PANIC, init_once); 143 SLAB_PANIC, init_once);
144 return 0;
149} 145}
146security_initcall(ima_iintcache_init);
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index a40da7ae590..b1bcb702a27 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 a89f44d5e03..b2c89d9de2a 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -14,13 +14,14 @@
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
@@ -84,6 +85,36 @@ out:
84 return found; 85 return found;
85} 86}
86 87
88/* ima_read_write_check - reflect possible reading/writing errors in the PCR.
89 *
90 * When opening a file for read, if the file is already open for write,
91 * the file could change, resulting in a file measurement error.
92 *
93 * Opening a file for write, if the file is already open for read, results
94 * in a time of measure, time of use (ToMToU) error.
95 *
96 * In either case invalidate the PCR.
97 */
98enum iint_pcr_error { TOMTOU, OPEN_WRITERS };
99static void ima_read_write_check(enum iint_pcr_error error,
100 struct ima_iint_cache *iint,
101 struct inode *inode,
102 const unsigned char *filename)
103{
104 switch (error) {
105 case TOMTOU:
106 if (iint->readcount > 0)
107 ima_add_violation(inode, filename, "invalid_pcr",
108 "ToMToU");
109 break;
110 case OPEN_WRITERS:
111 if (iint->writecount > 0)
112 ima_add_violation(inode, filename, "invalid_pcr",
113 "open_writers");
114 break;
115 }
116}
117
87/* 118/*
88 * Update the counts given an fmode_t 119 * Update the counts given an fmode_t
89 */ 120 */
@@ -99,6 +130,47 @@ static void ima_inc_counts(struct ima_iint_cache *iint, fmode_t mode)
99} 130}
100 131
101/* 132/*
133 * ima_counts_get - increment file counts
134 *
135 * Maintain read/write counters for all files, but only
136 * invalidate the PCR for measured files:
137 * - Opening a file for write when already open for read,
138 * results in a time of measure, time of use (ToMToU) error.
139 * - Opening a file for read when already open for write,
140 * could result in a file measurement error.
141 *
142 */
143void ima_counts_get(struct file *file)
144{
145 struct dentry *dentry = file->f_path.dentry;
146 struct inode *inode = dentry->d_inode;
147 fmode_t mode = file->f_mode;
148 struct ima_iint_cache *iint;
149 int rc;
150
151 if (!ima_initialized || !S_ISREG(inode->i_mode))
152 return;
153 iint = ima_iint_find_get(inode);
154 if (!iint)
155 return;
156 mutex_lock(&iint->mutex);
157 rc = ima_must_measure(iint, inode, MAY_READ, FILE_CHECK);
158 if (rc < 0)
159 goto out;
160
161 if (mode & FMODE_WRITE) {
162 ima_read_write_check(TOMTOU, iint, inode, dentry->d_name.name);
163 goto out;
164 }
165 ima_read_write_check(OPEN_WRITERS, iint, inode, dentry->d_name.name);
166out:
167 ima_inc_counts(iint, file->f_mode);
168 mutex_unlock(&iint->mutex);
169
170 kref_put(&iint->refcount, iint_free);
171}
172
173/*
102 * Decrement ima counts 174 * Decrement ima counts
103 */ 175 */
104static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode, 176static void ima_dec_counts(struct ima_iint_cache *iint, struct inode *inode,
@@ -153,123 +225,6 @@ void ima_file_free(struct file *file)
153 kref_put(&iint->refcount, iint_free); 225 kref_put(&iint->refcount, iint_free);
154} 226}
155 227
156/* ima_read_write_check - reflect possible reading/writing errors in the PCR.
157 *
158 * When opening a file for read, if the file is already open for write,
159 * the file could change, resulting in a file measurement error.
160 *
161 * Opening a file for write, if the file is already open for read, results
162 * in a time of measure, time of use (ToMToU) error.
163 *
164 * In either case invalidate the PCR.
165 */
166enum iint_pcr_error { TOMTOU, OPEN_WRITERS };
167static void ima_read_write_check(enum iint_pcr_error error,
168 struct ima_iint_cache *iint,
169 struct inode *inode,
170 const unsigned char *filename)
171{
172 switch (error) {
173 case TOMTOU:
174 if (iint->readcount > 0)
175 ima_add_violation(inode, filename, "invalid_pcr",
176 "ToMToU");
177 break;
178 case OPEN_WRITERS:
179 if (iint->writecount > 0)
180 ima_add_violation(inode, filename, "invalid_pcr",
181 "open_writers");
182 break;
183 }
184}
185
186static int get_path_measurement(struct ima_iint_cache *iint, struct file *file,
187 const unsigned char *filename)
188{
189 int rc = 0;
190
191 ima_inc_counts(iint, file->f_mode);
192
193 rc = ima_collect_measurement(iint, file);
194 if (!rc)
195 ima_store_measurement(iint, file, filename);
196 return rc;
197}
198
199/**
200 * ima_path_check - based on policy, collect/store measurement.
201 * @path: contains a pointer to the path to be measured
202 * @mask: contains MAY_READ, MAY_WRITE or MAY_EXECUTE
203 *
204 * Measure the file being open for readonly, based on the
205 * ima_must_measure() policy decision.
206 *
207 * Keep read/write counters for all files, but only
208 * invalidate the PCR for measured files:
209 * - Opening a file for write when already open for read,
210 * results in a time of measure, time of use (ToMToU) error.
211 * - Opening a file for read when already open for write,
212 * could result in a file measurement error.
213 *
214 * Always return 0 and audit dentry_open failures.
215 * (Return code will be based upon measurement appraisal.)
216 */
217int ima_path_check(struct path *path, int mask)
218{
219 struct inode *inode = path->dentry->d_inode;
220 struct ima_iint_cache *iint;
221 struct file *file = NULL;
222 int rc;
223
224 if (!ima_initialized || !S_ISREG(inode->i_mode))
225 return 0;
226 iint = ima_iint_find_get(inode);
227 if (!iint)
228 return 0;
229
230 mutex_lock(&iint->mutex);
231
232 rc = ima_must_measure(iint, inode, MAY_READ, PATH_CHECK);
233 if (rc < 0)
234 goto out;
235
236 if ((mask & MAY_WRITE) || (mask == 0))
237 ima_read_write_check(TOMTOU, iint, inode,
238 path->dentry->d_name.name);
239
240 if ((mask & (MAY_WRITE | MAY_READ | MAY_EXEC)) != MAY_READ)
241 goto out;
242
243 ima_read_write_check(OPEN_WRITERS, iint, inode,
244 path->dentry->d_name.name);
245 if (!(iint->flags & IMA_MEASURED)) {
246 struct dentry *dentry = dget(path->dentry);
247 struct vfsmount *mnt = mntget(path->mnt);
248
249 file = dentry_open(dentry, mnt, O_RDONLY | O_LARGEFILE,
250 current_cred());
251 if (IS_ERR(file)) {
252 int audit_info = 0;
253
254 integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode,
255 dentry->d_name.name,
256 "add_measurement",
257 "dentry_open failed",
258 1, audit_info);
259 file = NULL;
260 goto out;
261 }
262 rc = get_path_measurement(iint, file, dentry->d_name.name);
263 }
264out:
265 mutex_unlock(&iint->mutex);
266 if (file)
267 fput(file);
268 kref_put(&iint->refcount, iint_free);
269 return 0;
270}
271EXPORT_SYMBOL_GPL(ima_path_check);
272
273static int process_measurement(struct file *file, const unsigned char *filename, 228static int process_measurement(struct file *file, const unsigned char *filename,
274 int mask, int function) 229 int mask, int function)
275{ 230{
@@ -297,33 +252,6 @@ out:
297 return rc; 252 return rc;
298} 253}
299 254
300/*
301 * ima_counts_get - increment file counts
302 *
303 * - for IPC shm and shmat file.
304 * - for nfsd exported files.
305 *
306 * Increment the counts for these files to prevent unnecessary
307 * imbalance messages.
308 */
309void ima_counts_get(struct file *file)
310{
311 struct inode *inode = file->f_dentry->d_inode;
312 struct ima_iint_cache *iint;
313
314 if (!ima_initialized || !S_ISREG(inode->i_mode))
315 return;
316 iint = ima_iint_find_get(inode);
317 if (!iint)
318 return;
319 mutex_lock(&iint->mutex);
320 ima_inc_counts(iint, file->f_mode);
321 mutex_unlock(&iint->mutex);
322
323 kref_put(&iint->refcount, iint_free);
324}
325EXPORT_SYMBOL_GPL(ima_counts_get);
326
327/** 255/**
328 * ima_file_mmap - based on policy, collect/store measurement. 256 * ima_file_mmap - based on policy, collect/store measurement.
329 * @file: pointer to the file to be measured (May be NULL) 257 * @file: pointer to the file to be measured (May be NULL)
@@ -369,11 +297,31 @@ int ima_bprm_check(struct linux_binprm *bprm)
369 return 0; 297 return 0;
370} 298}
371 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
372static int __init init_ima(void) 321static int __init init_ima(void)
373{ 322{
374 int error; 323 int error;
375 324
376 ima_iintcache_init();
377 error = ima_init(); 325 error = ima_init();
378 ima_initialized = 1; 326 ima_initialized = 1;
379 return error; 327 return error;
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index e1278399b34..8643a93c596 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 a0880e9c8e0..46ba62b1adf 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 4770be375ff..a46e825cbf0 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/keyring.c b/security/keys/keyring.c
index 8ec02746ca9..1e4b0037935 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 9d01021ca0c..706d63f4f18 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 5c23afb31ec..06c2ccf26ed 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 03fe63ed55b..d8c1a6a0fb0 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/user_defined.c b/security/keys/user_defined.c
index 7c687d56822..e9aa0792965 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 acba3dfc8d2..893365b79a2 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>
diff --git a/security/security.c b/security/security.c
index 24e060be9fa..687c6fd14bb 100644
--- a/security/security.c
+++ b/security/security.c
@@ -23,10 +23,12 @@ static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
23 CONFIG_DEFAULT_SECURITY; 23 CONFIG_DEFAULT_SECURITY;
24 24
25/* things that live in capability.c */ 25/* things that live in capability.c */
26extern struct security_operations default_security_ops;
27extern void security_fixup_ops(struct security_operations *ops); 26extern void security_fixup_ops(struct security_operations *ops);
28 27
29struct security_operations *security_ops; /* Initialized to NULL */ 28static struct security_operations *security_ops;
29static struct security_operations default_security_ops = {
30 .name = "default",
31};
30 32
31static inline int verify(struct security_operations *ops) 33static inline int verify(struct security_operations *ops)
32{ 34{
@@ -63,6 +65,11 @@ int __init security_init(void)
63 return 0; 65 return 0;
64} 66}
65 67
68void reset_security_ops(void)
69{
70 security_ops = &default_security_ops;
71}
72
66/* Save user chosen LSM */ 73/* Save user chosen LSM */
67static int __init choose_lsm(char *str) 74static int __init choose_lsm(char *str)
68{ 75{
@@ -203,9 +210,9 @@ int security_quota_on(struct dentry *dentry)
203 return security_ops->quota_on(dentry); 210 return security_ops->quota_on(dentry);
204} 211}
205 212
206int security_syslog(int type) 213int security_syslog(int type, bool from_file)
207{ 214{
208 return security_ops->syslog(type); 215 return security_ops->syslog(type, from_file);
209} 216}
210 217
211int security_settime(struct timespec *ts, struct timezone *tz) 218int security_settime(struct timespec *ts, struct timezone *tz)
@@ -389,42 +396,42 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
389EXPORT_SYMBOL(security_inode_init_security); 396EXPORT_SYMBOL(security_inode_init_security);
390 397
391#ifdef CONFIG_SECURITY_PATH 398#ifdef CONFIG_SECURITY_PATH
392int security_path_mknod(struct path *path, struct dentry *dentry, int mode, 399int security_path_mknod(struct path *dir, struct dentry *dentry, int mode,
393 unsigned int dev) 400 unsigned int dev)
394{ 401{
395 if (unlikely(IS_PRIVATE(path->dentry->d_inode))) 402 if (unlikely(IS_PRIVATE(dir->dentry->d_inode)))
396 return 0; 403 return 0;
397 return security_ops->path_mknod(path, dentry, mode, dev); 404 return security_ops->path_mknod(dir, dentry, mode, dev);
398} 405}
399EXPORT_SYMBOL(security_path_mknod); 406EXPORT_SYMBOL(security_path_mknod);
400 407
401int security_path_mkdir(struct path *path, struct dentry *dentry, int mode) 408int security_path_mkdir(struct path *dir, struct dentry *dentry, int mode)
402{ 409{
403 if (unlikely(IS_PRIVATE(path->dentry->d_inode))) 410 if (unlikely(IS_PRIVATE(dir->dentry->d_inode)))
404 return 0; 411 return 0;
405 return security_ops->path_mkdir(path, dentry, mode); 412 return security_ops->path_mkdir(dir, dentry, mode);
406} 413}
407 414
408int security_path_rmdir(struct path *path, struct dentry *dentry) 415int security_path_rmdir(struct path *dir, struct dentry *dentry)
409{ 416{
410 if (unlikely(IS_PRIVATE(path->dentry->d_inode))) 417 if (unlikely(IS_PRIVATE(dir->dentry->d_inode)))
411 return 0; 418 return 0;
412 return security_ops->path_rmdir(path, dentry); 419 return security_ops->path_rmdir(dir, dentry);
413} 420}
414 421
415int security_path_unlink(struct path *path, struct dentry *dentry) 422int security_path_unlink(struct path *dir, struct dentry *dentry)
416{ 423{
417 if (unlikely(IS_PRIVATE(path->dentry->d_inode))) 424 if (unlikely(IS_PRIVATE(dir->dentry->d_inode)))
418 return 0; 425 return 0;
419 return security_ops->path_unlink(path, dentry); 426 return security_ops->path_unlink(dir, dentry);
420} 427}
421 428
422int security_path_symlink(struct path *path, struct dentry *dentry, 429int security_path_symlink(struct path *dir, struct dentry *dentry,
423 const char *old_name) 430 const char *old_name)
424{ 431{
425 if (unlikely(IS_PRIVATE(path->dentry->d_inode))) 432 if (unlikely(IS_PRIVATE(dir->dentry->d_inode)))
426 return 0; 433 return 0;
427 return security_ops->path_symlink(path, dentry, old_name); 434 return security_ops->path_symlink(dir, dentry, old_name);
428} 435}
429 436
430int security_path_link(struct dentry *old_dentry, struct path *new_dir, 437int security_path_link(struct dentry *old_dentry, struct path *new_dir,
@@ -630,14 +637,14 @@ int security_inode_killpriv(struct dentry *dentry)
630int 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)
631{ 638{
632 if (unlikely(IS_PRIVATE(inode))) 639 if (unlikely(IS_PRIVATE(inode)))
633 return 0; 640 return -EOPNOTSUPP;
634 return security_ops->inode_getsecurity(inode, name, buffer, alloc); 641 return security_ops->inode_getsecurity(inode, name, buffer, alloc);
635} 642}
636 643
637int 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)
638{ 645{
639 if (unlikely(IS_PRIVATE(inode))) 646 if (unlikely(IS_PRIVATE(inode)))
640 return 0; 647 return -EOPNOTSUPP;
641 return security_ops->inode_setsecurity(inode, name, value, size, flags); 648 return security_ops->inode_setsecurity(inode, name, value, size, flags);
642} 649}
643 650
@@ -666,8 +673,6 @@ int security_file_alloc(struct file *file)
666void security_file_free(struct file *file) 673void security_file_free(struct file *file)
667{ 674{
668 security_ops->file_free_security(file); 675 security_ops->file_free_security(file);
669 if (file->f_dentry)
670 ima_file_free(file);
671} 676}
672 677
673int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 678int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index f2dde268165..989fef82563 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -337,7 +337,7 @@ static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass)
337 * Look up an AVC entry that is valid for the 337 * Look up an AVC entry that is valid for the
338 * (@ssid, @tsid), interpreting the permissions 338 * (@ssid, @tsid), interpreting the permissions
339 * based on @tclass. If a valid AVC entry exists, 339 * based on @tclass. If a valid AVC entry exists,
340 * then this function return the avc_node. 340 * then this function returns the avc_node.
341 * Otherwise, this function returns NULL. 341 * Otherwise, this function returns NULL.
342 */ 342 */
343static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass) 343static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass)
@@ -489,17 +489,14 @@ void avc_audit(u32 ssid, u32 tsid,
489 struct common_audit_data stack_data; 489 struct common_audit_data stack_data;
490 u32 denied, audited; 490 u32 denied, audited;
491 denied = requested & ~avd->allowed; 491 denied = requested & ~avd->allowed;
492 if (denied) { 492 if (denied)
493 audited = denied; 493 audited = denied & avd->auditdeny;
494 if (!(audited & avd->auditdeny)) 494 else if (result)
495 return;
496 } else if (result) {
497 audited = denied = requested; 495 audited = denied = requested;
498 } else { 496 else
499 audited = requested; 497 audited = requested & avd->auditallow;
500 if (!(audited & avd->auditallow)) 498 if (!audited)
501 return; 499 return;
502 }
503 if (!a) { 500 if (!a) {
504 a = &stack_data; 501 a = &stack_data;
505 memset(a, 0, sizeof(*a)); 502 memset(a, 0, sizeof(*a));
@@ -526,7 +523,7 @@ void avc_audit(u32 ssid, u32 tsid,
526 * @perms: permissions 523 * @perms: permissions
527 * 524 *
528 * Register a callback function for events in the set @events 525 * Register a callback function for events in the set @events
529 * related to the SID pair (@ssid, @tsid) and 526 * related to the SID pair (@ssid, @tsid)
530 * and the permissions @perms, interpreting 527 * and the permissions @perms, interpreting
531 * @perms based on @tclass. Returns %0 on success or 528 * @perms based on @tclass. Returns %0 on success or
532 * -%ENOMEM if insufficient memory exists to add the callback. 529 * -%ENOMEM if insufficient memory exists to add the callback.
@@ -571,7 +568,7 @@ static inline int avc_sidcmp(u32 x, u32 y)
571 * 568 *
572 * 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.
573 * if kmalloc() called internal returns NULL, this function returns -ENOMEM. 570 * if kmalloc() called internal returns NULL, this function returns -ENOMEM.
574 * 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
575 * will release later by RCU. 572 * will release later by RCU.
576 */ 573 */
577static 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,
@@ -746,9 +743,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
746 else 743 else
747 avd = &avd_entry; 744 avd = &avd_entry;
748 745
749 rc = security_compute_av(ssid, tsid, tclass, requested, avd); 746 security_compute_av(ssid, tsid, tclass, avd);
750 if (rc)
751 goto out;
752 rcu_read_lock(); 747 rcu_read_lock();
753 node = avc_insert(ssid, tsid, tclass, avd); 748 node = avc_insert(ssid, tsid, tclass, avd);
754 } else { 749 } else {
@@ -770,7 +765,6 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
770 } 765 }
771 766
772 rcu_read_unlock(); 767 rcu_read_unlock();
773out:
774 return rc; 768 return rc;
775} 769}
776 770
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9a2ee845e9d..5feecb41009 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -76,6 +76,7 @@
76#include <linux/selinux.h> 76#include <linux/selinux.h>
77#include <linux/mutex.h> 77#include <linux/mutex.h>
78#include <linux/posix-timers.h> 78#include <linux/posix-timers.h>
79#include <linux/syslog.h>
79 80
80#include "avc.h" 81#include "avc.h"
81#include "objsec.h" 82#include "objsec.h"
@@ -125,13 +126,6 @@ __setup("selinux=", selinux_enabled_setup);
125int selinux_enabled = 1; 126int selinux_enabled = 1;
126#endif 127#endif
127 128
128
129/*
130 * Minimal support for a secondary security module,
131 * just to allow the use of the capability module.
132 */
133static struct security_operations *secondary_ops;
134
135/* Lists of inode and superblock security structures initialized 129/* Lists of inode and superblock security structures initialized
136 before the policy was loaded. */ 130 before the policy was loaded. */
137static LIST_HEAD(superblock_security_head); 131static LIST_HEAD(superblock_security_head);
@@ -2049,29 +2043,30 @@ static int selinux_quota_on(struct dentry *dentry)
2049 return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON); 2043 return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON);
2050} 2044}
2051 2045
2052static int selinux_syslog(int type) 2046static int selinux_syslog(int type, bool from_file)
2053{ 2047{
2054 int rc; 2048 int rc;
2055 2049
2056 rc = cap_syslog(type); 2050 rc = cap_syslog(type, from_file);
2057 if (rc) 2051 if (rc)
2058 return rc; 2052 return rc;
2059 2053
2060 switch (type) { 2054 switch (type) {
2061 case 3: /* Read last kernel messages */ 2055 case SYSLOG_ACTION_READ_ALL: /* Read last kernel messages */
2062 case 10: /* Return size of the log buffer */ 2056 case SYSLOG_ACTION_SIZE_BUFFER: /* Return size of the log buffer */
2063 rc = task_has_system(current, SYSTEM__SYSLOG_READ); 2057 rc = task_has_system(current, SYSTEM__SYSLOG_READ);
2064 break; 2058 break;
2065 case 6: /* Disable logging to console */ 2059 case SYSLOG_ACTION_CONSOLE_OFF: /* Disable logging to console */
2066 case 7: /* Enable logging to console */ 2060 case SYSLOG_ACTION_CONSOLE_ON: /* Enable logging to console */
2067 case 8: /* Set level of messages printed to console */ 2061 /* Set level of messages printed to console */
2062 case SYSLOG_ACTION_CONSOLE_LEVEL:
2068 rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE); 2063 rc = task_has_system(current, SYSTEM__SYSLOG_CONSOLE);
2069 break; 2064 break;
2070 case 0: /* Close log */ 2065 case SYSLOG_ACTION_CLOSE: /* Close log */
2071 case 1: /* Open log */ 2066 case SYSLOG_ACTION_OPEN: /* Open log */
2072 case 2: /* Read from log */ 2067 case SYSLOG_ACTION_READ: /* Read from log */
2073 case 4: /* Read/clear last kernel messages */ 2068 case SYSLOG_ACTION_READ_CLEAR: /* Read/clear last kernel messages */
2074 case 5: /* Clear ring buffer */ 2069 case SYSLOG_ACTION_CLEAR: /* Clear ring buffer */
2075 default: 2070 default:
2076 rc = task_has_system(current, SYSTEM__SYSLOG_MOD); 2071 rc = task_has_system(current, SYSTEM__SYSLOG_MOD);
2077 break; 2072 break;
@@ -3334,7 +3329,7 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
3334 3329
3335 if (ret == 0) 3330 if (ret == 0)
3336 tsec->create_sid = isec->sid; 3331 tsec->create_sid = isec->sid;
3337 return 0; 3332 return ret;
3338} 3333}
3339 3334
3340static int selinux_kernel_module_request(char *kmod_name) 3335static int selinux_kernel_module_request(char *kmod_name)
@@ -5672,9 +5667,6 @@ static __init int selinux_init(void)
5672 0, SLAB_PANIC, NULL); 5667 0, SLAB_PANIC, NULL);
5673 avc_init(); 5668 avc_init();
5674 5669
5675 secondary_ops = security_ops;
5676 if (!secondary_ops)
5677 panic("SELinux: No initial security operations\n");
5678 if (register_security(&selinux_ops)) 5670 if (register_security(&selinux_ops))
5679 panic("SELinux: Unable to register with kernel.\n"); 5671 panic("SELinux: Unable to register with kernel.\n");
5680 5672
@@ -5835,8 +5827,7 @@ int selinux_disable(void)
5835 selinux_disabled = 1; 5827 selinux_disabled = 1;
5836 selinux_enabled = 0; 5828 selinux_enabled = 0;
5837 5829
5838 /* Reset security_ops to the secondary module, dummy or capability. */ 5830 reset_security_ops();
5839 security_ops = secondary_ops;
5840 5831
5841 /* Try to destroy the avc node cache */ 5832 /* Try to destroy the avc node cache */
5842 avc_disable(); 5833 avc_disable();
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 2553266ad79..1f7c2491d3d 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -57,7 +57,6 @@
57struct netlbl_lsm_secattr; 57struct netlbl_lsm_secattr;
58 58
59extern int selinux_enabled; 59extern int selinux_enabled;
60extern int selinux_mls_enabled;
61 60
62/* Policy capabilities */ 61/* Policy capabilities */
63enum { 62enum {
@@ -80,6 +79,8 @@ extern int selinux_policycap_openperm;
80/* limitation of boundary depth */ 79/* limitation of boundary depth */
81#define POLICYDB_BOUNDS_MAXDEPTH 4 80#define POLICYDB_BOUNDS_MAXDEPTH 4
82 81
82int security_mls_enabled(void);
83
83int security_load_policy(void *data, size_t len); 84int security_load_policy(void *data, size_t len);
84 85
85int security_policycap_supported(unsigned int req_cap); 86int security_policycap_supported(unsigned int req_cap);
@@ -96,13 +97,11 @@ struct av_decision {
96/* definitions of av_decision.flags */ 97/* definitions of av_decision.flags */
97#define AVD_FLAGS_PERMISSIVE 0x0001 98#define AVD_FLAGS_PERMISSIVE 0x0001
98 99
99int security_compute_av(u32 ssid, u32 tsid, 100void security_compute_av(u32 ssid, u32 tsid,
100 u16 tclass, u32 requested, 101 u16 tclass, struct av_decision *avd);
101 struct av_decision *avd);
102 102
103int security_compute_av_user(u32 ssid, u32 tsid, 103void security_compute_av_user(u32 ssid, u32 tsid,
104 u16 tclass, u32 requested, 104 u16 tclass, struct av_decision *avd);
105 struct av_decision *avd);
106 105
107int security_transition_sid(u32 ssid, u32 tsid, 106int security_transition_sid(u32 ssid, u32 tsid,
108 u16 tclass, u32 *out_sid); 107 u16 tclass, u32 *out_sid);
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index b4e14bc0bf3..d6095d63d83 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 2534400317c..628da72ee76 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>
diff --git a/security/selinux/netlink.c b/security/selinux/netlink.c
index 1ae556446e6..0e147b6914a 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 7100072bb1b..dc92792271f 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 fe7fba67f19..cfe2d72d3fb 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 fab36fdf276..cd191bbec03 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_user(ssid, tsid, tclass, req, &avd); 525 security_compute_av_user(ssid, tsid, tclass, &avd);
526 if (length < 0)
527 goto out2;
528 526
529 length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, 527 length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT,
530 "%x %x %x %x %u %x", 528 "%x %x %x %x %u %x",
@@ -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/avtab.h b/security/selinux/ss/avtab.h
index 8da6a842808..cd4f734e274 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 d9dd7a2f6a8..45e8fb0515f 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 68c7348d1ac..04b6145d767 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 3f2b2706b5b..372b773f821 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,23 +513,21 @@ int mls_compute_sid(struct context *scontext,
513 u32 specified, 513 u32 specified,
514 struct context *newcontext) 514 struct context *newcontext)
515{ 515{
516 struct range_trans *rtr; 516 struct range_trans rtr;
517 struct mls_range *r;
517 518
518 if (!selinux_mls_enabled) 519 if (!policydb.mls_enabled)
519 return 0; 520 return 0;
520 521
521 switch (specified) { 522 switch (specified) {
522 case AVTAB_TRANSITION: 523 case AVTAB_TRANSITION:
523 /* Look for a range transition rule. */ 524 /* Look for a range transition rule. */
524 for (rtr = policydb.range_tr; rtr; rtr = rtr->next) { 525 rtr.source_type = scontext->type;
525 if (rtr->source_type == scontext->type && 526 rtr.target_type = tcontext->type;
526 rtr->target_type == tcontext->type && 527 rtr.target_class = tclass;
527 rtr->target_class == tclass) { 528 r = hashtab_search(policydb.range_tr, &rtr);
528 /* Set the range from the rule */ 529 if (r)
529 return mls_range_set(newcontext, 530 return mls_range_set(newcontext, r);
530 &rtr->target_range);
531 }
532 }
533 /* Fallthrough */ 531 /* Fallthrough */
534 case AVTAB_CHANGE: 532 case AVTAB_CHANGE:
535 if (tclass == policydb.process_class) 533 if (tclass == policydb.process_class)
@@ -541,8 +539,8 @@ int mls_compute_sid(struct context *scontext,
541 case AVTAB_MEMBER: 539 case AVTAB_MEMBER:
542 /* Use the process effective MLS attributes. */ 540 /* Use the process effective MLS attributes. */
543 return mls_context_cpy_low(newcontext, scontext); 541 return mls_context_cpy_low(newcontext, scontext);
544 default: 542
545 return -EINVAL; 543 /* fall through */
546 } 544 }
547 return -EINVAL; 545 return -EINVAL;
548} 546}
@@ -561,7 +559,7 @@ int mls_compute_sid(struct context *scontext,
561void mls_export_netlbl_lvl(struct context *context, 559void mls_export_netlbl_lvl(struct context *context,
562 struct netlbl_lsm_secattr *secattr) 560 struct netlbl_lsm_secattr *secattr)
563{ 561{
564 if (!selinux_mls_enabled) 562 if (!policydb.mls_enabled)
565 return; 563 return;
566 564
567 secattr->attr.mls.lvl = context->range.level[0].sens - 1; 565 secattr->attr.mls.lvl = context->range.level[0].sens - 1;
@@ -581,7 +579,7 @@ void mls_export_netlbl_lvl(struct context *context,
581void mls_import_netlbl_lvl(struct context *context, 579void mls_import_netlbl_lvl(struct context *context,
582 struct netlbl_lsm_secattr *secattr) 580 struct netlbl_lsm_secattr *secattr)
583{ 581{
584 if (!selinux_mls_enabled) 582 if (!policydb.mls_enabled)
585 return; 583 return;
586 584
587 context->range.level[0].sens = secattr->attr.mls.lvl + 1; 585 context->range.level[0].sens = secattr->attr.mls.lvl + 1;
@@ -603,7 +601,7 @@ int mls_export_netlbl_cat(struct context *context,
603{ 601{
604 int rc; 602 int rc;
605 603
606 if (!selinux_mls_enabled) 604 if (!policydb.mls_enabled)
607 return 0; 605 return 0;
608 606
609 rc = ebitmap_netlbl_export(&context->range.level[0].cat, 607 rc = ebitmap_netlbl_export(&context->range.level[0].cat,
@@ -631,7 +629,7 @@ int mls_import_netlbl_cat(struct context *context,
631{ 629{
632 int rc; 630 int rc;
633 631
634 if (!selinux_mls_enabled) 632 if (!policydb.mls_enabled)
635 return 0; 633 return 0;
636 634
637 rc = ebitmap_netlbl_import(&context->range.level[0].cat, 635 rc = ebitmap_netlbl_import(&context->range.level[0].cat,
diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h
index 1276715aaa8..cd9152632e5 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 b6e943a2106..03bed52a805 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 f03667213ea..23c6e53c102 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,20 +734,8 @@ 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++)
@@ -1686,12 +1715,11 @@ int policydb_read(struct policydb *p, void *fp)
1686 int i, j, rc; 1715 int i, j, rc;
1687 __le32 buf[4]; 1716 __le32 buf[4];
1688 u32 nodebuf[8]; 1717 u32 nodebuf[8];
1689 u32 len, len2, config, nprim, nel, nel2; 1718 u32 len, len2, nprim, nel, nel2;
1690 char *policydb_str; 1719 char *policydb_str;
1691 struct policydb_compat_info *info; 1720 struct policydb_compat_info *info;
1692 struct range_trans *rt, *lrt; 1721 struct range_trans *rt;
1693 1722 struct mls_range *r;
1694 config = 0;
1695 1723
1696 rc = policydb_init(p); 1724 rc = policydb_init(p);
1697 if (rc) 1725 if (rc)
@@ -1740,7 +1768,7 @@ int policydb_read(struct policydb *p, void *fp)
1740 kfree(policydb_str); 1768 kfree(policydb_str);
1741 policydb_str = NULL; 1769 policydb_str = NULL;
1742 1770
1743 /* Read the version, config, and table sizes. */ 1771 /* Read the version and table sizes. */
1744 rc = next_entry(buf, fp, sizeof(u32)*4); 1772 rc = next_entry(buf, fp, sizeof(u32)*4);
1745 if (rc < 0) 1773 if (rc < 0)
1746 goto bad; 1774 goto bad;
@@ -1755,13 +1783,7 @@ int policydb_read(struct policydb *p, void *fp)
1755 } 1783 }
1756 1784
1757 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { 1785 if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
1758 if (ss_initialized && !selinux_mls_enabled) { 1786 p->mls_enabled = 1;
1759 printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
1760 " and MLS policies\n");
1761 goto bad;
1762 }
1763 selinux_mls_enabled = 1;
1764 config |= POLICYDB_CONFIG_MLS;
1765 1787
1766 if (p->policyvers < POLICYDB_VERSION_MLS) { 1788 if (p->policyvers < POLICYDB_VERSION_MLS) {
1767 printk(KERN_ERR "SELinux: security policydb version %d " 1789 printk(KERN_ERR "SELinux: security policydb version %d "
@@ -1769,12 +1791,6 @@ int policydb_read(struct policydb *p, void *fp)
1769 p->policyvers); 1791 p->policyvers);
1770 goto bad; 1792 goto bad;
1771 } 1793 }
1772 } else {
1773 if (ss_initialized && selinux_mls_enabled) {
1774 printk(KERN_ERR "SELinux: Cannot switch between MLS and"
1775 " non-MLS policies\n");
1776 goto bad;
1777 }
1778 } 1794 }
1779 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); 1795 p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
1780 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); 1796 p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
@@ -2122,44 +2138,61 @@ int policydb_read(struct policydb *p, void *fp)
2122 if (rc < 0) 2138 if (rc < 0)
2123 goto bad; 2139 goto bad;
2124 nel = le32_to_cpu(buf[0]); 2140 nel = le32_to_cpu(buf[0]);
2125 lrt = NULL;
2126 for (i = 0; i < nel; i++) { 2141 for (i = 0; i < nel; i++) {
2127 rt = kzalloc(sizeof(*rt), GFP_KERNEL); 2142 rt = kzalloc(sizeof(*rt), GFP_KERNEL);
2128 if (!rt) { 2143 if (!rt) {
2129 rc = -ENOMEM; 2144 rc = -ENOMEM;
2130 goto bad; 2145 goto bad;
2131 } 2146 }
2132 if (lrt)
2133 lrt->next = rt;
2134 else
2135 p->range_tr = rt;
2136 rc = next_entry(buf, fp, (sizeof(u32) * 2)); 2147 rc = next_entry(buf, fp, (sizeof(u32) * 2));
2137 if (rc < 0) 2148 if (rc < 0) {
2149 kfree(rt);
2138 goto bad; 2150 goto bad;
2151 }
2139 rt->source_type = le32_to_cpu(buf[0]); 2152 rt->source_type = le32_to_cpu(buf[0]);
2140 rt->target_type = le32_to_cpu(buf[1]); 2153 rt->target_type = le32_to_cpu(buf[1]);
2141 if (new_rangetr) { 2154 if (new_rangetr) {
2142 rc = next_entry(buf, fp, sizeof(u32)); 2155 rc = next_entry(buf, fp, sizeof(u32));
2143 if (rc < 0) 2156 if (rc < 0) {
2157 kfree(rt);
2144 goto bad; 2158 goto bad;
2159 }
2145 rt->target_class = le32_to_cpu(buf[0]); 2160 rt->target_class = le32_to_cpu(buf[0]);
2146 } else 2161 } else
2147 rt->target_class = p->process_class; 2162 rt->target_class = p->process_class;
2148 if (!policydb_type_isvalid(p, rt->source_type) || 2163 if (!policydb_type_isvalid(p, rt->source_type) ||
2149 !policydb_type_isvalid(p, rt->target_type) || 2164 !policydb_type_isvalid(p, rt->target_type) ||
2150 !policydb_class_isvalid(p, rt->target_class)) { 2165 !policydb_class_isvalid(p, rt->target_class)) {
2166 kfree(rt);
2151 rc = -EINVAL; 2167 rc = -EINVAL;
2152 goto bad; 2168 goto bad;
2153 } 2169 }
2154 rc = mls_read_range_helper(&rt->target_range, fp); 2170 r = kzalloc(sizeof(*r), GFP_KERNEL);
2155 if (rc) 2171 if (!r) {
2172 kfree(rt);
2173 rc = -ENOMEM;
2156 goto bad; 2174 goto bad;
2157 if (!mls_range_isvalid(p, &rt->target_range)) { 2175 }
2176 rc = mls_read_range_helper(r, fp);
2177 if (rc) {
2178 kfree(rt);
2179 kfree(r);
2180 goto bad;
2181 }
2182 if (!mls_range_isvalid(p, r)) {
2158 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);
2159 goto bad; 2192 goto bad;
2160 } 2193 }
2161 lrt = rt;
2162 } 2194 }
2195 rangetr_hash_eval(p->range_tr);
2163 } 2196 }
2164 2197
2165 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 cdcc5700946..26d9adf8542 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -27,6 +27,8 @@
27#include "symtab.h" 27#include "symtab.h"
28#include "avtab.h" 28#include "avtab.h"
29#include "sidtab.h" 29#include "sidtab.h"
30#include "ebitmap.h"
31#include "mls_types.h"
30#include "context.h" 32#include "context.h"
31#include "constraint.h" 33#include "constraint.h"
32 34
@@ -113,8 +115,6 @@ struct range_trans {
113 u32 source_type; 115 u32 source_type;
114 u32 target_type; 116 u32 target_type;
115 u32 target_class; 117 u32 target_class;
116 struct mls_range target_range;
117 struct range_trans *next;
118}; 118};
119 119
120/* Boolean data type */ 120/* Boolean data type */
@@ -187,6 +187,8 @@ struct genfs {
187 187
188/* The policy database */ 188/* The policy database */
189struct policydb { 189struct policydb {
190 int mls_enabled;
191
190 /* symbol tables */ 192 /* symbol tables */
191 struct symtab symtab[SYM_NUM]; 193 struct symtab symtab[SYM_NUM];
192#define p_commons symtab[SYM_COMMONS] 194#define p_commons symtab[SYM_COMMONS]
@@ -240,8 +242,8 @@ struct policydb {
240 fixed labeling behavior. */ 242 fixed labeling behavior. */
241 struct genfs *genfs; 243 struct genfs *genfs;
242 244
243 /* range transitions */ 245 /* range transitions table (range_trans_key -> mls_range) */
244 struct range_trans *range_tr; 246 struct hashtab *range_tr;
245 247
246 /* type -> attribute reverse mapping */ 248 /* type -> attribute reverse mapping */
247 struct ebitmap *type_attr_map; 249 struct ebitmap *type_attr_map;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index b3efae204ac..cf27b3ee1a9 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -26,6 +26,10 @@
26 * 26 *
27 * Added support for bounds domain and audit messaged on masked permissions 27 * Added support for bounds domain and audit messaged on masked permissions
28 * 28 *
29 * Updated: Guido Trentalancia <guido@trentalancia.com>
30 *
31 * Added support for runtime switching of the policy type
32 *
29 * Copyright (C) 2008, 2009 NEC Corporation 33 * Copyright (C) 2008, 2009 NEC Corporation
30 * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. 34 * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
31 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. 35 * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
@@ -87,11 +91,10 @@ static u32 latest_granting;
87static int context_struct_to_string(struct context *context, char **scontext, 91static int context_struct_to_string(struct context *context, char **scontext,
88 u32 *scontext_len); 92 u32 *scontext_len);
89 93
90static int context_struct_compute_av(struct context *scontext, 94static void context_struct_compute_av(struct context *scontext,
91 struct context *tcontext, 95 struct context *tcontext,
92 u16 tclass, 96 u16 tclass,
93 u32 requested, 97 struct av_decision *avd);
94 struct av_decision *avd);
95 98
96struct selinux_mapping { 99struct selinux_mapping {
97 u16 value; /* policy value */ 100 u16 value; /* policy value */
@@ -196,23 +199,6 @@ static u16 unmap_class(u16 tclass)
196 return tclass; 199 return tclass;
197} 200}
198 201
199static u32 unmap_perm(u16 tclass, u32 tperm)
200{
201 if (tclass < current_mapping_size) {
202 unsigned i;
203 u32 kperm = 0;
204
205 for (i = 0; i < current_mapping[tclass].num_perms; i++)
206 if (tperm & (1<<i)) {
207 kperm |= current_mapping[tclass].perms[i];
208 tperm &= ~(1<<i);
209 }
210 return kperm;
211 }
212
213 return tperm;
214}
215
216static void map_decision(u16 tclass, struct av_decision *avd, 202static void map_decision(u16 tclass, struct av_decision *avd,
217 int allow_unknown) 203 int allow_unknown)
218{ 204{
@@ -250,6 +236,10 @@ static void map_decision(u16 tclass, struct av_decision *avd,
250 } 236 }
251} 237}
252 238
239int security_mls_enabled(void)
240{
241 return policydb.mls_enabled;
242}
253 243
254/* 244/*
255 * Return the boolean value of a constraint expression 245 * Return the boolean value of a constraint expression
@@ -465,7 +455,8 @@ static void security_dump_masked_av(struct context *scontext,
465 char *scontext_name = NULL; 455 char *scontext_name = NULL;
466 char *tcontext_name = NULL; 456 char *tcontext_name = NULL;
467 char *permission_names[32]; 457 char *permission_names[32];
468 int index, length; 458 int index;
459 u32 length;
469 bool need_comma = false; 460 bool need_comma = false;
470 461
471 if (!permissions) 462 if (!permissions)
@@ -532,7 +523,6 @@ out:
532static void type_attribute_bounds_av(struct context *scontext, 523static void type_attribute_bounds_av(struct context *scontext,
533 struct context *tcontext, 524 struct context *tcontext,
534 u16 tclass, 525 u16 tclass,
535 u32 requested,
536 struct av_decision *avd) 526 struct av_decision *avd)
537{ 527{
538 struct context lo_scontext; 528 struct context lo_scontext;
@@ -553,7 +543,6 @@ static void type_attribute_bounds_av(struct context *scontext,
553 context_struct_compute_av(&lo_scontext, 543 context_struct_compute_av(&lo_scontext,
554 tcontext, 544 tcontext,
555 tclass, 545 tclass,
556 requested,
557 &lo_avd); 546 &lo_avd);
558 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 547 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
559 return; /* no masked permission */ 548 return; /* no masked permission */
@@ -569,7 +558,6 @@ static void type_attribute_bounds_av(struct context *scontext,
569 context_struct_compute_av(scontext, 558 context_struct_compute_av(scontext,
570 &lo_tcontext, 559 &lo_tcontext,
571 tclass, 560 tclass,
572 requested,
573 &lo_avd); 561 &lo_avd);
574 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 562 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
575 return; /* no masked permission */ 563 return; /* no masked permission */
@@ -586,7 +574,6 @@ static void type_attribute_bounds_av(struct context *scontext,
586 context_struct_compute_av(&lo_scontext, 574 context_struct_compute_av(&lo_scontext,
587 &lo_tcontext, 575 &lo_tcontext,
588 tclass, 576 tclass,
589 requested,
590 &lo_avd); 577 &lo_avd);
591 if ((lo_avd.allowed & avd->allowed) == avd->allowed) 578 if ((lo_avd.allowed & avd->allowed) == avd->allowed)
592 return; /* no masked permission */ 579 return; /* no masked permission */
@@ -607,11 +594,10 @@ static void type_attribute_bounds_av(struct context *scontext,
607 * Compute access vectors based on a context structure pair for 594 * Compute access vectors based on a context structure pair for
608 * the permissions in a particular class. 595 * the permissions in a particular class.
609 */ 596 */
610static int context_struct_compute_av(struct context *scontext, 597static void context_struct_compute_av(struct context *scontext,
611 struct context *tcontext, 598 struct context *tcontext,
612 u16 tclass, 599 u16 tclass,
613 u32 requested, 600 struct av_decision *avd)
614 struct av_decision *avd)
615{ 601{
616 struct constraint_node *constraint; 602 struct constraint_node *constraint;
617 struct role_allow *ra; 603 struct role_allow *ra;
@@ -622,19 +608,14 @@ static int context_struct_compute_av(struct context *scontext,
622 struct ebitmap_node *snode, *tnode; 608 struct ebitmap_node *snode, *tnode;
623 unsigned int i, j; 609 unsigned int i, j;
624 610
625 /*
626 * Initialize the access vectors to the default values.
627 */
628 avd->allowed = 0; 611 avd->allowed = 0;
629 avd->auditallow = 0; 612 avd->auditallow = 0;
630 avd->auditdeny = 0xffffffff; 613 avd->auditdeny = 0xffffffff;
631 avd->seqno = latest_granting;
632 avd->flags = 0;
633 614
634 if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) { 615 if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) {
635 if (printk_ratelimit()) 616 if (printk_ratelimit())
636 printk(KERN_WARNING "SELinux: Invalid class %hu\n", tclass); 617 printk(KERN_WARNING "SELinux: Invalid class %hu\n", tclass);
637 return -EINVAL; 618 return;
638 } 619 }
639 620
640 tclass_datum = policydb.class_val_to_struct[tclass - 1]; 621 tclass_datum = policydb.class_val_to_struct[tclass - 1];
@@ -705,9 +686,7 @@ static int context_struct_compute_av(struct context *scontext,
705 * permission and notice it to userspace via audit. 686 * permission and notice it to userspace via audit.
706 */ 687 */
707 type_attribute_bounds_av(scontext, tcontext, 688 type_attribute_bounds_av(scontext, tcontext,
708 tclass, requested, avd); 689 tclass, avd);
709
710 return 0;
711} 690}
712 691
713static int security_validtrans_handle_fail(struct context *ocontext, 692static int security_validtrans_handle_fail(struct context *ocontext,
@@ -864,7 +843,7 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
864 if (rc) { 843 if (rc) {
865 char *old_name = NULL; 844 char *old_name = NULL;
866 char *new_name = NULL; 845 char *new_name = NULL;
867 int length; 846 u32 length;
868 847
869 if (!context_struct_to_string(old_context, 848 if (!context_struct_to_string(old_context,
870 &old_name, &length) && 849 &old_name, &length) &&
@@ -886,110 +865,116 @@ out:
886 return rc; 865 return rc;
887} 866}
888 867
889 868static void avd_init(struct av_decision *avd)
890static int security_compute_av_core(u32 ssid,
891 u32 tsid,
892 u16 tclass,
893 u32 requested,
894 struct av_decision *avd)
895{ 869{
896 struct context *scontext = NULL, *tcontext = NULL; 870 avd->allowed = 0;
897 int rc = 0; 871 avd->auditallow = 0;
898 872 avd->auditdeny = 0xffffffff;
899 scontext = sidtab_search(&sidtab, ssid); 873 avd->seqno = latest_granting;
900 if (!scontext) { 874 avd->flags = 0;
901 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
902 __func__, ssid);
903 return -EINVAL;
904 }
905 tcontext = sidtab_search(&sidtab, tsid);
906 if (!tcontext) {
907 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
908 __func__, tsid);
909 return -EINVAL;
910 }
911
912 rc = context_struct_compute_av(scontext, tcontext, tclass,
913 requested, avd);
914
915 /* permissive domain? */
916 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
917 avd->flags |= AVD_FLAGS_PERMISSIVE;
918
919 return rc;
920} 875}
921 876
877
922/** 878/**
923 * security_compute_av - Compute access vector decisions. 879 * security_compute_av - Compute access vector decisions.
924 * @ssid: source security identifier 880 * @ssid: source security identifier
925 * @tsid: target security identifier 881 * @tsid: target security identifier
926 * @tclass: target security class 882 * @tclass: target security class
927 * @requested: requested permissions
928 * @avd: access vector decisions 883 * @avd: access vector decisions
929 * 884 *
930 * Compute a set of access vector decisions based on the 885 * Compute a set of access vector decisions based on the
931 * SID pair (@ssid, @tsid) for the permissions in @tclass. 886 * SID pair (@ssid, @tsid) for the permissions in @tclass.
932 * Return -%EINVAL if any of the parameters are invalid or %0
933 * if the access vector decisions were computed successfully.
934 */ 887 */
935int security_compute_av(u32 ssid, 888void security_compute_av(u32 ssid,
936 u32 tsid, 889 u32 tsid,
937 u16 orig_tclass, 890 u16 orig_tclass,
938 u32 orig_requested, 891 struct av_decision *avd)
939 struct av_decision *avd)
940{ 892{
941 u16 tclass; 893 u16 tclass;
942 u32 requested; 894 struct context *scontext = NULL, *tcontext = NULL;
943 int rc;
944 895
945 read_lock(&policy_rwlock); 896 read_lock(&policy_rwlock);
946 897 avd_init(avd);
947 if (!ss_initialized) 898 if (!ss_initialized)
948 goto allow; 899 goto allow;
949 900
950 requested = unmap_perm(orig_tclass, orig_requested); 901 scontext = sidtab_search(&sidtab, ssid);
902 if (!scontext) {
903 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
904 __func__, ssid);
905 goto out;
906 }
907
908 /* permissive domain? */
909 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
910 avd->flags |= AVD_FLAGS_PERMISSIVE;
911
912 tcontext = sidtab_search(&sidtab, tsid);
913 if (!tcontext) {
914 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
915 __func__, tsid);
916 goto out;
917 }
918
951 tclass = unmap_class(orig_tclass); 919 tclass = unmap_class(orig_tclass);
952 if (unlikely(orig_tclass && !tclass)) { 920 if (unlikely(orig_tclass && !tclass)) {
953 if (policydb.allow_unknown) 921 if (policydb.allow_unknown)
954 goto allow; 922 goto allow;
955 rc = -EINVAL;
956 goto out; 923 goto out;
957 } 924 }
958 rc = security_compute_av_core(ssid, tsid, tclass, requested, avd); 925 context_struct_compute_av(scontext, tcontext, tclass, avd);
959 map_decision(orig_tclass, avd, policydb.allow_unknown); 926 map_decision(orig_tclass, avd, policydb.allow_unknown);
960out: 927out:
961 read_unlock(&policy_rwlock); 928 read_unlock(&policy_rwlock);
962 return rc; 929 return;
963allow: 930allow:
964 avd->allowed = 0xffffffff; 931 avd->allowed = 0xffffffff;
965 avd->auditallow = 0;
966 avd->auditdeny = 0xffffffff;
967 avd->seqno = latest_granting;
968 avd->flags = 0;
969 rc = 0;
970 goto out; 932 goto out;
971} 933}
972 934
973int security_compute_av_user(u32 ssid, 935void security_compute_av_user(u32 ssid,
974 u32 tsid, 936 u32 tsid,
975 u16 tclass, 937 u16 tclass,
976 u32 requested, 938 struct av_decision *avd)
977 struct av_decision *avd)
978{ 939{
979 int rc; 940 struct context *scontext = NULL, *tcontext = NULL;
980 941
981 if (!ss_initialized) { 942 read_lock(&policy_rwlock);
982 avd->allowed = 0xffffffff; 943 avd_init(avd);
983 avd->auditallow = 0; 944 if (!ss_initialized)
984 avd->auditdeny = 0xffffffff; 945 goto allow;
985 avd->seqno = latest_granting; 946
986 return 0; 947 scontext = sidtab_search(&sidtab, ssid);
948 if (!scontext) {
949 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
950 __func__, ssid);
951 goto out;
987 } 952 }
988 953
989 read_lock(&policy_rwlock); 954 /* permissive domain? */
990 rc = security_compute_av_core(ssid, tsid, tclass, requested, avd); 955 if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
956 avd->flags |= AVD_FLAGS_PERMISSIVE;
957
958 tcontext = sidtab_search(&sidtab, tsid);
959 if (!tcontext) {
960 printk(KERN_ERR "SELinux: %s: unrecognized SID %d\n",
961 __func__, tsid);
962 goto out;
963 }
964
965 if (unlikely(!tclass)) {
966 if (policydb.allow_unknown)
967 goto allow;
968 goto out;
969 }
970
971 context_struct_compute_av(scontext, tcontext, tclass, avd);
972 out:
991 read_unlock(&policy_rwlock); 973 read_unlock(&policy_rwlock);
992 return rc; 974 return;
975allow:
976 avd->allowed = 0xffffffff;
977 goto out;
993} 978}
994 979
995/* 980/*
@@ -1565,7 +1550,10 @@ static int clone_sid(u32 sid,
1565{ 1550{
1566 struct sidtab *s = arg; 1551 struct sidtab *s = arg;
1567 1552
1568 return sidtab_insert(s, sid, context); 1553 if (sid > SECINITSID_NUM)
1554 return sidtab_insert(s, sid, context);
1555 else
1556 return 0;
1569} 1557}
1570 1558
1571static inline int convert_context_handle_invalid_context(struct context *context) 1559static inline int convert_context_handle_invalid_context(struct context *context)
@@ -1606,12 +1594,17 @@ static int convert_context(u32 key,
1606{ 1594{
1607 struct convert_context_args *args; 1595 struct convert_context_args *args;
1608 struct context oldc; 1596 struct context oldc;
1597 struct ocontext *oc;
1598 struct mls_range *range;
1609 struct role_datum *role; 1599 struct role_datum *role;
1610 struct type_datum *typdatum; 1600 struct type_datum *typdatum;
1611 struct user_datum *usrdatum; 1601 struct user_datum *usrdatum;
1612 char *s; 1602 char *s;
1613 u32 len; 1603 u32 len;
1614 int rc; 1604 int rc = 0;
1605
1606 if (key <= SECINITSID_NUM)
1607 goto out;
1615 1608
1616 args = p; 1609 args = p;
1617 1610
@@ -1673,9 +1666,39 @@ static int convert_context(u32 key,
1673 goto bad; 1666 goto bad;
1674 c->type = typdatum->value; 1667 c->type = typdatum->value;
1675 1668
1676 rc = mls_convert_context(args->oldp, args->newp, c); 1669 /* Convert the MLS fields if dealing with MLS policies */
1677 if (rc) 1670 if (args->oldp->mls_enabled && args->newp->mls_enabled) {
1678 goto bad; 1671 rc = mls_convert_context(args->oldp, args->newp, c);
1672 if (rc)
1673 goto bad;
1674 } else if (args->oldp->mls_enabled && !args->newp->mls_enabled) {
1675 /*
1676 * Switching between MLS and non-MLS policy:
1677 * free any storage used by the MLS fields in the
1678 * context for all existing entries in the sidtab.
1679 */
1680 mls_context_destroy(c);
1681 } else if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
1682 /*
1683 * Switching between non-MLS and MLS policy:
1684 * ensure that the MLS fields of the context for all
1685 * existing entries in the sidtab are filled in with a
1686 * suitable default value, likely taken from one of the
1687 * initial SIDs.
1688 */
1689 oc = args->newp->ocontexts[OCON_ISID];
1690 while (oc && oc->sid[0] != SECINITSID_UNLABELED)
1691 oc = oc->next;
1692 if (!oc) {
1693 printk(KERN_ERR "SELinux: unable to look up"
1694 " the initial SIDs list\n");
1695 goto bad;
1696 }
1697 range = &oc->context[0].range;
1698 rc = mls_range_set(c, range);
1699 if (rc)
1700 goto bad;
1701 }
1679 1702
1680 /* Check the validity of the new context. */ 1703 /* Check the validity of the new context. */
1681 if (!policydb_context_isvalid(args->newp, c)) { 1704 if (!policydb_context_isvalid(args->newp, c)) {
@@ -1771,9 +1794,17 @@ int security_load_policy(void *data, size_t len)
1771 if (policydb_read(&newpolicydb, fp)) 1794 if (policydb_read(&newpolicydb, fp))
1772 return -EINVAL; 1795 return -EINVAL;
1773 1796
1774 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");
1775 policydb_destroy(&newpolicydb); 1806 policydb_destroy(&newpolicydb);
1776 return -ENOMEM; 1807 return rc;
1777 } 1808 }
1778 1809
1779 if (selinux_set_mapping(&newpolicydb, secclass_map, 1810 if (selinux_set_mapping(&newpolicydb, secclass_map,
@@ -1800,8 +1831,12 @@ int security_load_policy(void *data, size_t len)
1800 args.oldp = &policydb; 1831 args.oldp = &policydb;
1801 args.newp = &newpolicydb; 1832 args.newp = &newpolicydb;
1802 rc = sidtab_map(&newsidtab, convert_context, &args); 1833 rc = sidtab_map(&newsidtab, convert_context, &args);
1803 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");
1804 goto err; 1838 goto err;
1839 }
1805 1840
1806 /* Save the old policydb and SID table to free later. */ 1841 /* Save the old policydb and SID table to free later. */
1807 memcpy(&oldpolicydb, &policydb, sizeof policydb); 1842 memcpy(&oldpolicydb, &policydb, sizeof policydb);
@@ -2397,7 +2432,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid)
2397 u32 len; 2432 u32 len;
2398 int rc = 0; 2433 int rc = 0;
2399 2434
2400 if (!ss_initialized || !selinux_mls_enabled) { 2435 if (!ss_initialized || !policydb.mls_enabled) {
2401 *new_sid = sid; 2436 *new_sid = sid;
2402 goto out; 2437 goto out;
2403 } 2438 }
@@ -2498,7 +2533,7 @@ int security_net_peersid_resolve(u32 nlbl_sid, u32 nlbl_type,
2498 /* we don't need to check ss_initialized here since the only way both 2533 /* we don't need to check ss_initialized here since the only way both
2499 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the 2534 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
2500 * security server was initialized and ss_initialized was true */ 2535 * security server was initialized and ss_initialized was true */
2501 if (!selinux_mls_enabled) { 2536 if (!policydb.mls_enabled) {
2502 *peer_sid = SECSID_NULL; 2537 *peer_sid = SECSID_NULL;
2503 return 0; 2538 return 0;
2504 } 2539 }
@@ -2555,7 +2590,7 @@ int security_get_classes(char ***classes, int *nclasses)
2555 read_lock(&policy_rwlock); 2590 read_lock(&policy_rwlock);
2556 2591
2557 *nclasses = policydb.p_classes.nprim; 2592 *nclasses = policydb.p_classes.nprim;
2558 *classes = kcalloc(*nclasses, sizeof(*classes), GFP_ATOMIC); 2593 *classes = kcalloc(*nclasses, sizeof(**classes), GFP_ATOMIC);
2559 if (!*classes) 2594 if (!*classes)
2560 goto out; 2595 goto out;
2561 2596
@@ -2602,7 +2637,7 @@ int security_get_permissions(char *class, char ***perms, int *nperms)
2602 } 2637 }
2603 2638
2604 *nperms = match->permissions.nprim; 2639 *nperms = match->permissions.nprim;
2605 *perms = kcalloc(*nperms, sizeof(*perms), GFP_ATOMIC); 2640 *perms = kcalloc(*nperms, sizeof(**perms), GFP_ATOMIC);
2606 if (!*perms) 2641 if (!*perms)
2607 goto out; 2642 goto out;
2608 2643
diff --git a/security/selinux/ss/symtab.c b/security/selinux/ss/symtab.c
index 837658a98a5..bcf9f620426 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 f3cb9ed731a..fff78d3b51a 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 0f9ac814690..f4fac64c4da 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 529c9ca6587..fdfeaa2f28e 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;
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index aeead758509..a2b72d77f92 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 10ccd686b29..60a9e2002da 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 e0d0354008b..975c45d88ba 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,14 +180,12 @@ 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; 190 const char *const start = filename;
191 bool in_repetition = false; 191 bool in_repetition = false;
@@ -193,7 +193,6 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
193 unsigned char c; 193 unsigned char c;
194 unsigned char d; 194 unsigned char d;
195 unsigned char e; 195 unsigned char e;
196 const char *original_filename = filename;
197 196
198 if (!filename) 197 if (!filename)
199 goto out; 198 goto out;
@@ -282,25 +281,20 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
282 goto out; 281 goto out;
283 return true; 282 return true;
284 out: 283 out:
285 printk(KERN_DEBUG "%s: Invalid pathname '%s'\n", function,
286 original_filename);
287 return false; 284 return false;
288} 285}
289 286
290/** 287/**
291 * 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.
292 * @domainname: The domainname to check. 289 * @domainname: The domainname to check.
293 * @function: The name of function calling me.
294 * 290 *
295 * Returns true if @domainname follows the naming rules, false otherwise. 291 * Returns true if @domainname follows the naming rules, false otherwise.
296 */ 292 */
297bool tomoyo_is_correct_domain(const unsigned char *domainname, 293bool tomoyo_is_correct_domain(const unsigned char *domainname)
298 const char *function)
299{ 294{
300 unsigned char c; 295 unsigned char c;
301 unsigned char d; 296 unsigned char d;
302 unsigned char e; 297 unsigned char e;
303 const char *org_domainname = domainname;
304 298
305 if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME, 299 if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME,
306 TOMOYO_ROOT_NAME_LEN)) 300 TOMOYO_ROOT_NAME_LEN))
@@ -343,8 +337,6 @@ bool tomoyo_is_correct_domain(const unsigned char *domainname,
343 } while (*domainname); 337 } while (*domainname);
344 return true; 338 return true;
345 out: 339 out:
346 printk(KERN_DEBUG "%s: Invalid domainname '%s'\n", function,
347 org_domainname);
348 return false; 340 return false;
349} 341}
350 342
@@ -365,10 +357,9 @@ bool tomoyo_is_domain_def(const unsigned char *buffer)
365 * 357 *
366 * @domainname: The domainname to find. 358 * @domainname: The domainname to find.
367 * 359 *
368 * Caller must call down_read(&tomoyo_domain_list_lock); or
369 * down_write(&tomoyo_domain_list_lock); .
370 *
371 * 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().
372 */ 363 */
373struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname) 364struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)
374{ 365{
@@ -377,7 +368,7 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)
377 368
378 name.name = domainname; 369 name.name = domainname;
379 tomoyo_fill_path_info(&name); 370 tomoyo_fill_path_info(&name);
380 list_for_each_entry(domain, &tomoyo_domain_list, list) { 371 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
381 if (!domain->is_deleted && 372 if (!domain->is_deleted &&
382 !tomoyo_pathcmp(&name, domain->domainname)) 373 !tomoyo_pathcmp(&name, domain->domainname))
383 return domain; 374 return domain;
@@ -748,7 +739,7 @@ bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
748 * 739 *
749 * Returns the tomoyo_realpath() of current process on success, NULL otherwise. 740 * Returns the tomoyo_realpath() of current process on success, NULL otherwise.
750 * 741 *
751 * This function uses tomoyo_alloc(), so the caller must call tomoyo_free() 742 * This function uses kzalloc(), so the caller must call kfree()
752 * if this function didn't return NULL. 743 * if this function didn't return NULL.
753 */ 744 */
754static const char *tomoyo_get_exe(void) 745static const char *tomoyo_get_exe(void)
@@ -829,6 +820,8 @@ bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain)
829 * @domain: Pointer to "struct tomoyo_domain_info". 820 * @domain: Pointer to "struct tomoyo_domain_info".
830 * 821 *
831 * 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().
832 */ 825 */
833bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain) 826bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain)
834{ 827{
@@ -837,61 +830,29 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain)
837 830
838 if (!domain) 831 if (!domain)
839 return true; 832 return true;
840 down_read(&tomoyo_domain_acl_info_list_lock); 833 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
841 list_for_each_entry(ptr, &domain->acl_info_list, list) { 834 switch (ptr->type) {
842 if (ptr->type & TOMOYO_ACL_DELETED) 835 struct tomoyo_path_acl *acl;
843 continue; 836 u32 perm;
844 switch (tomoyo_acl_type2(ptr)) { 837 u8 i;
845 struct tomoyo_single_path_acl_record *acl1; 838 case TOMOYO_TYPE_PATH_ACL:
846 struct tomoyo_double_path_acl_record *acl2; 839 acl = container_of(ptr, struct tomoyo_path_acl, head);
847 u16 perm; 840 perm = acl->perm | (((u32) acl->perm_high) << 16);
848 case TOMOYO_TYPE_SINGLE_PATH_ACL: 841 for (i = 0; i < TOMOYO_MAX_PATH_OPERATION; i++)
849 acl1 = container_of(ptr, 842 if (perm & (1 << i))
850 struct tomoyo_single_path_acl_record, 843 count++;
851 head); 844 if (perm & (1 << TOMOYO_TYPE_READ_WRITE))
852 perm = acl1->perm; 845 count -= 2;
853 if (perm & (1 << TOMOYO_TYPE_EXECUTE_ACL))
854 count++;
855 if (perm &
856 ((1 << TOMOYO_TYPE_READ_ACL) |
857 (1 << TOMOYO_TYPE_WRITE_ACL)))
858 count++;
859 if (perm & (1 << TOMOYO_TYPE_CREATE_ACL))
860 count++;
861 if (perm & (1 << TOMOYO_TYPE_UNLINK_ACL))
862 count++;
863 if (perm & (1 << TOMOYO_TYPE_MKDIR_ACL))
864 count++;
865 if (perm & (1 << TOMOYO_TYPE_RMDIR_ACL))
866 count++;
867 if (perm & (1 << TOMOYO_TYPE_MKFIFO_ACL))
868 count++;
869 if (perm & (1 << TOMOYO_TYPE_MKSOCK_ACL))
870 count++;
871 if (perm & (1 << TOMOYO_TYPE_MKBLOCK_ACL))
872 count++;
873 if (perm & (1 << TOMOYO_TYPE_MKCHAR_ACL))
874 count++;
875 if (perm & (1 << TOMOYO_TYPE_TRUNCATE_ACL))
876 count++;
877 if (perm & (1 << TOMOYO_TYPE_SYMLINK_ACL))
878 count++;
879 if (perm & (1 << TOMOYO_TYPE_REWRITE_ACL))
880 count++;
881 break; 846 break;
882 case TOMOYO_TYPE_DOUBLE_PATH_ACL: 847 case TOMOYO_TYPE_PATH2_ACL:
883 acl2 = container_of(ptr, 848 perm = container_of(ptr, struct tomoyo_path2_acl, head)
884 struct tomoyo_double_path_acl_record, 849 ->perm;
885 head); 850 for (i = 0; i < TOMOYO_MAX_PATH2_OPERATION; i++)
886 perm = acl2->perm; 851 if (perm & (1 << i))
887 if (perm & (1 << TOMOYO_TYPE_LINK_ACL)) 852 count++;
888 count++;
889 if (perm & (1 << TOMOYO_TYPE_RENAME_ACL))
890 count++;
891 break; 853 break;
892 } 854 }
893 } 855 }
894 up_read(&tomoyo_domain_acl_info_list_lock);
895 if (count < tomoyo_check_flags(domain, TOMOYO_MAX_ACCEPT_ENTRY)) 856 if (count < tomoyo_check_flags(domain, TOMOYO_MAX_ACCEPT_ENTRY))
896 return true; 857 return true;
897 if (!domain->quota_warned) { 858 if (!domain->quota_warned) {
@@ -923,9 +884,12 @@ static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned
923 ptr = tomoyo_profile_ptr[profile]; 884 ptr = tomoyo_profile_ptr[profile];
924 if (ptr) 885 if (ptr)
925 goto ok; 886 goto ok;
926 ptr = tomoyo_alloc_element(sizeof(*ptr)); 887 ptr = kmalloc(sizeof(*ptr), GFP_KERNEL);
927 if (!ptr) 888 if (!tomoyo_memory_ok(ptr)) {
889 kfree(ptr);
890 ptr = NULL;
928 goto ok; 891 goto ok;
892 }
929 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) 893 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++)
930 ptr->value[i] = tomoyo_control_array[i].current_value; 894 ptr->value[i] = tomoyo_control_array[i].current_value;
931 mb(); /* Avoid out-of-order execution. */ 895 mb(); /* Avoid out-of-order execution. */
@@ -966,7 +930,9 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
966 return -EINVAL; 930 return -EINVAL;
967 *cp = '\0'; 931 *cp = '\0';
968 if (!strcmp(data, "COMMENT")) { 932 if (!strcmp(data, "COMMENT")) {
969 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);
970 return 0; 936 return 0;
971 } 937 }
972 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) { 938 for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) {
@@ -1061,27 +1027,6 @@ static int tomoyo_read_profile(struct tomoyo_io_buffer *head)
1061} 1027}
1062 1028
1063/* 1029/*
1064 * tomoyo_policy_manager_entry is a structure which is used for holding list of
1065 * domainnames or programs which are permitted to modify configuration via
1066 * /sys/kernel/security/tomoyo/ interface.
1067 * It has following fields.
1068 *
1069 * (1) "list" which is linked to tomoyo_policy_manager_list .
1070 * (2) "manager" is a domainname or a program's pathname.
1071 * (3) "is_domain" is a bool which is true if "manager" is a domainname, false
1072 * otherwise.
1073 * (4) "is_deleted" is a bool which is true if marked as deleted, false
1074 * otherwise.
1075 */
1076struct tomoyo_policy_manager_entry {
1077 struct list_head list;
1078 /* A path to program or a domainname. */
1079 const struct tomoyo_path_info *manager;
1080 bool is_domain; /* True if manager is a domainname. */
1081 bool is_deleted; /* True if this entry is deleted. */
1082};
1083
1084/*
1085 * 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
1086 * programs which are permitted to modify configuration via 1031 * programs which are permitted to modify configuration via
1087 * /sys/kernel/security/tomoyo/ interface. 1032 * /sys/kernel/security/tomoyo/ interface.
@@ -1111,8 +1056,7 @@ struct tomoyo_policy_manager_entry {
1111 * 1056 *
1112 * # cat /sys/kernel/security/tomoyo/manager 1057 * # cat /sys/kernel/security/tomoyo/manager
1113 */ 1058 */
1114static LIST_HEAD(tomoyo_policy_manager_list); 1059LIST_HEAD(tomoyo_policy_manager_list);
1115static DECLARE_RWSEM(tomoyo_policy_manager_list_lock);
1116 1060
1117/** 1061/**
1118 * tomoyo_update_manager_entry - Add a manager entry. 1062 * tomoyo_update_manager_entry - Add a manager entry.
@@ -1121,48 +1065,50 @@ static DECLARE_RWSEM(tomoyo_policy_manager_list_lock);
1121 * @is_delete: True if it is a delete request. 1065 * @is_delete: True if it is a delete request.
1122 * 1066 *
1123 * Returns 0 on success, negative value otherwise. 1067 * Returns 0 on success, negative value otherwise.
1068 *
1069 * Caller holds tomoyo_read_lock().
1124 */ 1070 */
1125static int tomoyo_update_manager_entry(const char *manager, 1071static int tomoyo_update_manager_entry(const char *manager,
1126 const bool is_delete) 1072 const bool is_delete)
1127{ 1073{
1128 struct tomoyo_policy_manager_entry *new_entry; 1074 struct tomoyo_policy_manager_entry *entry = NULL;
1129 struct tomoyo_policy_manager_entry *ptr; 1075 struct tomoyo_policy_manager_entry *ptr;
1130 const struct tomoyo_path_info *saved_manager; 1076 const struct tomoyo_path_info *saved_manager;
1131 int error = -ENOMEM; 1077 int error = is_delete ? -ENOENT : -ENOMEM;
1132 bool is_domain = false; 1078 bool is_domain = false;
1133 1079
1134 if (tomoyo_is_domain_def(manager)) { 1080 if (tomoyo_is_domain_def(manager)) {
1135 if (!tomoyo_is_correct_domain(manager, __func__)) 1081 if (!tomoyo_is_correct_domain(manager))
1136 return -EINVAL; 1082 return -EINVAL;
1137 is_domain = true; 1083 is_domain = true;
1138 } else { 1084 } else {
1139 if (!tomoyo_is_correct_path(manager, 1, -1, -1, __func__)) 1085 if (!tomoyo_is_correct_path(manager, 1, -1, -1))
1140 return -EINVAL; 1086 return -EINVAL;
1141 } 1087 }
1142 saved_manager = tomoyo_save_name(manager); 1088 saved_manager = tomoyo_get_name(manager);
1143 if (!saved_manager) 1089 if (!saved_manager)
1144 return -ENOMEM; 1090 return -ENOMEM;
1145 down_write(&tomoyo_policy_manager_list_lock); 1091 if (!is_delete)
1146 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) {
1147 if (ptr->manager != saved_manager) 1095 if (ptr->manager != saved_manager)
1148 continue; 1096 continue;
1149 ptr->is_deleted = is_delete; 1097 ptr->is_deleted = is_delete;
1150 error = 0; 1098 error = 0;
1151 goto out; 1099 break;
1152 } 1100 }
1153 if (is_delete) { 1101 if (!is_delete && error && tomoyo_memory_ok(entry)) {
1154 error = -ENOENT; 1102 entry->manager = saved_manager;
1155 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;
1156 } 1108 }
1157 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 1109 mutex_unlock(&tomoyo_policy_lock);
1158 if (!new_entry) 1110 tomoyo_put_name(saved_manager);
1159 goto out; 1111 kfree(entry);
1160 new_entry->manager = saved_manager;
1161 new_entry->is_domain = is_domain;
1162 list_add_tail(&new_entry->list, &tomoyo_policy_manager_list);
1163 error = 0;
1164 out:
1165 up_write(&tomoyo_policy_manager_list_lock);
1166 return error; 1112 return error;
1167} 1113}
1168 1114
@@ -1172,6 +1118,8 @@ static int tomoyo_update_manager_entry(const char *manager,
1172 * @head: Pointer to "struct tomoyo_io_buffer". 1118 * @head: Pointer to "struct tomoyo_io_buffer".
1173 * 1119 *
1174 * Returns 0 on success, negative value otherwise. 1120 * Returns 0 on success, negative value otherwise.
1121 *
1122 * Caller holds tomoyo_read_lock().
1175 */ 1123 */
1176static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head) 1124static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head)
1177{ 1125{
@@ -1191,6 +1139,8 @@ static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head)
1191 * @head: Pointer to "struct tomoyo_io_buffer". 1139 * @head: Pointer to "struct tomoyo_io_buffer".
1192 * 1140 *
1193 * Returns 0. 1141 * Returns 0.
1142 *
1143 * Caller holds tomoyo_read_lock().
1194 */ 1144 */
1195static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head) 1145static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
1196{ 1146{
@@ -1199,7 +1149,6 @@ static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
1199 1149
1200 if (head->read_eof) 1150 if (head->read_eof)
1201 return 0; 1151 return 0;
1202 down_read(&tomoyo_policy_manager_list_lock);
1203 list_for_each_cookie(pos, head->read_var2, 1152 list_for_each_cookie(pos, head->read_var2,
1204 &tomoyo_policy_manager_list) { 1153 &tomoyo_policy_manager_list) {
1205 struct tomoyo_policy_manager_entry *ptr; 1154 struct tomoyo_policy_manager_entry *ptr;
@@ -1211,7 +1160,6 @@ static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
1211 if (!done) 1160 if (!done)
1212 break; 1161 break;
1213 } 1162 }
1214 up_read(&tomoyo_policy_manager_list_lock);
1215 head->read_eof = done; 1163 head->read_eof = done;
1216 return 0; 1164 return 0;
1217} 1165}
@@ -1221,6 +1169,8 @@ static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
1221 * 1169 *
1222 * Returns true if the current process is permitted to modify policy 1170 * Returns true if the current process is permitted to modify policy
1223 * via /sys/kernel/security/tomoyo/ interface. 1171 * via /sys/kernel/security/tomoyo/ interface.
1172 *
1173 * Caller holds tomoyo_read_lock().
1224 */ 1174 */
1225static bool tomoyo_is_policy_manager(void) 1175static bool tomoyo_is_policy_manager(void)
1226{ 1176{
@@ -1234,29 +1184,25 @@ static bool tomoyo_is_policy_manager(void)
1234 return true; 1184 return true;
1235 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))
1236 return false; 1186 return false;
1237 down_read(&tomoyo_policy_manager_list_lock); 1187 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
1238 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) {
1239 if (!ptr->is_deleted && ptr->is_domain 1188 if (!ptr->is_deleted && ptr->is_domain
1240 && !tomoyo_pathcmp(domainname, ptr->manager)) { 1189 && !tomoyo_pathcmp(domainname, ptr->manager)) {
1241 found = true; 1190 found = true;
1242 break; 1191 break;
1243 } 1192 }
1244 } 1193 }
1245 up_read(&tomoyo_policy_manager_list_lock);
1246 if (found) 1194 if (found)
1247 return true; 1195 return true;
1248 exe = tomoyo_get_exe(); 1196 exe = tomoyo_get_exe();
1249 if (!exe) 1197 if (!exe)
1250 return false; 1198 return false;
1251 down_read(&tomoyo_policy_manager_list_lock); 1199 list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
1252 list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) {
1253 if (!ptr->is_deleted && !ptr->is_domain 1200 if (!ptr->is_deleted && !ptr->is_domain
1254 && !strcmp(exe, ptr->manager->name)) { 1201 && !strcmp(exe, ptr->manager->name)) {
1255 found = true; 1202 found = true;
1256 break; 1203 break;
1257 } 1204 }
1258 } 1205 }
1259 up_read(&tomoyo_policy_manager_list_lock);
1260 if (!found) { /* Reduce error messages. */ 1206 if (!found) { /* Reduce error messages. */
1261 static pid_t last_pid; 1207 static pid_t last_pid;
1262 const pid_t pid = current->pid; 1208 const pid_t pid = current->pid;
@@ -1266,7 +1212,7 @@ static bool tomoyo_is_policy_manager(void)
1266 last_pid = pid; 1212 last_pid = pid;
1267 } 1213 }
1268 } 1214 }
1269 tomoyo_free(exe); 1215 kfree(exe);
1270 return found; 1216 return found;
1271} 1217}
1272 1218
@@ -1277,6 +1223,8 @@ static bool tomoyo_is_policy_manager(void)
1277 * @data: String to parse. 1223 * @data: String to parse.
1278 * 1224 *
1279 * Returns true on success, false otherwise. 1225 * Returns true on success, false otherwise.
1226 *
1227 * Caller holds tomoyo_read_lock().
1280 */ 1228 */
1281static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head, 1229static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
1282 const char *data) 1230 const char *data)
@@ -1286,17 +1234,16 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
1286 1234
1287 if (sscanf(data, "pid=%u", &pid) == 1) { 1235 if (sscanf(data, "pid=%u", &pid) == 1) {
1288 struct task_struct *p; 1236 struct task_struct *p;
1237 rcu_read_lock();
1289 read_lock(&tasklist_lock); 1238 read_lock(&tasklist_lock);
1290 p = find_task_by_vpid(pid); 1239 p = find_task_by_vpid(pid);
1291 if (p) 1240 if (p)
1292 domain = tomoyo_real_domain(p); 1241 domain = tomoyo_real_domain(p);
1293 read_unlock(&tasklist_lock); 1242 read_unlock(&tasklist_lock);
1243 rcu_read_unlock();
1294 } else if (!strncmp(data, "domain=", 7)) { 1244 } else if (!strncmp(data, "domain=", 7)) {
1295 if (tomoyo_is_domain_def(data + 7)) { 1245 if (tomoyo_is_domain_def(data + 7))
1296 down_read(&tomoyo_domain_list_lock);
1297 domain = tomoyo_find_domain(data + 7); 1246 domain = tomoyo_find_domain(data + 7);
1298 up_read(&tomoyo_domain_list_lock);
1299 }
1300 } else 1247 } else
1301 return false; 1248 return false;
1302 head->write_var1 = domain; 1249 head->write_var1 = domain;
@@ -1310,13 +1257,11 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
1310 if (domain) { 1257 if (domain) {
1311 struct tomoyo_domain_info *d; 1258 struct tomoyo_domain_info *d;
1312 head->read_var1 = NULL; 1259 head->read_var1 = NULL;
1313 down_read(&tomoyo_domain_list_lock); 1260 list_for_each_entry_rcu(d, &tomoyo_domain_list, list) {
1314 list_for_each_entry(d, &tomoyo_domain_list, list) {
1315 if (d == domain) 1261 if (d == domain)
1316 break; 1262 break;
1317 head->read_var1 = &d->list; 1263 head->read_var1 = &d->list;
1318 } 1264 }
1319 up_read(&tomoyo_domain_list_lock);
1320 head->read_var2 = NULL; 1265 head->read_var2 = NULL;
1321 head->read_bit = 0; 1266 head->read_bit = 0;
1322 head->read_step = 0; 1267 head->read_step = 0;
@@ -1332,6 +1277,8 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
1332 * @domainname: The name of domain. 1277 * @domainname: The name of domain.
1333 * 1278 *
1334 * Returns 0. 1279 * Returns 0.
1280 *
1281 * Caller holds tomoyo_read_lock().
1335 */ 1282 */
1336static int tomoyo_delete_domain(char *domainname) 1283static int tomoyo_delete_domain(char *domainname)
1337{ 1284{
@@ -1340,9 +1287,9 @@ static int tomoyo_delete_domain(char *domainname)
1340 1287
1341 name.name = domainname; 1288 name.name = domainname;
1342 tomoyo_fill_path_info(&name); 1289 tomoyo_fill_path_info(&name);
1343 down_write(&tomoyo_domain_list_lock); 1290 mutex_lock(&tomoyo_policy_lock);
1344 /* Is there an active domain? */ 1291 /* Is there an active domain? */
1345 list_for_each_entry(domain, &tomoyo_domain_list, list) { 1292 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
1346 /* Never delete tomoyo_kernel_domain */ 1293 /* Never delete tomoyo_kernel_domain */
1347 if (domain == &tomoyo_kernel_domain) 1294 if (domain == &tomoyo_kernel_domain)
1348 continue; 1295 continue;
@@ -1352,7 +1299,7 @@ static int tomoyo_delete_domain(char *domainname)
1352 domain->is_deleted = true; 1299 domain->is_deleted = true;
1353 break; 1300 break;
1354 } 1301 }
1355 up_write(&tomoyo_domain_list_lock); 1302 mutex_unlock(&tomoyo_policy_lock);
1356 return 0; 1303 return 0;
1357} 1304}
1358 1305
@@ -1362,6 +1309,8 @@ static int tomoyo_delete_domain(char *domainname)
1362 * @head: Pointer to "struct tomoyo_io_buffer". 1309 * @head: Pointer to "struct tomoyo_io_buffer".
1363 * 1310 *
1364 * Returns 0 on success, negative value otherwise. 1311 * Returns 0 on success, negative value otherwise.
1312 *
1313 * Caller holds tomoyo_read_lock().
1365 */ 1314 */
1366static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head) 1315static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
1367{ 1316{
@@ -1384,11 +1333,9 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
1384 domain = NULL; 1333 domain = NULL;
1385 if (is_delete) 1334 if (is_delete)
1386 tomoyo_delete_domain(data); 1335 tomoyo_delete_domain(data);
1387 else if (is_select) { 1336 else if (is_select)
1388 down_read(&tomoyo_domain_list_lock);
1389 domain = tomoyo_find_domain(data); 1337 domain = tomoyo_find_domain(data);
1390 up_read(&tomoyo_domain_list_lock); 1338 else
1391 } else
1392 domain = tomoyo_find_or_assign_new_domain(data, 0); 1339 domain = tomoyo_find_or_assign_new_domain(data, 0);
1393 head->write_var1 = domain; 1340 head->write_var1 = domain;
1394 return 0; 1341 return 0;
@@ -1403,43 +1350,39 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
1403 return 0; 1350 return 0;
1404 } 1351 }
1405 if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) { 1352 if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
1406 tomoyo_set_domain_flag(domain, is_delete, 1353 domain->ignore_global_allow_read = !is_delete;
1407 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ);
1408 return 0; 1354 return 0;
1409 } 1355 }
1410 return tomoyo_write_file_policy(data, domain, is_delete); 1356 return tomoyo_write_file_policy(data, domain, is_delete);
1411} 1357}
1412 1358
1413/** 1359/**
1414 * tomoyo_print_single_path_acl - Print a single path ACL entry. 1360 * tomoyo_print_path_acl - Print a single path ACL entry.
1415 * 1361 *
1416 * @head: Pointer to "struct tomoyo_io_buffer". 1362 * @head: Pointer to "struct tomoyo_io_buffer".
1417 * @ptr: Pointer to "struct tomoyo_single_path_acl_record". 1363 * @ptr: Pointer to "struct tomoyo_path_acl".
1418 * 1364 *
1419 * Returns true on success, false otherwise. 1365 * Returns true on success, false otherwise.
1420 */ 1366 */
1421static bool tomoyo_print_single_path_acl(struct tomoyo_io_buffer *head, 1367static bool tomoyo_print_path_acl(struct tomoyo_io_buffer *head,
1422 struct tomoyo_single_path_acl_record * 1368 struct tomoyo_path_acl *ptr)
1423 ptr)
1424{ 1369{
1425 int pos; 1370 int pos;
1426 u8 bit; 1371 u8 bit;
1427 const char *atmark = ""; 1372 const char *atmark = "";
1428 const char *filename; 1373 const char *filename;
1429 const u16 perm = ptr->perm; 1374 const u32 perm = ptr->perm | (((u32) ptr->perm_high) << 16);
1430 1375
1431 filename = ptr->filename->name; 1376 filename = ptr->filename->name;
1432 for (bit = head->read_bit; bit < TOMOYO_MAX_SINGLE_PATH_OPERATION; 1377 for (bit = head->read_bit; bit < TOMOYO_MAX_PATH_OPERATION; bit++) {
1433 bit++) {
1434 const char *msg; 1378 const char *msg;
1435 if (!(perm & (1 << bit))) 1379 if (!(perm & (1 << bit)))
1436 continue; 1380 continue;
1437 /* Print "read/write" instead of "read" and "write". */ 1381 /* Print "read/write" instead of "read" and "write". */
1438 if ((bit == TOMOYO_TYPE_READ_ACL || 1382 if ((bit == TOMOYO_TYPE_READ || bit == TOMOYO_TYPE_WRITE)
1439 bit == TOMOYO_TYPE_WRITE_ACL) 1383 && (perm & (1 << TOMOYO_TYPE_READ_WRITE)))
1440 && (perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)))
1441 continue; 1384 continue;
1442 msg = tomoyo_sp2keyword(bit); 1385 msg = tomoyo_path2keyword(bit);
1443 pos = head->read_avail; 1386 pos = head->read_avail;
1444 if (!tomoyo_io_printf(head, "allow_%s %s%s\n", msg, 1387 if (!tomoyo_io_printf(head, "allow_%s %s%s\n", msg,
1445 atmark, filename)) 1388 atmark, filename))
@@ -1454,16 +1397,15 @@ static bool tomoyo_print_single_path_acl(struct tomoyo_io_buffer *head,
1454} 1397}
1455 1398
1456/** 1399/**
1457 * tomoyo_print_double_path_acl - Print a double path ACL entry. 1400 * tomoyo_print_path2_acl - Print a double path ACL entry.
1458 * 1401 *
1459 * @head: Pointer to "struct tomoyo_io_buffer". 1402 * @head: Pointer to "struct tomoyo_io_buffer".
1460 * @ptr: Pointer to "struct tomoyo_double_path_acl_record". 1403 * @ptr: Pointer to "struct tomoyo_path2_acl".
1461 * 1404 *
1462 * Returns true on success, false otherwise. 1405 * Returns true on success, false otherwise.
1463 */ 1406 */
1464static bool tomoyo_print_double_path_acl(struct tomoyo_io_buffer *head, 1407static bool tomoyo_print_path2_acl(struct tomoyo_io_buffer *head,
1465 struct tomoyo_double_path_acl_record * 1408 struct tomoyo_path2_acl *ptr)
1466 ptr)
1467{ 1409{
1468 int pos; 1410 int pos;
1469 const char *atmark1 = ""; 1411 const char *atmark1 = "";
@@ -1475,12 +1417,11 @@ static bool tomoyo_print_double_path_acl(struct tomoyo_io_buffer *head,
1475 1417
1476 filename1 = ptr->filename1->name; 1418 filename1 = ptr->filename1->name;
1477 filename2 = ptr->filename2->name; 1419 filename2 = ptr->filename2->name;
1478 for (bit = head->read_bit; bit < TOMOYO_MAX_DOUBLE_PATH_OPERATION; 1420 for (bit = head->read_bit; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) {
1479 bit++) {
1480 const char *msg; 1421 const char *msg;
1481 if (!(perm & (1 << bit))) 1422 if (!(perm & (1 << bit)))
1482 continue; 1423 continue;
1483 msg = tomoyo_dp2keyword(bit); 1424 msg = tomoyo_path22keyword(bit);
1484 pos = head->read_avail; 1425 pos = head->read_avail;
1485 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,
1486 atmark1, filename1, atmark2, filename2)) 1427 atmark1, filename1, atmark2, filename2))
@@ -1505,23 +1446,17 @@ static bool tomoyo_print_double_path_acl(struct tomoyo_io_buffer *head,
1505static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, 1446static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
1506 struct tomoyo_acl_info *ptr) 1447 struct tomoyo_acl_info *ptr)
1507{ 1448{
1508 const u8 acl_type = tomoyo_acl_type2(ptr); 1449 const u8 acl_type = ptr->type;
1509 1450
1510 if (acl_type & TOMOYO_ACL_DELETED) 1451 if (acl_type == TOMOYO_TYPE_PATH_ACL) {
1511 return true; 1452 struct tomoyo_path_acl *acl
1512 if (acl_type == TOMOYO_TYPE_SINGLE_PATH_ACL) { 1453 = container_of(ptr, struct tomoyo_path_acl, head);
1513 struct tomoyo_single_path_acl_record *acl 1454 return tomoyo_print_path_acl(head, acl);
1514 = container_of(ptr,
1515 struct tomoyo_single_path_acl_record,
1516 head);
1517 return tomoyo_print_single_path_acl(head, acl);
1518 } 1455 }
1519 if (acl_type == TOMOYO_TYPE_DOUBLE_PATH_ACL) { 1456 if (acl_type == TOMOYO_TYPE_PATH2_ACL) {
1520 struct tomoyo_double_path_acl_record *acl 1457 struct tomoyo_path2_acl *acl
1521 = container_of(ptr, 1458 = container_of(ptr, struct tomoyo_path2_acl, head);
1522 struct tomoyo_double_path_acl_record, 1459 return tomoyo_print_path2_acl(head, acl);
1523 head);
1524 return tomoyo_print_double_path_acl(head, acl);
1525 } 1460 }
1526 BUG(); /* This must not happen. */ 1461 BUG(); /* This must not happen. */
1527 return false; 1462 return false;
@@ -1533,6 +1468,8 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
1533 * @head: Pointer to "struct tomoyo_io_buffer". 1468 * @head: Pointer to "struct tomoyo_io_buffer".
1534 * 1469 *
1535 * Returns 0. 1470 * Returns 0.
1471 *
1472 * Caller holds tomoyo_read_lock().
1536 */ 1473 */
1537static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head) 1474static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
1538{ 1475{
@@ -1544,7 +1481,6 @@ static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
1544 return 0; 1481 return 0;
1545 if (head->read_step == 0) 1482 if (head->read_step == 0)
1546 head->read_step = 1; 1483 head->read_step = 1;
1547 down_read(&tomoyo_domain_list_lock);
1548 list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) { 1484 list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) {
1549 struct tomoyo_domain_info *domain; 1485 struct tomoyo_domain_info *domain;
1550 const char *quota_exceeded = ""; 1486 const char *quota_exceeded = "";
@@ -1558,10 +1494,9 @@ static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
1558 /* Print domainname and flags. */ 1494 /* Print domainname and flags. */
1559 if (domain->quota_warned) 1495 if (domain->quota_warned)
1560 quota_exceeded = "quota_exceeded\n"; 1496 quota_exceeded = "quota_exceeded\n";
1561 if (domain->flags & TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED) 1497 if (domain->transition_failed)
1562 transition_failed = "transition_failed\n"; 1498 transition_failed = "transition_failed\n";
1563 if (domain->flags & 1499 if (domain->ignore_global_allow_read)
1564 TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ)
1565 ignore_global_allow_read 1500 ignore_global_allow_read
1566 = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n"; 1501 = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
1567 done = tomoyo_io_printf(head, "%s\n" TOMOYO_KEYWORD_USE_PROFILE 1502 done = tomoyo_io_printf(head, "%s\n" TOMOYO_KEYWORD_USE_PROFILE
@@ -1577,7 +1512,6 @@ acl_loop:
1577 if (head->read_step == 3) 1512 if (head->read_step == 3)
1578 goto tail_mark; 1513 goto tail_mark;
1579 /* Print ACL entries in the domain. */ 1514 /* Print ACL entries in the domain. */
1580 down_read(&tomoyo_domain_acl_info_list_lock);
1581 list_for_each_cookie(apos, head->read_var2, 1515 list_for_each_cookie(apos, head->read_var2,
1582 &domain->acl_info_list) { 1516 &domain->acl_info_list) {
1583 struct tomoyo_acl_info *ptr 1517 struct tomoyo_acl_info *ptr
@@ -1587,7 +1521,6 @@ acl_loop:
1587 if (!done) 1521 if (!done)
1588 break; 1522 break;
1589 } 1523 }
1590 up_read(&tomoyo_domain_acl_info_list_lock);
1591 if (!done) 1524 if (!done)
1592 break; 1525 break;
1593 head->read_step = 3; 1526 head->read_step = 3;
@@ -1599,7 +1532,6 @@ tail_mark:
1599 if (head->read_single_domain) 1532 if (head->read_single_domain)
1600 break; 1533 break;
1601 } 1534 }
1602 up_read(&tomoyo_domain_list_lock);
1603 head->read_eof = done; 1535 head->read_eof = done;
1604 return 0; 1536 return 0;
1605} 1537}
@@ -1615,6 +1547,8 @@ tail_mark:
1615 * 1547 *
1616 * ( echo "select " $domainname; echo "use_profile " $profile ) | 1548 * ( echo "select " $domainname; echo "use_profile " $profile ) |
1617 * /usr/lib/ccs/loadpolicy -d 1549 * /usr/lib/ccs/loadpolicy -d
1550 *
1551 * Caller holds tomoyo_read_lock().
1618 */ 1552 */
1619static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head) 1553static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
1620{ 1554{
@@ -1626,9 +1560,7 @@ static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
1626 if (!cp) 1560 if (!cp)
1627 return -EINVAL; 1561 return -EINVAL;
1628 *cp = '\0'; 1562 *cp = '\0';
1629 down_read(&tomoyo_domain_list_lock);
1630 domain = tomoyo_find_domain(cp + 1); 1563 domain = tomoyo_find_domain(cp + 1);
1631 up_read(&tomoyo_domain_list_lock);
1632 if (strict_strtoul(data, 10, &profile)) 1564 if (strict_strtoul(data, 10, &profile))
1633 return -EINVAL; 1565 return -EINVAL;
1634 if (domain && profile < TOMOYO_MAX_PROFILES 1566 if (domain && profile < TOMOYO_MAX_PROFILES
@@ -1650,6 +1582,8 @@ static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
1650 * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" ) 1582 * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" )
1651 * domainname = $0; } else if ( $1 == "use_profile" ) { 1583 * domainname = $0; } else if ( $1 == "use_profile" ) {
1652 * print $2 " " domainname; domainname = ""; } } ; ' 1584 * print $2 " " domainname; domainname = ""; } } ; '
1585 *
1586 * Caller holds tomoyo_read_lock().
1653 */ 1587 */
1654static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head) 1588static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
1655{ 1589{
@@ -1658,7 +1592,6 @@ static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
1658 1592
1659 if (head->read_eof) 1593 if (head->read_eof)
1660 return 0; 1594 return 0;
1661 down_read(&tomoyo_domain_list_lock);
1662 list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) { 1595 list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) {
1663 struct tomoyo_domain_info *domain; 1596 struct tomoyo_domain_info *domain;
1664 domain = list_entry(pos, struct tomoyo_domain_info, list); 1597 domain = list_entry(pos, struct tomoyo_domain_info, list);
@@ -1669,7 +1602,6 @@ static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
1669 if (!done) 1602 if (!done)
1670 break; 1603 break;
1671 } 1604 }
1672 up_read(&tomoyo_domain_list_lock);
1673 head->read_eof = done; 1605 head->read_eof = done;
1674 return 0; 1606 return 0;
1675} 1607}
@@ -1707,11 +1639,13 @@ static int tomoyo_read_pid(struct tomoyo_io_buffer *head)
1707 const int pid = head->read_step; 1639 const int pid = head->read_step;
1708 struct task_struct *p; 1640 struct task_struct *p;
1709 struct tomoyo_domain_info *domain = NULL; 1641 struct tomoyo_domain_info *domain = NULL;
1642 rcu_read_lock();
1710 read_lock(&tasklist_lock); 1643 read_lock(&tasklist_lock);
1711 p = find_task_by_vpid(pid); 1644 p = find_task_by_vpid(pid);
1712 if (p) 1645 if (p)
1713 domain = tomoyo_real_domain(p); 1646 domain = tomoyo_real_domain(p);
1714 read_unlock(&tasklist_lock); 1647 read_unlock(&tasklist_lock);
1648 rcu_read_unlock();
1715 if (domain) 1649 if (domain)
1716 tomoyo_io_printf(head, "%d %u %s", pid, domain->profile, 1650 tomoyo_io_printf(head, "%d %u %s", pid, domain->profile,
1717 domain->domainname->name); 1651 domain->domainname->name);
@@ -1726,6 +1660,8 @@ static int tomoyo_read_pid(struct tomoyo_io_buffer *head)
1726 * @head: Pointer to "struct tomoyo_io_buffer". 1660 * @head: Pointer to "struct tomoyo_io_buffer".
1727 * 1661 *
1728 * Returns 0 on success, negative value otherwise. 1662 * Returns 0 on success, negative value otherwise.
1663 *
1664 * Caller holds tomoyo_read_lock().
1729 */ 1665 */
1730static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) 1666static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head)
1731{ 1667{
@@ -1760,6 +1696,8 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head)
1760 * @head: Pointer to "struct tomoyo_io_buffer". 1696 * @head: Pointer to "struct tomoyo_io_buffer".
1761 * 1697 *
1762 * Returns 0 on success, -EINVAL otherwise. 1698 * Returns 0 on success, -EINVAL otherwise.
1699 *
1700 * Caller holds tomoyo_read_lock().
1763 */ 1701 */
1764static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head) 1702static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head)
1765{ 1703{
@@ -1889,15 +1827,13 @@ void tomoyo_load_policy(const char *filename)
1889 tomoyo_policy_loaded = true; 1827 tomoyo_policy_loaded = true;
1890 { /* Check all profiles currently assigned to domains are defined. */ 1828 { /* Check all profiles currently assigned to domains are defined. */
1891 struct tomoyo_domain_info *domain; 1829 struct tomoyo_domain_info *domain;
1892 down_read(&tomoyo_domain_list_lock); 1830 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
1893 list_for_each_entry(domain, &tomoyo_domain_list, list) {
1894 const u8 profile = domain->profile; 1831 const u8 profile = domain->profile;
1895 if (tomoyo_profile_ptr[profile]) 1832 if (tomoyo_profile_ptr[profile])
1896 continue; 1833 continue;
1897 panic("Profile %u (used by '%s') not defined.\n", 1834 panic("Profile %u (used by '%s') not defined.\n",
1898 profile, domain->domainname->name); 1835 profile, domain->domainname->name);
1899 } 1836 }
1900 up_read(&tomoyo_domain_list_lock);
1901 } 1837 }
1902} 1838}
1903 1839
@@ -1945,10 +1881,12 @@ static int tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
1945 * @file: Pointer to "struct file". 1881 * @file: Pointer to "struct file".
1946 * 1882 *
1947 * 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().
1948 */ 1886 */
1949static int tomoyo_open_control(const u8 type, struct file *file) 1887static int tomoyo_open_control(const u8 type, struct file *file)
1950{ 1888{
1951 struct tomoyo_io_buffer *head = tomoyo_alloc(sizeof(*head)); 1889 struct tomoyo_io_buffer *head = kzalloc(sizeof(*head), GFP_KERNEL);
1952 1890
1953 if (!head) 1891 if (!head)
1954 return -ENOMEM; 1892 return -ENOMEM;
@@ -2009,9 +1947,9 @@ static int tomoyo_open_control(const u8 type, struct file *file)
2009 } else { 1947 } else {
2010 if (!head->readbuf_size) 1948 if (!head->readbuf_size)
2011 head->readbuf_size = 4096 * 2; 1949 head->readbuf_size = 4096 * 2;
2012 head->read_buf = tomoyo_alloc(head->readbuf_size); 1950 head->read_buf = kzalloc(head->readbuf_size, GFP_KERNEL);
2013 if (!head->read_buf) { 1951 if (!head->read_buf) {
2014 tomoyo_free(head); 1952 kfree(head);
2015 return -ENOMEM; 1953 return -ENOMEM;
2016 } 1954 }
2017 } 1955 }
@@ -2023,13 +1961,14 @@ static int tomoyo_open_control(const u8 type, struct file *file)
2023 head->write = NULL; 1961 head->write = NULL;
2024 } else if (head->write) { 1962 } else if (head->write) {
2025 head->writebuf_size = 4096 * 2; 1963 head->writebuf_size = 4096 * 2;
2026 head->write_buf = tomoyo_alloc(head->writebuf_size); 1964 head->write_buf = kzalloc(head->writebuf_size, GFP_KERNEL);
2027 if (!head->write_buf) { 1965 if (!head->write_buf) {
2028 tomoyo_free(head->read_buf); 1966 kfree(head->read_buf);
2029 tomoyo_free(head); 1967 kfree(head);
2030 return -ENOMEM; 1968 return -ENOMEM;
2031 } 1969 }
2032 } 1970 }
1971 head->reader_idx = tomoyo_read_lock();
2033 file->private_data = head; 1972 file->private_data = head;
2034 /* 1973 /*
2035 * Call the handler now if the file is 1974 * Call the handler now if the file is
@@ -2051,6 +1990,8 @@ static int tomoyo_open_control(const u8 type, struct file *file)
2051 * @buffer_len: Size of @buffer. 1990 * @buffer_len: Size of @buffer.
2052 * 1991 *
2053 * Returns bytes read on success, negative value otherwise. 1992 * Returns bytes read on success, negative value otherwise.
1993 *
1994 * Caller holds tomoyo_read_lock().
2054 */ 1995 */
2055static int tomoyo_read_control(struct file *file, char __user *buffer, 1996static int tomoyo_read_control(struct file *file, char __user *buffer,
2056 const int buffer_len) 1997 const int buffer_len)
@@ -2094,6 +2035,8 @@ static int tomoyo_read_control(struct file *file, char __user *buffer,
2094 * @buffer_len: Size of @buffer. 2035 * @buffer_len: Size of @buffer.
2095 * 2036 *
2096 * Returns @buffer_len on success, negative value otherwise. 2037 * Returns @buffer_len on success, negative value otherwise.
2038 *
2039 * Caller holds tomoyo_read_lock().
2097 */ 2040 */
2098static int tomoyo_write_control(struct file *file, const char __user *buffer, 2041static int tomoyo_write_control(struct file *file, const char __user *buffer,
2099 const int buffer_len) 2042 const int buffer_len)
@@ -2144,52 +2087,29 @@ static int tomoyo_write_control(struct file *file, const char __user *buffer,
2144 * @file: Pointer to "struct file". 2087 * @file: Pointer to "struct file".
2145 * 2088 *
2146 * Releases memory and returns 0. 2089 * Releases memory and returns 0.
2090 *
2091 * Caller looses tomoyo_read_lock().
2147 */ 2092 */
2148static int tomoyo_close_control(struct file *file) 2093static int tomoyo_close_control(struct file *file)
2149{ 2094{
2150 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;
2151 2097
2098 tomoyo_read_unlock(head->reader_idx);
2152 /* Release memory used for policy I/O. */ 2099 /* Release memory used for policy I/O. */
2153 tomoyo_free(head->read_buf); 2100 kfree(head->read_buf);
2154 head->read_buf = NULL; 2101 head->read_buf = NULL;
2155 tomoyo_free(head->write_buf); 2102 kfree(head->write_buf);
2156 head->write_buf = NULL; 2103 head->write_buf = NULL;
2157 tomoyo_free(head); 2104 kfree(head);
2158 head = NULL; 2105 head = NULL;
2159 file->private_data = NULL; 2106 file->private_data = NULL;
2107 if (is_write)
2108 tomoyo_run_gc();
2160 return 0; 2109 return 0;
2161} 2110}
2162 2111
2163/** 2112/**
2164 * tomoyo_alloc_acl_element - Allocate permanent memory for ACL entry.
2165 *
2166 * @acl_type: Type of ACL entry.
2167 *
2168 * Returns pointer to the ACL entry on success, NULL otherwise.
2169 */
2170void *tomoyo_alloc_acl_element(const u8 acl_type)
2171{
2172 int len;
2173 struct tomoyo_acl_info *ptr;
2174
2175 switch (acl_type) {
2176 case TOMOYO_TYPE_SINGLE_PATH_ACL:
2177 len = sizeof(struct tomoyo_single_path_acl_record);
2178 break;
2179 case TOMOYO_TYPE_DOUBLE_PATH_ACL:
2180 len = sizeof(struct tomoyo_double_path_acl_record);
2181 break;
2182 default:
2183 return NULL;
2184 }
2185 ptr = tomoyo_alloc_element(len);
2186 if (!ptr)
2187 return NULL;
2188 ptr->type = acl_type;
2189 return ptr;
2190}
2191
2192/**
2193 * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface. 2113 * tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface.
2194 * 2114 *
2195 * @inode: Pointer to "struct inode". 2115 * @inode: Pointer to "struct inode".
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 92169d29b2d..67bd22dd3e6 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
@@ -66,13 +173,14 @@ struct tomoyo_path_info {
66}; 173};
67 174
68/* 175/*
69 * This is the max length of a token. 176 * tomoyo_name_entry is a structure which is used for linking
70 * 177 * "struct tomoyo_path_info" into tomoyo_name_list .
71 * A token consists of only ASCII printable characters.
72 * Non printable characters in a token is represented in \ooo style
73 * octal string. Thus, \ itself is represented as \\.
74 */ 178 */
75#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};
76 184
77/* 185/*
78 * 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
@@ -89,7 +197,7 @@ struct tomoyo_path_info {
89 * "struct tomoyo_path_info_with_data". 197 * "struct tomoyo_path_info_with_data".
90 */ 198 */
91struct tomoyo_path_info_with_data { 199struct tomoyo_path_info_with_data {
92 /* Keep "head" first, for this pointer is passed to tomoyo_free(). */ 200 /* Keep "head" first, for this pointer is passed to kfree(). */
93 struct tomoyo_path_info head; 201 struct tomoyo_path_info head;
94 char barrier1[16]; /* Safeguard for overrun. */ 202 char barrier1[16]; /* Safeguard for overrun. */
95 char body[TOMOYO_MAX_PATHNAME_LEN]; 203 char body[TOMOYO_MAX_PATHNAME_LEN];
@@ -101,30 +209,19 @@ struct tomoyo_path_info_with_data {
101 * 209 *
102 * (1) "list" which is linked to the ->acl_info_list of 210 * (1) "list" which is linked to the ->acl_info_list of
103 * "struct tomoyo_domain_info" 211 * "struct tomoyo_domain_info"
104 * (2) "type" which tells 212 * (2) "type" which tells type of the entry (either
105 * (a) type & 0x7F : type of the entry (either 213 * "struct tomoyo_path_acl" or "struct tomoyo_path2_acl").
106 * "struct tomoyo_single_path_acl_record" or
107 * "struct tomoyo_double_path_acl_record")
108 * (b) type & 0x80 : whether the entry is marked as "deleted".
109 * 214 *
110 * Packing "struct tomoyo_acl_info" allows 215 * Packing "struct tomoyo_acl_info" allows
111 * "struct tomoyo_single_path_acl_record" to embed "u16" and 216 * "struct tomoyo_path_acl" to embed "u8" + "u16" and
112 * "struct tomoyo_double_path_acl_record" to embed "u8" 217 * "struct tomoyo_path2_acl" to embed "u8"
113 * without enlarging their structure size. 218 * without enlarging their structure size.
114 */ 219 */
115struct tomoyo_acl_info { 220struct tomoyo_acl_info {
116 struct list_head list; 221 struct list_head list;
117 /*
118 * Type of this ACL entry.
119 *
120 * MSB is is_deleted flag.
121 */
122 u8 type; 222 u8 type;
123} __packed; 223} __packed;
124 224
125/* This ACL entry is deleted. */
126#define TOMOYO_ACL_DELETED 0x80
127
128/* 225/*
129 * 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
130 * (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.
@@ -138,7 +235,17 @@ struct tomoyo_acl_info {
138 * "deleted", false otherwise. 235 * "deleted", false otherwise.
139 * (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
140 * when learning mode learned too much entries. 237 * when learning mode learned too much entries.
141 * (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.
142 * 249 *
143 * A domain's lifecycle is an analogy of files on / directory. 250 * A domain's lifecycle is an analogy of files on / directory.
144 * Multiple domains with the same domainname cannot be created (as with 251 * Multiple domains with the same domainname cannot be created (as with
@@ -155,25 +262,13 @@ struct tomoyo_domain_info {
155 u8 profile; /* Profile number to use. */ 262 u8 profile; /* Profile number to use. */
156 bool is_deleted; /* Delete flag. */ 263 bool is_deleted; /* Delete flag. */
157 bool quota_warned; /* Quota warnning flag. */ 264 bool quota_warned; /* Quota warnning flag. */
158 /* DOMAIN_FLAGS_*. Use tomoyo_set_domain_flag() to modify. */ 265 bool ignore_global_allow_read; /* Ignore "allow_read" flag. */
159 u8 flags; 266 bool transition_failed; /* Domain transition failed flag. */
267 atomic_t users; /* Number of referring credentials. */
160}; 268};
161 269
162/* Profile number is an integer between 0 and 255. */
163#define TOMOYO_MAX_PROFILES 256
164
165/* Ignore "allow_read" directive in exception policy. */
166#define TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ 1
167/*
168 * This domain was unable to create a new domain at tomoyo_find_next_domain()
169 * because the name of the domain to be created was too long or
170 * it could not allocate memory.
171 * More than one process continued execve() without domain transition.
172 */
173#define TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED 2
174
175/* 270/*
176 * 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
177 * entry with one pathname operation (e.g. open(), mkdir()). 272 * entry with one pathname operation (e.g. open(), mkdir()).
178 * It has following fields. 273 * It has following fields.
179 * 274 *
@@ -184,18 +279,21 @@ struct tomoyo_domain_info {
184 * Directives held by this structure are "allow_read/write", "allow_execute", 279 * Directives held by this structure are "allow_read/write", "allow_execute",
185 * "allow_read", "allow_write", "allow_create", "allow_unlink", "allow_mkdir", 280 * "allow_read", "allow_write", "allow_create", "allow_unlink", "allow_mkdir",
186 * "allow_rmdir", "allow_mkfifo", "allow_mksock", "allow_mkblock", 281 * "allow_rmdir", "allow_mkfifo", "allow_mksock", "allow_mkblock",
187 * "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".
188 */ 285 */
189struct tomoyo_single_path_acl_record { 286struct tomoyo_path_acl {
190 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;
191 u16 perm; 289 u16 perm;
192 /* Pointer to single pathname. */ 290 /* Pointer to single pathname. */
193 const struct tomoyo_path_info *filename; 291 const struct tomoyo_path_info *filename;
194}; 292};
195 293
196/* 294/*
197 * 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
198 * entry with two pathnames operation (i.e. link() and rename()). 296 * entry with two pathnames operation (i.e. link(), rename() and pivot_root()).
199 * It has following fields. 297 * It has following fields.
200 * 298 *
201 * (1) "head" which is a "struct tomoyo_acl_info". 299 * (1) "head" which is a "struct tomoyo_acl_info".
@@ -203,10 +301,11 @@ struct tomoyo_single_path_acl_record {
203 * (3) "filename1" is the source/old pathname. 301 * (3) "filename1" is the source/old pathname.
204 * (4) "filename2" is the destination/new pathname. 302 * (4) "filename2" is the destination/new pathname.
205 * 303 *
206 * 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".
207 */ 306 */
208struct tomoyo_double_path_acl_record { 307struct tomoyo_path2_acl {
209 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_DOUBLE_PATH_ACL */ 308 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH2_ACL */
210 u8 perm; 309 u8 perm;
211 /* Pointer to single pathname. */ 310 /* Pointer to single pathname. */
212 const struct tomoyo_path_info *filename1; 311 const struct tomoyo_path_info *filename1;
@@ -214,29 +313,6 @@ struct tomoyo_double_path_acl_record {
214 const struct tomoyo_path_info *filename2; 313 const struct tomoyo_path_info *filename2;
215}; 314};
216 315
217/* Keywords for ACLs. */
218#define TOMOYO_KEYWORD_ALIAS "alias "
219#define TOMOYO_KEYWORD_ALLOW_READ "allow_read "
220#define TOMOYO_KEYWORD_DELETE "delete "
221#define TOMOYO_KEYWORD_DENY_REWRITE "deny_rewrite "
222#define TOMOYO_KEYWORD_FILE_PATTERN "file_pattern "
223#define TOMOYO_KEYWORD_INITIALIZE_DOMAIN "initialize_domain "
224#define TOMOYO_KEYWORD_KEEP_DOMAIN "keep_domain "
225#define TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN "no_initialize_domain "
226#define TOMOYO_KEYWORD_NO_KEEP_DOMAIN "no_keep_domain "
227#define TOMOYO_KEYWORD_SELECT "select "
228#define TOMOYO_KEYWORD_USE_PROFILE "use_profile "
229#define TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "ignore_global_allow_read"
230/* A domain definition starts with <kernel>. */
231#define TOMOYO_ROOT_NAME "<kernel>"
232#define TOMOYO_ROOT_NAME_LEN (sizeof(TOMOYO_ROOT_NAME) - 1)
233
234/* Index numbers for Access Controls. */
235#define TOMOYO_MAC_FOR_FILE 0 /* domain_policy.conf */
236#define TOMOYO_MAX_ACCEPT_ENTRY 1
237#define TOMOYO_VERBOSE 2
238#define TOMOYO_MAX_CONTROL_INDEX 3
239
240/* 316/*
241 * 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
242 * configuration via /sys/kernel/security/tomoyo/ interface. 318 * configuration via /sys/kernel/security/tomoyo/ interface.
@@ -265,6 +341,8 @@ struct tomoyo_io_buffer {
265 int (*write) (struct tomoyo_io_buffer *); 341 int (*write) (struct tomoyo_io_buffer *);
266 /* Exclusive lock for this structure. */ 342 /* Exclusive lock for this structure. */
267 struct mutex io_sem; 343 struct mutex io_sem;
344 /* Index returned by tomoyo_read_lock(). */
345 int reader_idx;
268 /* The position currently reading from. */ 346 /* The position currently reading from. */
269 struct list_head *read_var1; 347 struct list_head *read_var1;
270 /* Extra variables for reading. */ 348 /* Extra variables for reading. */
@@ -293,18 +371,159 @@ struct tomoyo_io_buffer {
293 int writebuf_size; 371 int writebuf_size;
294}; 372};
295 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
296/* Check whether the domain has too many ACL entries to hold. */ 517/* Check whether the domain has too many ACL entries to hold. */
297bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain); 518bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain);
298/* Transactional sprintf() for policy dump. */ 519/* Transactional sprintf() for policy dump. */
299bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 520bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
300 __attribute__ ((format(printf, 2, 3))); 521 __attribute__ ((format(printf, 2, 3)));
301/* Check whether the domainname is correct. */ 522/* Check whether the domainname is correct. */
302bool tomoyo_is_correct_domain(const unsigned char *domainname, 523bool tomoyo_is_correct_domain(const unsigned char *domainname);
303 const char *function);
304/* Check whether the token is correct. */ 524/* Check whether the token is correct. */
305bool tomoyo_is_correct_path(const char *filename, const s8 start_type, 525bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
306 const s8 pattern_type, const s8 end_type, 526 const s8 pattern_type, const s8 end_type);
307 const char *function);
308/* Check whether the token can be a domainname. */ 527/* Check whether the token can be a domainname. */
309bool tomoyo_is_domain_def(const unsigned char *buffer); 528bool tomoyo_is_domain_def(const unsigned char *buffer);
310/* Check whether the given filename matches the given pattern. */ 529/* Check whether the given filename matches the given pattern. */
@@ -328,13 +547,13 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head);
328/* Write domain policy violation warning message to console? */ 547/* Write domain policy violation warning message to console? */
329bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain); 548bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain);
330/* Convert double path operation to operation name. */ 549/* Convert double path operation to operation name. */
331const char *tomoyo_dp2keyword(const u8 operation); 550const char *tomoyo_path22keyword(const u8 operation);
332/* Get the last component of the given domainname. */ 551/* Get the last component of the given domainname. */
333const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain); 552const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain);
334/* Get warning message. */ 553/* Get warning message. */
335const char *tomoyo_get_msg(const bool is_enforce); 554const char *tomoyo_get_msg(const bool is_enforce);
336/* Convert single path operation to operation name. */ 555/* Convert single path operation to operation name. */
337const char *tomoyo_sp2keyword(const u8 operation); 556const char *tomoyo_path2keyword(const u8 operation);
338/* Create "alias" entry in exception policy. */ 557/* Create "alias" entry in exception policy. */
339int tomoyo_write_alias_policy(char *data, const bool is_delete); 558int tomoyo_write_alias_policy(char *data, const bool is_delete);
340/* 559/*
@@ -370,33 +589,107 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
370/* Check mode for specified functionality. */ 589/* Check mode for specified functionality. */
371unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain, 590unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
372 const u8 index); 591 const u8 index);
373/* Allocate memory for structures. */
374void *tomoyo_alloc_acl_element(const u8 acl_type);
375/* Fill in "struct tomoyo_path_info" members. */ 592/* Fill in "struct tomoyo_path_info" members. */
376void tomoyo_fill_path_info(struct tomoyo_path_info *ptr); 593void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
377/* Run policy loader when /sbin/init starts. */ 594/* Run policy loader when /sbin/init starts. */
378void tomoyo_load_policy(const char *filename); 595void tomoyo_load_policy(const char *filename);
379/* Change "struct tomoyo_domain_info"->flags. */
380void tomoyo_set_domain_flag(struct tomoyo_domain_info *domain,
381 const bool is_delete, const u8 flags);
382 596
383/* strcmp() for "struct tomoyo_path_info" structure. */ 597/* Convert binary string to ascii string. */
384static inline bool tomoyo_pathcmp(const struct tomoyo_path_info *a, 598int tomoyo_encode(char *buffer, int buflen, const char *str);
385 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)
386{ 679{
387 return a->hash != b->hash || strcmp(a->name, b->name); 680 return srcu_read_lock(&tomoyo_ss);
388} 681}
389 682
390/* Get type of an ACL entry. */ 683static inline void tomoyo_read_unlock(int idx)
391static inline u8 tomoyo_acl_type1(struct tomoyo_acl_info *ptr)
392{ 684{
393 return ptr->type & ~TOMOYO_ACL_DELETED; 685 srcu_read_unlock(&tomoyo_ss, idx);
394} 686}
395 687
396/* Get type of an ACL entry. */ 688/* strcmp() for "struct tomoyo_path_info" structure. */
397static 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)
398{ 691{
399 return ptr->type; 692 return a->hash != b->hash || strcmp(a->name, b->name);
400} 693}
401 694
402/** 695/**
@@ -423,18 +716,25 @@ static inline bool tomoyo_is_invalid(const unsigned char c)
423 return c && (c <= ' ' || c >= 127); 716 return c && (c <= ' ' || c >= 127);
424} 717}
425 718
426/* The list for "struct tomoyo_domain_info". */ 719static inline void tomoyo_put_name(const struct tomoyo_path_info *name)
427extern struct list_head tomoyo_domain_list; 720{
428extern struct rw_semaphore tomoyo_domain_list_lock; 721 if (name) {
429 722 struct tomoyo_name_entry *ptr =
430/* Lock for domain->acl_info_list. */ 723 container_of(name, struct tomoyo_name_entry, entry);
431extern struct rw_semaphore tomoyo_domain_acl_info_list_lock; 724 atomic_dec(&ptr->users);
725 }
726}
432 727
433/* Has /sbin/init started? */ 728static inline struct tomoyo_domain_info *tomoyo_domain(void)
434extern bool tomoyo_policy_loaded; 729{
730 return current_cred()->security;
731}
435 732
436/* The kernel's domain. */ 733static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
437extern struct tomoyo_domain_info tomoyo_kernel_domain; 734 *task)
735{
736 return task_cred_xxx(task, security);
737}
438 738
439/** 739/**
440 * list_for_each_cookie - iterate over a list with cookie. 740 * list_for_each_cookie - iterate over a list with cookie.
@@ -442,16 +742,16 @@ extern struct tomoyo_domain_info tomoyo_kernel_domain;
442 * @cookie: the &struct list_head to use as a cookie. 742 * @cookie: the &struct list_head to use as a cookie.
443 * @head: the head for your list. 743 * @head: the head for your list.
444 * 744 *
445 * Same with list_for_each() except that this primitive uses @cookie 745 * Same with list_for_each_rcu() except that this primitive uses @cookie
446 * so that we can continue iteration. 746 * so that we can continue iteration.
447 * @cookie must be NULL when iteration starts, and @cookie will become 747 * @cookie must be NULL when iteration starts, and @cookie will become
448 * NULL when iteration finishes. 748 * NULL when iteration finishes.
449 */ 749 */
450#define list_for_each_cookie(pos, cookie, head) \ 750#define list_for_each_cookie(pos, cookie, head) \
451 for (({ if (!cookie) \ 751 for (({ if (!cookie) \
452 cookie = head; }), \ 752 cookie = head; }), \
453 pos = (cookie)->next; \ 753 pos = rcu_dereference((cookie)->next); \
454 prefetch(pos->next), pos != (head) || ((cookie) = NULL); \ 754 prefetch(pos->next), pos != (head) || ((cookie) = NULL); \
455 (cookie) = pos, pos = pos->next) 755 (cookie) = pos, pos = rcu_dereference(pos->next))
456 756
457#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 fcf52accce2..acb8c397d5c 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 9a6c58881c0..6f3fe76a1fd 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -10,108 +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
16/*
17 * tomoyo_globally_readable_file_entry is a structure which is used for holding
18 * "allow_read" entries.
19 * It has following fields.
20 *
21 * (1) "list" which is linked to tomoyo_globally_readable_list .
22 * (2) "filename" is a pathname which is allowed to open(O_RDONLY).
23 * (3) "is_deleted" is a bool which is true if marked as deleted, false
24 * otherwise.
25 */
26struct tomoyo_globally_readable_file_entry {
27 struct list_head list;
28 const struct tomoyo_path_info *filename;
29 bool is_deleted;
30};
31
32/*
33 * tomoyo_pattern_entry is a structure which is used for holding
34 * "tomoyo_pattern_list" entries.
35 * It has following fields.
36 *
37 * (1) "list" which is linked to tomoyo_pattern_list .
38 * (2) "pattern" is a pathname pattern which is used for converting pathnames
39 * to pathname patterns during learning mode.
40 * (3) "is_deleted" is a bool which is true if marked as deleted, false
41 * otherwise.
42 */
43struct tomoyo_pattern_entry {
44 struct list_head list;
45 const struct tomoyo_path_info *pattern;
46 bool is_deleted;
47};
48
49/*
50 * tomoyo_no_rewrite_entry is a structure which is used for holding
51 * "deny_rewrite" entries.
52 * It has following fields.
53 *
54 * (1) "list" which is linked to tomoyo_no_rewrite_list .
55 * (2) "pattern" is a pathname which is by default not permitted to modify
56 * already existing content.
57 * (3) "is_deleted" is a bool which is true if marked as deleted, false
58 * otherwise.
59 */
60struct tomoyo_no_rewrite_entry {
61 struct list_head list;
62 const struct tomoyo_path_info *pattern;
63 bool is_deleted;
64};
65 14
66/* Keyword array for single path operations. */ 15/* Keyword array for single path operations. */
67static const char *tomoyo_sp_keyword[TOMOYO_MAX_SINGLE_PATH_OPERATION] = { 16static const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = {
68 [TOMOYO_TYPE_READ_WRITE_ACL] = "read/write", 17 [TOMOYO_TYPE_READ_WRITE] = "read/write",
69 [TOMOYO_TYPE_EXECUTE_ACL] = "execute", 18 [TOMOYO_TYPE_EXECUTE] = "execute",
70 [TOMOYO_TYPE_READ_ACL] = "read", 19 [TOMOYO_TYPE_READ] = "read",
71 [TOMOYO_TYPE_WRITE_ACL] = "write", 20 [TOMOYO_TYPE_WRITE] = "write",
72 [TOMOYO_TYPE_CREATE_ACL] = "create", 21 [TOMOYO_TYPE_CREATE] = "create",
73 [TOMOYO_TYPE_UNLINK_ACL] = "unlink", 22 [TOMOYO_TYPE_UNLINK] = "unlink",
74 [TOMOYO_TYPE_MKDIR_ACL] = "mkdir", 23 [TOMOYO_TYPE_MKDIR] = "mkdir",
75 [TOMOYO_TYPE_RMDIR_ACL] = "rmdir", 24 [TOMOYO_TYPE_RMDIR] = "rmdir",
76 [TOMOYO_TYPE_MKFIFO_ACL] = "mkfifo", 25 [TOMOYO_TYPE_MKFIFO] = "mkfifo",
77 [TOMOYO_TYPE_MKSOCK_ACL] = "mksock", 26 [TOMOYO_TYPE_MKSOCK] = "mksock",
78 [TOMOYO_TYPE_MKBLOCK_ACL] = "mkblock", 27 [TOMOYO_TYPE_MKBLOCK] = "mkblock",
79 [TOMOYO_TYPE_MKCHAR_ACL] = "mkchar", 28 [TOMOYO_TYPE_MKCHAR] = "mkchar",
80 [TOMOYO_TYPE_TRUNCATE_ACL] = "truncate", 29 [TOMOYO_TYPE_TRUNCATE] = "truncate",
81 [TOMOYO_TYPE_SYMLINK_ACL] = "symlink", 30 [TOMOYO_TYPE_SYMLINK] = "symlink",
82 [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",
83}; 39};
84 40
85/* Keyword array for double path operations. */ 41/* Keyword array for double path operations. */
86static const char *tomoyo_dp_keyword[TOMOYO_MAX_DOUBLE_PATH_OPERATION] = { 42static const char *tomoyo_path2_keyword[TOMOYO_MAX_PATH2_OPERATION] = {
87 [TOMOYO_TYPE_LINK_ACL] = "link", 43 [TOMOYO_TYPE_LINK] = "link",
88 [TOMOYO_TYPE_RENAME_ACL] = "rename", 44 [TOMOYO_TYPE_RENAME] = "rename",
45 [TOMOYO_TYPE_PIVOT_ROOT] = "pivot_root",
89}; 46};
90 47
91/** 48/**
92 * tomoyo_sp2keyword - Get the name of single path operation. 49 * tomoyo_path2keyword - Get the name of single path operation.
93 * 50 *
94 * @operation: Type of operation. 51 * @operation: Type of operation.
95 * 52 *
96 * Returns the name of single path operation. 53 * Returns the name of single path operation.
97 */ 54 */
98const char *tomoyo_sp2keyword(const u8 operation) 55const char *tomoyo_path2keyword(const u8 operation)
99{ 56{
100 return (operation < TOMOYO_MAX_SINGLE_PATH_OPERATION) 57 return (operation < TOMOYO_MAX_PATH_OPERATION)
101 ? tomoyo_sp_keyword[operation] : NULL; 58 ? tomoyo_path_keyword[operation] : NULL;
102} 59}
103 60
104/** 61/**
105 * tomoyo_dp2keyword - Get the name of double path operation. 62 * tomoyo_path22keyword - Get the name of double path operation.
106 * 63 *
107 * @operation: Type of operation. 64 * @operation: Type of operation.
108 * 65 *
109 * Returns the name of double path operation. 66 * Returns the name of double path operation.
110 */ 67 */
111const char *tomoyo_dp2keyword(const u8 operation) 68const char *tomoyo_path22keyword(const u8 operation)
112{ 69{
113 return (operation < TOMOYO_MAX_DOUBLE_PATH_OPERATION) 70 return (operation < TOMOYO_MAX_PATH2_OPERATION)
114 ? tomoyo_dp_keyword[operation] : NULL; 71 ? tomoyo_path2_keyword[operation] : NULL;
115} 72}
116 73
117/** 74/**
@@ -142,7 +99,8 @@ static bool tomoyo_strendswith(const char *name, const char *tail)
142static struct tomoyo_path_info *tomoyo_get_path(struct path *path) 99static struct tomoyo_path_info *tomoyo_get_path(struct path *path)
143{ 100{
144 int error; 101 int error;
145 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);
146 104
147 if (!buf) 105 if (!buf)
148 return NULL; 106 return NULL;
@@ -154,20 +112,17 @@ static struct tomoyo_path_info *tomoyo_get_path(struct path *path)
154 tomoyo_fill_path_info(&buf->head); 112 tomoyo_fill_path_info(&buf->head);
155 return &buf->head; 113 return &buf->head;
156 } 114 }
157 tomoyo_free(buf); 115 kfree(buf);
158 return NULL; 116 return NULL;
159} 117}
160 118
161/* Lock for domain->acl_info_list. */ 119static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
162DECLARE_RWSEM(tomoyo_domain_acl_info_list_lock); 120 const char *filename2,
163 121 struct tomoyo_domain_info *const domain,
164static int tomoyo_update_double_path_acl(const u8 type, const char *filename1, 122 const bool is_delete);
165 const char *filename2, 123static int tomoyo_update_path_acl(const u8 type, const char *filename,
166 struct tomoyo_domain_info * 124 struct tomoyo_domain_info *const domain,
167 const domain, const bool is_delete); 125 const bool is_delete);
168static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
169 struct tomoyo_domain_info *
170 const domain, const bool is_delete);
171 126
172/* 127/*
173 * 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
@@ -194,8 +149,7 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
194 * 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
195 * belongs to. 150 * belongs to.
196 */ 151 */
197static LIST_HEAD(tomoyo_globally_readable_list); 152LIST_HEAD(tomoyo_globally_readable_list);
198static DECLARE_RWSEM(tomoyo_globally_readable_list_lock);
199 153
200/** 154/**
201 * 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.
@@ -204,40 +158,42 @@ static DECLARE_RWSEM(tomoyo_globally_readable_list_lock);
204 * @is_delete: True if it is a delete request. 158 * @is_delete: True if it is a delete request.
205 * 159 *
206 * Returns 0 on success, negative value otherwise. 160 * Returns 0 on success, negative value otherwise.
161 *
162 * Caller holds tomoyo_read_lock().
207 */ 163 */
208static int tomoyo_update_globally_readable_entry(const char *filename, 164static int tomoyo_update_globally_readable_entry(const char *filename,
209 const bool is_delete) 165 const bool is_delete)
210{ 166{
211 struct tomoyo_globally_readable_file_entry *new_entry; 167 struct tomoyo_globally_readable_file_entry *entry = NULL;
212 struct tomoyo_globally_readable_file_entry *ptr; 168 struct tomoyo_globally_readable_file_entry *ptr;
213 const struct tomoyo_path_info *saved_filename; 169 const struct tomoyo_path_info *saved_filename;
214 int error = -ENOMEM; 170 int error = is_delete ? -ENOENT : -ENOMEM;
215 171
216 if (!tomoyo_is_correct_path(filename, 1, 0, -1, __func__)) 172 if (!tomoyo_is_correct_path(filename, 1, 0, -1))
217 return -EINVAL; 173 return -EINVAL;
218 saved_filename = tomoyo_save_name(filename); 174 saved_filename = tomoyo_get_name(filename);
219 if (!saved_filename) 175 if (!saved_filename)
220 return -ENOMEM; 176 return -ENOMEM;
221 down_write(&tomoyo_globally_readable_list_lock); 177 if (!is_delete)
222 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) {
223 if (ptr->filename != saved_filename) 181 if (ptr->filename != saved_filename)
224 continue; 182 continue;
225 ptr->is_deleted = is_delete; 183 ptr->is_deleted = is_delete;
226 error = 0; 184 error = 0;
227 goto out; 185 break;
228 } 186 }
229 if (is_delete) { 187 if (!is_delete && error && tomoyo_memory_ok(entry)) {
230 error = -ENOENT; 188 entry->filename = saved_filename;
231 goto out; 189 saved_filename = NULL;
190 list_add_tail_rcu(&entry->list, &tomoyo_globally_readable_list);
191 entry = NULL;
192 error = 0;
232 } 193 }
233 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 194 mutex_unlock(&tomoyo_policy_lock);
234 if (!new_entry) 195 tomoyo_put_name(saved_filename);
235 goto out; 196 kfree(entry);
236 new_entry->filename = saved_filename;
237 list_add_tail(&new_entry->list, &tomoyo_globally_readable_list);
238 error = 0;
239 out:
240 up_write(&tomoyo_globally_readable_list_lock);
241 return error; 197 return error;
242} 198}
243 199
@@ -247,21 +203,22 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
247 * @filename: The filename to check. 203 * @filename: The filename to check.
248 * 204 *
249 * 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().
250 */ 208 */
251static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info * 209static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info *
252 filename) 210 filename)
253{ 211{
254 struct tomoyo_globally_readable_file_entry *ptr; 212 struct tomoyo_globally_readable_file_entry *ptr;
255 bool found = false; 213 bool found = false;
256 down_read(&tomoyo_globally_readable_list_lock); 214
257 list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) { 215 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
258 if (!ptr->is_deleted && 216 if (!ptr->is_deleted &&
259 tomoyo_path_matches_pattern(filename, ptr->filename)) { 217 tomoyo_path_matches_pattern(filename, ptr->filename)) {
260 found = true; 218 found = true;
261 break; 219 break;
262 } 220 }
263 } 221 }
264 up_read(&tomoyo_globally_readable_list_lock);
265 return found; 222 return found;
266} 223}
267 224
@@ -272,6 +229,8 @@ static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info *
272 * @is_delete: True if it is a delete request. 229 * @is_delete: True if it is a delete request.
273 * 230 *
274 * Returns 0 on success, negative value otherwise. 231 * Returns 0 on success, negative value otherwise.
232 *
233 * Caller holds tomoyo_read_lock().
275 */ 234 */
276int tomoyo_write_globally_readable_policy(char *data, const bool is_delete) 235int tomoyo_write_globally_readable_policy(char *data, const bool is_delete)
277{ 236{
@@ -284,13 +243,14 @@ int tomoyo_write_globally_readable_policy(char *data, const bool is_delete)
284 * @head: Pointer to "struct tomoyo_io_buffer". 243 * @head: Pointer to "struct tomoyo_io_buffer".
285 * 244 *
286 * Returns true on success, false otherwise. 245 * Returns true on success, false otherwise.
246 *
247 * Caller holds tomoyo_read_lock().
287 */ 248 */
288bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head) 249bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
289{ 250{
290 struct list_head *pos; 251 struct list_head *pos;
291 bool done = true; 252 bool done = true;
292 253
293 down_read(&tomoyo_globally_readable_list_lock);
294 list_for_each_cookie(pos, head->read_var2, 254 list_for_each_cookie(pos, head->read_var2,
295 &tomoyo_globally_readable_list) { 255 &tomoyo_globally_readable_list) {
296 struct tomoyo_globally_readable_file_entry *ptr; 256 struct tomoyo_globally_readable_file_entry *ptr;
@@ -304,7 +264,6 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
304 if (!done) 264 if (!done)
305 break; 265 break;
306 } 266 }
307 up_read(&tomoyo_globally_readable_list_lock);
308 return done; 267 return done;
309} 268}
310 269
@@ -337,8 +296,7 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
337 * 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
338 * current process from accessing other process's information. 297 * current process from accessing other process's information.
339 */ 298 */
340static LIST_HEAD(tomoyo_pattern_list); 299LIST_HEAD(tomoyo_pattern_list);
341static DECLARE_RWSEM(tomoyo_pattern_list_lock);
342 300
343/** 301/**
344 * tomoyo_update_file_pattern_entry - Update "struct tomoyo_pattern_entry" list. 302 * tomoyo_update_file_pattern_entry - Update "struct tomoyo_pattern_entry" list.
@@ -347,40 +305,43 @@ static DECLARE_RWSEM(tomoyo_pattern_list_lock);
347 * @is_delete: True if it is a delete request. 305 * @is_delete: True if it is a delete request.
348 * 306 *
349 * Returns 0 on success, negative value otherwise. 307 * Returns 0 on success, negative value otherwise.
308 *
309 * Caller holds tomoyo_read_lock().
350 */ 310 */
351static int tomoyo_update_file_pattern_entry(const char *pattern, 311static int tomoyo_update_file_pattern_entry(const char *pattern,
352 const bool is_delete) 312 const bool is_delete)
353{ 313{
354 struct tomoyo_pattern_entry *new_entry; 314 struct tomoyo_pattern_entry *entry = NULL;
355 struct tomoyo_pattern_entry *ptr; 315 struct tomoyo_pattern_entry *ptr;
356 const struct tomoyo_path_info *saved_pattern; 316 const struct tomoyo_path_info *saved_pattern;
357 int error = -ENOMEM; 317 int error = is_delete ? -ENOENT : -ENOMEM;
358 318
359 if (!tomoyo_is_correct_path(pattern, 0, 1, 0, __func__)) 319 saved_pattern = tomoyo_get_name(pattern);
360 return -EINVAL;
361 saved_pattern = tomoyo_save_name(pattern);
362 if (!saved_pattern) 320 if (!saved_pattern)
363 return -ENOMEM; 321 return error;
364 down_write(&tomoyo_pattern_list_lock); 322 if (!saved_pattern->is_patterned)
365 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) {
366 if (saved_pattern != ptr->pattern) 328 if (saved_pattern != ptr->pattern)
367 continue; 329 continue;
368 ptr->is_deleted = is_delete; 330 ptr->is_deleted = is_delete;
369 error = 0; 331 error = 0;
370 goto out; 332 break;
371 } 333 }
372 if (is_delete) { 334 if (!is_delete && error && tomoyo_memory_ok(entry)) {
373 error = -ENOENT; 335 entry->pattern = saved_pattern;
374 goto out; 336 saved_pattern = NULL;
337 list_add_tail_rcu(&entry->list, &tomoyo_pattern_list);
338 entry = NULL;
339 error = 0;
375 } 340 }
376 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 341 mutex_unlock(&tomoyo_policy_lock);
377 if (!new_entry)
378 goto out;
379 new_entry->pattern = saved_pattern;
380 list_add_tail(&new_entry->list, &tomoyo_pattern_list);
381 error = 0;
382 out: 342 out:
383 up_write(&tomoyo_pattern_list_lock); 343 kfree(entry);
344 tomoyo_put_name(saved_pattern);
384 return error; 345 return error;
385} 346}
386 347
@@ -390,6 +351,8 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
390 * @filename: The filename to find patterned pathname. 351 * @filename: The filename to find patterned pathname.
391 * 352 *
392 * 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().
393 */ 356 */
394static const struct tomoyo_path_info * 357static const struct tomoyo_path_info *
395tomoyo_get_file_pattern(const struct tomoyo_path_info *filename) 358tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
@@ -397,8 +360,7 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
397 struct tomoyo_pattern_entry *ptr; 360 struct tomoyo_pattern_entry *ptr;
398 const struct tomoyo_path_info *pattern = NULL; 361 const struct tomoyo_path_info *pattern = NULL;
399 362
400 down_read(&tomoyo_pattern_list_lock); 363 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
401 list_for_each_entry(ptr, &tomoyo_pattern_list, list) {
402 if (ptr->is_deleted) 364 if (ptr->is_deleted)
403 continue; 365 continue;
404 if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) 366 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
@@ -411,7 +373,6 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
411 break; 373 break;
412 } 374 }
413 } 375 }
414 up_read(&tomoyo_pattern_list_lock);
415 if (pattern) 376 if (pattern)
416 filename = pattern; 377 filename = pattern;
417 return filename; 378 return filename;
@@ -424,6 +385,8 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
424 * @is_delete: True if it is a delete request. 385 * @is_delete: True if it is a delete request.
425 * 386 *
426 * Returns 0 on success, negative value otherwise. 387 * Returns 0 on success, negative value otherwise.
388 *
389 * Caller holds tomoyo_read_lock().
427 */ 390 */
428int tomoyo_write_pattern_policy(char *data, const bool is_delete) 391int tomoyo_write_pattern_policy(char *data, const bool is_delete)
429{ 392{
@@ -436,13 +399,14 @@ int tomoyo_write_pattern_policy(char *data, const bool is_delete)
436 * @head: Pointer to "struct tomoyo_io_buffer". 399 * @head: Pointer to "struct tomoyo_io_buffer".
437 * 400 *
438 * Returns true on success, false otherwise. 401 * Returns true on success, false otherwise.
402 *
403 * Caller holds tomoyo_read_lock().
439 */ 404 */
440bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head) 405bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
441{ 406{
442 struct list_head *pos; 407 struct list_head *pos;
443 bool done = true; 408 bool done = true;
444 409
445 down_read(&tomoyo_pattern_list_lock);
446 list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) { 410 list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) {
447 struct tomoyo_pattern_entry *ptr; 411 struct tomoyo_pattern_entry *ptr;
448 ptr = list_entry(pos, struct tomoyo_pattern_entry, list); 412 ptr = list_entry(pos, struct tomoyo_pattern_entry, list);
@@ -453,7 +417,6 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
453 if (!done) 417 if (!done)
454 break; 418 break;
455 } 419 }
456 up_read(&tomoyo_pattern_list_lock);
457 return done; 420 return done;
458} 421}
459 422
@@ -486,8 +449,7 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
486 * " (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
487 * 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.
488 */ 451 */
489static LIST_HEAD(tomoyo_no_rewrite_list); 452LIST_HEAD(tomoyo_no_rewrite_list);
490static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock);
491 453
492/** 454/**
493 * 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.
@@ -496,39 +458,42 @@ static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock);
496 * @is_delete: True if it is a delete request. 458 * @is_delete: True if it is a delete request.
497 * 459 *
498 * Returns 0 on success, negative value otherwise. 460 * Returns 0 on success, negative value otherwise.
461 *
462 * Caller holds tomoyo_read_lock().
499 */ 463 */
500static int tomoyo_update_no_rewrite_entry(const char *pattern, 464static int tomoyo_update_no_rewrite_entry(const char *pattern,
501 const bool is_delete) 465 const bool is_delete)
502{ 466{
503 struct tomoyo_no_rewrite_entry *new_entry, *ptr; 467 struct tomoyo_no_rewrite_entry *entry = NULL;
468 struct tomoyo_no_rewrite_entry *ptr;
504 const struct tomoyo_path_info *saved_pattern; 469 const struct tomoyo_path_info *saved_pattern;
505 int error = -ENOMEM; 470 int error = is_delete ? -ENOENT : -ENOMEM;
506 471
507 if (!tomoyo_is_correct_path(pattern, 0, 0, 0, __func__)) 472 if (!tomoyo_is_correct_path(pattern, 0, 0, 0))
508 return -EINVAL; 473 return -EINVAL;
509 saved_pattern = tomoyo_save_name(pattern); 474 saved_pattern = tomoyo_get_name(pattern);
510 if (!saved_pattern) 475 if (!saved_pattern)
511 return -ENOMEM; 476 return error;
512 down_write(&tomoyo_no_rewrite_list_lock); 477 if (!is_delete)
513 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) {
514 if (ptr->pattern != saved_pattern) 481 if (ptr->pattern != saved_pattern)
515 continue; 482 continue;
516 ptr->is_deleted = is_delete; 483 ptr->is_deleted = is_delete;
517 error = 0; 484 error = 0;
518 goto out; 485 break;
519 } 486 }
520 if (is_delete) { 487 if (!is_delete && error && tomoyo_memory_ok(entry)) {
521 error = -ENOENT; 488 entry->pattern = saved_pattern;
522 goto out; 489 saved_pattern = NULL;
490 list_add_tail_rcu(&entry->list, &tomoyo_no_rewrite_list);
491 entry = NULL;
492 error = 0;
523 } 493 }
524 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 494 mutex_unlock(&tomoyo_policy_lock);
525 if (!new_entry) 495 tomoyo_put_name(saved_pattern);
526 goto out; 496 kfree(entry);
527 new_entry->pattern = saved_pattern;
528 list_add_tail(&new_entry->list, &tomoyo_no_rewrite_list);
529 error = 0;
530 out:
531 up_write(&tomoyo_no_rewrite_list_lock);
532 return error; 497 return error;
533} 498}
534 499
@@ -539,14 +504,15 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
539 * 504 *
540 * Returns true if @filename is specified by "deny_rewrite" directive, 505 * Returns true if @filename is specified by "deny_rewrite" directive,
541 * false otherwise. 506 * false otherwise.
507 *
508 * Caller holds tomoyo_read_lock().
542 */ 509 */
543static 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)
544{ 511{
545 struct tomoyo_no_rewrite_entry *ptr; 512 struct tomoyo_no_rewrite_entry *ptr;
546 bool found = false; 513 bool found = false;
547 514
548 down_read(&tomoyo_no_rewrite_list_lock); 515 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
549 list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) {
550 if (ptr->is_deleted) 516 if (ptr->is_deleted)
551 continue; 517 continue;
552 if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) 518 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
@@ -554,7 +520,6 @@ static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
554 found = true; 520 found = true;
555 break; 521 break;
556 } 522 }
557 up_read(&tomoyo_no_rewrite_list_lock);
558 return found; 523 return found;
559} 524}
560 525
@@ -565,6 +530,8 @@ static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
565 * @is_delete: True if it is a delete request. 530 * @is_delete: True if it is a delete request.
566 * 531 *
567 * Returns 0 on success, negative value otherwise. 532 * Returns 0 on success, negative value otherwise.
533 *
534 * Caller holds tomoyo_read_lock().
568 */ 535 */
569int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete) 536int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete)
570{ 537{
@@ -577,13 +544,14 @@ int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete)
577 * @head: Pointer to "struct tomoyo_io_buffer". 544 * @head: Pointer to "struct tomoyo_io_buffer".
578 * 545 *
579 * Returns true on success, false otherwise. 546 * Returns true on success, false otherwise.
547 *
548 * Caller holds tomoyo_read_lock().
580 */ 549 */
581bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head) 550bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
582{ 551{
583 struct list_head *pos; 552 struct list_head *pos;
584 bool done = true; 553 bool done = true;
585 554
586 down_read(&tomoyo_no_rewrite_list_lock);
587 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) {
588 struct tomoyo_no_rewrite_entry *ptr; 556 struct tomoyo_no_rewrite_entry *ptr;
589 ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list); 557 ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list);
@@ -594,7 +562,6 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
594 if (!done) 562 if (!done)
595 break; 563 break;
596 } 564 }
597 up_read(&tomoyo_no_rewrite_list_lock);
598 return done; 565 return done;
599} 566}
600 567
@@ -612,6 +579,8 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
612 * Current policy syntax uses "allow_read/write" instead of "6", 579 * Current policy syntax uses "allow_read/write" instead of "6",
613 * "allow_read" instead of "4", "allow_write" instead of "2", 580 * "allow_read" instead of "4", "allow_write" instead of "2",
614 * "allow_execute" instead of "1". 581 * "allow_execute" instead of "1".
582 *
583 * Caller holds tomoyo_read_lock().
615 */ 584 */
616static int tomoyo_update_file_acl(const char *filename, u8 perm, 585static int tomoyo_update_file_acl(const char *filename, u8 perm,
617 struct tomoyo_domain_info * const domain, 586 struct tomoyo_domain_info * const domain,
@@ -629,19 +598,19 @@ static int tomoyo_update_file_acl(const char *filename, u8 perm,
629 */ 598 */
630 return 0; 599 return 0;
631 if (perm & 4) 600 if (perm & 4)
632 tomoyo_update_single_path_acl(TOMOYO_TYPE_READ_ACL, filename, 601 tomoyo_update_path_acl(TOMOYO_TYPE_READ, filename, domain,
633 domain, is_delete); 602 is_delete);
634 if (perm & 2) 603 if (perm & 2)
635 tomoyo_update_single_path_acl(TOMOYO_TYPE_WRITE_ACL, filename, 604 tomoyo_update_path_acl(TOMOYO_TYPE_WRITE, filename, domain,
636 domain, is_delete); 605 is_delete);
637 if (perm & 1) 606 if (perm & 1)
638 tomoyo_update_single_path_acl(TOMOYO_TYPE_EXECUTE_ACL, 607 tomoyo_update_path_acl(TOMOYO_TYPE_EXECUTE, filename, domain,
639 filename, domain, is_delete); 608 is_delete);
640 return 0; 609 return 0;
641} 610}
642 611
643/** 612/**
644 * tomoyo_check_single_path_acl2 - Check permission for single path operation. 613 * tomoyo_path_acl2 - Check permission for single path operation.
645 * 614 *
646 * @domain: Pointer to "struct tomoyo_domain_info". 615 * @domain: Pointer to "struct tomoyo_domain_info".
647 * @filename: Filename to check. 616 * @filename: Filename to check.
@@ -649,26 +618,28 @@ static int tomoyo_update_file_acl(const char *filename, u8 perm,
649 * @may_use_pattern: True if patterned ACL is permitted. 618 * @may_use_pattern: True if patterned ACL is permitted.
650 * 619 *
651 * Returns 0 on success, -EPERM otherwise. 620 * Returns 0 on success, -EPERM otherwise.
621 *
622 * Caller holds tomoyo_read_lock().
652 */ 623 */
653static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info * 624static int tomoyo_path_acl2(const struct tomoyo_domain_info *domain,
654 domain, 625 const struct tomoyo_path_info *filename,
655 const struct tomoyo_path_info * 626 const u32 perm, const bool may_use_pattern)
656 filename,
657 const u16 perm,
658 const bool may_use_pattern)
659{ 627{
660 struct tomoyo_acl_info *ptr; 628 struct tomoyo_acl_info *ptr;
661 int error = -EPERM; 629 int error = -EPERM;
662 630
663 down_read(&tomoyo_domain_acl_info_list_lock); 631 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
664 list_for_each_entry(ptr, &domain->acl_info_list, list) { 632 struct tomoyo_path_acl *acl;
665 struct tomoyo_single_path_acl_record *acl; 633 if (ptr->type != TOMOYO_TYPE_PATH_ACL)
666 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL)
667 continue;
668 acl = container_of(ptr, struct tomoyo_single_path_acl_record,
669 head);
670 if (!(acl->perm & perm))
671 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 }
672 if (may_use_pattern || !acl->filename->is_patterned) { 643 if (may_use_pattern || !acl->filename->is_patterned) {
673 if (!tomoyo_path_matches_pattern(filename, 644 if (!tomoyo_path_matches_pattern(filename,
674 acl->filename)) 645 acl->filename))
@@ -679,7 +650,6 @@ static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info *
679 error = 0; 650 error = 0;
680 break; 651 break;
681 } 652 }
682 up_read(&tomoyo_domain_acl_info_list_lock);
683 return error; 653 return error;
684} 654}
685 655
@@ -691,27 +661,28 @@ static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info *
691 * @operation: Mode ("read" or "write" or "read/write" or "execute"). 661 * @operation: Mode ("read" or "write" or "read/write" or "execute").
692 * 662 *
693 * Returns 0 on success, -EPERM otherwise. 663 * Returns 0 on success, -EPERM otherwise.
664 *
665 * Caller holds tomoyo_read_lock().
694 */ 666 */
695static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain, 667static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain,
696 const struct tomoyo_path_info *filename, 668 const struct tomoyo_path_info *filename,
697 const u8 operation) 669 const u8 operation)
698{ 670{
699 u16 perm = 0; 671 u32 perm = 0;
700 672
701 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) 673 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
702 return 0; 674 return 0;
703 if (operation == 6) 675 if (operation == 6)
704 perm = 1 << TOMOYO_TYPE_READ_WRITE_ACL; 676 perm = 1 << TOMOYO_TYPE_READ_WRITE;
705 else if (operation == 4) 677 else if (operation == 4)
706 perm = 1 << TOMOYO_TYPE_READ_ACL; 678 perm = 1 << TOMOYO_TYPE_READ;
707 else if (operation == 2) 679 else if (operation == 2)
708 perm = 1 << TOMOYO_TYPE_WRITE_ACL; 680 perm = 1 << TOMOYO_TYPE_WRITE;
709 else if (operation == 1) 681 else if (operation == 1)
710 perm = 1 << TOMOYO_TYPE_EXECUTE_ACL; 682 perm = 1 << TOMOYO_TYPE_EXECUTE;
711 else 683 else
712 BUG(); 684 BUG();
713 return tomoyo_check_single_path_acl2(domain, filename, perm, 685 return tomoyo_path_acl2(domain, filename, perm, operation != 1);
714 operation != 1);
715} 686}
716 687
717/** 688/**
@@ -724,6 +695,8 @@ static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain,
724 * @mode: Access control mode. 695 * @mode: Access control mode.
725 * 696 *
726 * Returns 0 on success, negative value otherwise. 697 * Returns 0 on success, negative value otherwise.
698 *
699 * Caller holds tomoyo_read_lock().
727 */ 700 */
728static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain, 701static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
729 const struct tomoyo_path_info *filename, 702 const struct tomoyo_path_info *filename,
@@ -737,18 +710,17 @@ static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
737 if (!filename) 710 if (!filename)
738 return 0; 711 return 0;
739 error = tomoyo_check_file_acl(domain, filename, perm); 712 error = tomoyo_check_file_acl(domain, filename, perm);
740 if (error && perm == 4 && 713 if (error && perm == 4 && !domain->ignore_global_allow_read
741 (domain->flags & TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ) == 0
742 && tomoyo_is_globally_readable_file(filename)) 714 && tomoyo_is_globally_readable_file(filename))
743 error = 0; 715 error = 0;
744 if (perm == 6) 716 if (perm == 6)
745 msg = tomoyo_sp2keyword(TOMOYO_TYPE_READ_WRITE_ACL); 717 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ_WRITE);
746 else if (perm == 4) 718 else if (perm == 4)
747 msg = tomoyo_sp2keyword(TOMOYO_TYPE_READ_ACL); 719 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ);
748 else if (perm == 2) 720 else if (perm == 2)
749 msg = tomoyo_sp2keyword(TOMOYO_TYPE_WRITE_ACL); 721 msg = tomoyo_path2keyword(TOMOYO_TYPE_WRITE);
750 else if (perm == 1) 722 else if (perm == 1)
751 msg = tomoyo_sp2keyword(TOMOYO_TYPE_EXECUTE_ACL); 723 msg = tomoyo_path2keyword(TOMOYO_TYPE_EXECUTE);
752 else 724 else
753 BUG(); 725 BUG();
754 if (!error) 726 if (!error)
@@ -777,6 +749,8 @@ static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
777 * @is_delete: True if it is a delete request. 749 * @is_delete: True if it is a delete request.
778 * 750 *
779 * Returns 0 on success, negative value otherwise. 751 * Returns 0 on success, negative value otherwise.
752 *
753 * Caller holds tomoyo_read_lock().
780 */ 754 */
781int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain, 755int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
782 const bool is_delete) 756 const bool is_delete)
@@ -795,28 +769,28 @@ int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
795 if (strncmp(data, "allow_", 6)) 769 if (strncmp(data, "allow_", 6))
796 goto out; 770 goto out;
797 data += 6; 771 data += 6;
798 for (type = 0; type < TOMOYO_MAX_SINGLE_PATH_OPERATION; type++) { 772 for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++) {
799 if (strcmp(data, tomoyo_sp_keyword[type])) 773 if (strcmp(data, tomoyo_path_keyword[type]))
800 continue; 774 continue;
801 return tomoyo_update_single_path_acl(type, filename, 775 return tomoyo_update_path_acl(type, filename, domain,
802 domain, is_delete); 776 is_delete);
803 } 777 }
804 filename2 = strchr(filename, ' '); 778 filename2 = strchr(filename, ' ');
805 if (!filename2) 779 if (!filename2)
806 goto out; 780 goto out;
807 *filename2++ = '\0'; 781 *filename2++ = '\0';
808 for (type = 0; type < TOMOYO_MAX_DOUBLE_PATH_OPERATION; type++) { 782 for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++) {
809 if (strcmp(data, tomoyo_dp_keyword[type])) 783 if (strcmp(data, tomoyo_path2_keyword[type]))
810 continue; 784 continue;
811 return tomoyo_update_double_path_acl(type, filename, filename2, 785 return tomoyo_update_path2_acl(type, filename, filename2,
812 domain, is_delete); 786 domain, is_delete);
813 } 787 }
814 out: 788 out:
815 return -EINVAL; 789 return -EINVAL;
816} 790}
817 791
818/** 792/**
819 * tomoyo_update_single_path_acl - Update "struct tomoyo_single_path_acl_record" list. 793 * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list.
820 * 794 *
821 * @type: Type of operation. 795 * @type: Type of operation.
822 * @filename: Filename. 796 * @filename: Filename.
@@ -824,85 +798,82 @@ int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
824 * @is_delete: True if it is a delete request. 798 * @is_delete: True if it is a delete request.
825 * 799 *
826 * Returns 0 on success, negative value otherwise. 800 * Returns 0 on success, negative value otherwise.
801 *
802 * Caller holds tomoyo_read_lock().
827 */ 803 */
828static int tomoyo_update_single_path_acl(const u8 type, const char *filename, 804static int tomoyo_update_path_acl(const u8 type, const char *filename,
829 struct tomoyo_domain_info * 805 struct tomoyo_domain_info *const domain,
830 const domain, const bool is_delete) 806 const bool is_delete)
831{ 807{
832 static const u16 rw_mask = 808 static const u32 rw_mask =
833 (1 << TOMOYO_TYPE_READ_ACL) | (1 << TOMOYO_TYPE_WRITE_ACL); 809 (1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE);
834 const struct tomoyo_path_info *saved_filename; 810 const struct tomoyo_path_info *saved_filename;
835 struct tomoyo_acl_info *ptr; 811 struct tomoyo_acl_info *ptr;
836 struct tomoyo_single_path_acl_record *acl; 812 struct tomoyo_path_acl *entry = NULL;
837 int error = -ENOMEM; 813 int error = is_delete ? -ENOENT : -ENOMEM;
838 const u16 perm = 1 << type; 814 const u32 perm = 1 << type;
839 815
840 if (!domain) 816 if (!domain)
841 return -EINVAL; 817 return -EINVAL;
842 if (!tomoyo_is_correct_path(filename, 0, 0, 0, __func__)) 818 if (!tomoyo_is_correct_path(filename, 0, 0, 0))
843 return -EINVAL; 819 return -EINVAL;
844 saved_filename = tomoyo_save_name(filename); 820 saved_filename = tomoyo_get_name(filename);
845 if (!saved_filename) 821 if (!saved_filename)
846 return -ENOMEM; 822 return -ENOMEM;
847 down_write(&tomoyo_domain_acl_info_list_lock); 823 if (!is_delete)
848 if (is_delete) 824 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
849 goto delete; 825 mutex_lock(&tomoyo_policy_lock);
850 list_for_each_entry(ptr, &domain->acl_info_list, list) { 826 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
851 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)
852 continue; 830 continue;
853 acl = container_of(ptr, struct tomoyo_single_path_acl_record,
854 head);
855 if (acl->filename != saved_filename) 831 if (acl->filename != saved_filename)
856 continue; 832 continue;
857 /* Special case. Clear all bits if marked as deleted. */ 833 if (is_delete) {
858 if (ptr->type & TOMOYO_ACL_DELETED) 834 if (perm <= 0xFFFF)
859 acl->perm = 0; 835 acl->perm &= ~perm;
860 acl->perm |= perm; 836 else
861 if ((acl->perm & rw_mask) == rw_mask) 837 acl->perm_high &= ~(perm >> 16);
862 acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE_ACL; 838 if ((acl->perm & rw_mask) != rw_mask)
863 else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)) 839 acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE);
864 acl->perm |= rw_mask; 840 else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE)))
865 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 }
866 error = 0; 852 error = 0;
867 goto out; 853 break;
868 } 854 }
869 /* Not found. Append it to the tail. */ 855 if (!is_delete && error && tomoyo_memory_ok(entry)) {
870 acl = tomoyo_alloc_acl_element(TOMOYO_TYPE_SINGLE_PATH_ACL); 856 entry->head.type = TOMOYO_TYPE_PATH_ACL;
871 if (!acl) 857 if (perm <= 0xFFFF)
872 goto out; 858 entry->perm = perm;
873 acl->perm = perm; 859 else
874 if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL)) 860 entry->perm_high = (perm >> 16);
875 acl->perm |= rw_mask; 861 if (perm == (1 << TOMOYO_TYPE_READ_WRITE))
876 acl->filename = saved_filename; 862 entry->perm |= rw_mask;
877 list_add_tail(&acl->head.list, &domain->acl_info_list); 863 entry->filename = saved_filename;
878 error = 0; 864 saved_filename = NULL;
879 goto out; 865 list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
880 delete: 866 entry = NULL;
881 error = -ENOENT;
882 list_for_each_entry(ptr, &domain->acl_info_list, list) {
883 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL)
884 continue;
885 acl = container_of(ptr, struct tomoyo_single_path_acl_record,
886 head);
887 if (acl->filename != saved_filename)
888 continue;
889 acl->perm &= ~perm;
890 if ((acl->perm & rw_mask) != rw_mask)
891 acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE_ACL);
892 else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)))
893 acl->perm &= ~rw_mask;
894 if (!acl->perm)
895 ptr->type |= TOMOYO_ACL_DELETED;
896 error = 0; 867 error = 0;
897 break;
898 } 868 }
899 out: 869 mutex_unlock(&tomoyo_policy_lock);
900 up_write(&tomoyo_domain_acl_info_list_lock); 870 kfree(entry);
871 tomoyo_put_name(saved_filename);
901 return error; 872 return error;
902} 873}
903 874
904/** 875/**
905 * tomoyo_update_double_path_acl - Update "struct tomoyo_double_path_acl_record" list. 876 * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list.
906 * 877 *
907 * @type: Type of operation. 878 * @type: Type of operation.
908 * @filename1: First filename. 879 * @filename1: First filename.
@@ -911,98 +882,88 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
911 * @is_delete: True if it is a delete request. 882 * @is_delete: True if it is a delete request.
912 * 883 *
913 * Returns 0 on success, negative value otherwise. 884 * Returns 0 on success, negative value otherwise.
885 *
886 * Caller holds tomoyo_read_lock().
914 */ 887 */
915static int tomoyo_update_double_path_acl(const u8 type, const char *filename1, 888static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
916 const char *filename2, 889 const char *filename2,
917 struct tomoyo_domain_info * 890 struct tomoyo_domain_info *const domain,
918 const domain, const bool is_delete) 891 const bool is_delete)
919{ 892{
920 const struct tomoyo_path_info *saved_filename1; 893 const struct tomoyo_path_info *saved_filename1;
921 const struct tomoyo_path_info *saved_filename2; 894 const struct tomoyo_path_info *saved_filename2;
922 struct tomoyo_acl_info *ptr; 895 struct tomoyo_acl_info *ptr;
923 struct tomoyo_double_path_acl_record *acl; 896 struct tomoyo_path2_acl *entry = NULL;
924 int error = -ENOMEM; 897 int error = is_delete ? -ENOENT : -ENOMEM;
925 const u8 perm = 1 << type; 898 const u8 perm = 1 << type;
926 899
927 if (!domain) 900 if (!domain)
928 return -EINVAL; 901 return -EINVAL;
929 if (!tomoyo_is_correct_path(filename1, 0, 0, 0, __func__) || 902 if (!tomoyo_is_correct_path(filename1, 0, 0, 0) ||
930 !tomoyo_is_correct_path(filename2, 0, 0, 0, __func__)) 903 !tomoyo_is_correct_path(filename2, 0, 0, 0))
931 return -EINVAL; 904 return -EINVAL;
932 saved_filename1 = tomoyo_save_name(filename1); 905 saved_filename1 = tomoyo_get_name(filename1);
933 saved_filename2 = tomoyo_save_name(filename2); 906 saved_filename2 = tomoyo_get_name(filename2);
934 if (!saved_filename1 || !saved_filename2) 907 if (!saved_filename1 || !saved_filename2)
935 return -ENOMEM;
936 down_write(&tomoyo_domain_acl_info_list_lock);
937 if (is_delete)
938 goto delete;
939 list_for_each_entry(ptr, &domain->acl_info_list, list) {
940 if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
941 continue;
942 acl = container_of(ptr, struct tomoyo_double_path_acl_record,
943 head);
944 if (acl->filename1 != saved_filename1 ||
945 acl->filename2 != saved_filename2)
946 continue;
947 /* Special case. Clear all bits if marked as deleted. */
948 if (ptr->type & TOMOYO_ACL_DELETED)
949 acl->perm = 0;
950 acl->perm |= perm;
951 ptr->type &= ~TOMOYO_ACL_DELETED;
952 error = 0;
953 goto out; 908 goto out;
954 } 909 if (!is_delete)
955 /* Not found. Append it to the tail. */ 910 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
956 acl = tomoyo_alloc_acl_element(TOMOYO_TYPE_DOUBLE_PATH_ACL); 911 mutex_lock(&tomoyo_policy_lock);
957 if (!acl) 912 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
958 goto out; 913 struct tomoyo_path2_acl *acl =
959 acl->perm = perm; 914 container_of(ptr, struct tomoyo_path2_acl, head);
960 acl->filename1 = saved_filename1; 915 if (ptr->type != TOMOYO_TYPE_PATH2_ACL)
961 acl->filename2 = saved_filename2;
962 list_add_tail(&acl->head.list, &domain->acl_info_list);
963 error = 0;
964 goto out;
965 delete:
966 error = -ENOENT;
967 list_for_each_entry(ptr, &domain->acl_info_list, list) {
968 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
969 continue; 916 continue;
970 acl = container_of(ptr, struct tomoyo_double_path_acl_record,
971 head);
972 if (acl->filename1 != saved_filename1 || 917 if (acl->filename1 != saved_filename1 ||
973 acl->filename2 != saved_filename2) 918 acl->filename2 != saved_filename2)
974 continue; 919 continue;
975 acl->perm &= ~perm; 920 if (is_delete)
976 if (!acl->perm) 921 acl->perm &= ~perm;
977 ptr->type |= TOMOYO_ACL_DELETED; 922 else
923 acl->perm |= perm;
978 error = 0; 924 error = 0;
979 break; 925 break;
980 } 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);
981 out: 939 out:
982 up_write(&tomoyo_domain_acl_info_list_lock); 940 tomoyo_put_name(saved_filename1);
941 tomoyo_put_name(saved_filename2);
942 kfree(entry);
983 return error; 943 return error;
984} 944}
985 945
986/** 946/**
987 * tomoyo_check_single_path_acl - Check permission for single path operation. 947 * tomoyo_path_acl - Check permission for single path operation.
988 * 948 *
989 * @domain: Pointer to "struct tomoyo_domain_info". 949 * @domain: Pointer to "struct tomoyo_domain_info".
990 * @type: Type of operation. 950 * @type: Type of operation.
991 * @filename: Filename to check. 951 * @filename: Filename to check.
992 * 952 *
993 * Returns 0 on success, negative value otherwise. 953 * Returns 0 on success, negative value otherwise.
954 *
955 * Caller holds tomoyo_read_lock().
994 */ 956 */
995static int tomoyo_check_single_path_acl(struct tomoyo_domain_info *domain, 957static int tomoyo_path_acl(struct tomoyo_domain_info *domain, const u8 type,
996 const u8 type, 958 const struct tomoyo_path_info *filename)
997 const struct tomoyo_path_info *filename)
998{ 959{
999 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) 960 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
1000 return 0; 961 return 0;
1001 return tomoyo_check_single_path_acl2(domain, filename, 1 << type, 1); 962 return tomoyo_path_acl2(domain, filename, 1 << type, 1);
1002} 963}
1003 964
1004/** 965/**
1005 * tomoyo_check_double_path_acl - Check permission for double path operation. 966 * tomoyo_path2_acl - Check permission for double path operation.
1006 * 967 *
1007 * @domain: Pointer to "struct tomoyo_domain_info". 968 * @domain: Pointer to "struct tomoyo_domain_info".
1008 * @type: Type of operation. 969 * @type: Type of operation.
@@ -1010,13 +971,13 @@ static int tomoyo_check_single_path_acl(struct tomoyo_domain_info *domain,
1010 * @filename2: Second filename to check. 971 * @filename2: Second filename to check.
1011 * 972 *
1012 * Returns 0 on success, -EPERM otherwise. 973 * Returns 0 on success, -EPERM otherwise.
974 *
975 * Caller holds tomoyo_read_lock().
1013 */ 976 */
1014static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain, 977static int tomoyo_path2_acl(const struct tomoyo_domain_info *domain,
1015 const u8 type, 978 const u8 type,
1016 const struct tomoyo_path_info * 979 const struct tomoyo_path_info *filename1,
1017 filename1, 980 const struct tomoyo_path_info *filename2)
1018 const struct tomoyo_path_info *
1019 filename2)
1020{ 981{
1021 struct tomoyo_acl_info *ptr; 982 struct tomoyo_acl_info *ptr;
1022 const u8 perm = 1 << type; 983 const u8 perm = 1 << type;
@@ -1024,13 +985,11 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
1024 985
1025 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) 986 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
1026 return 0; 987 return 0;
1027 down_read(&tomoyo_domain_acl_info_list_lock); 988 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
1028 list_for_each_entry(ptr, &domain->acl_info_list, list) { 989 struct tomoyo_path2_acl *acl;
1029 struct tomoyo_double_path_acl_record *acl; 990 if (ptr->type != TOMOYO_TYPE_PATH2_ACL)
1030 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
1031 continue; 991 continue;
1032 acl = container_of(ptr, struct tomoyo_double_path_acl_record, 992 acl = container_of(ptr, struct tomoyo_path2_acl, head);
1033 head);
1034 if (!(acl->perm & perm)) 993 if (!(acl->perm & perm))
1035 continue; 994 continue;
1036 if (!tomoyo_path_matches_pattern(filename1, acl->filename1)) 995 if (!tomoyo_path_matches_pattern(filename1, acl->filename1))
@@ -1040,12 +999,11 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
1040 error = 0; 999 error = 0;
1041 break; 1000 break;
1042 } 1001 }
1043 up_read(&tomoyo_domain_acl_info_list_lock);
1044 return error; 1002 return error;
1045} 1003}
1046 1004
1047/** 1005/**
1048 * tomoyo_check_single_path_permission2 - Check permission for single path operation. 1006 * tomoyo_path_permission2 - Check permission for single path operation.
1049 * 1007 *
1050 * @domain: Pointer to "struct tomoyo_domain_info". 1008 * @domain: Pointer to "struct tomoyo_domain_info".
1051 * @operation: Type of operation. 1009 * @operation: Type of operation.
@@ -1053,11 +1011,13 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
1053 * @mode: Access control mode. 1011 * @mode: Access control mode.
1054 * 1012 *
1055 * Returns 0 on success, negative value otherwise. 1013 * Returns 0 on success, negative value otherwise.
1014 *
1015 * Caller holds tomoyo_read_lock().
1056 */ 1016 */
1057static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info * 1017static int tomoyo_path_permission2(struct tomoyo_domain_info *const domain,
1058 const domain, u8 operation, 1018 u8 operation,
1059 const struct tomoyo_path_info * 1019 const struct tomoyo_path_info *filename,
1060 filename, const u8 mode) 1020 const u8 mode)
1061{ 1021{
1062 const char *msg; 1022 const char *msg;
1063 int error; 1023 int error;
@@ -1066,8 +1026,8 @@ static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info *
1066 if (!mode) 1026 if (!mode)
1067 return 0; 1027 return 0;
1068 next: 1028 next:
1069 error = tomoyo_check_single_path_acl(domain, operation, filename); 1029 error = tomoyo_path_acl(domain, operation, filename);
1070 msg = tomoyo_sp2keyword(operation); 1030 msg = tomoyo_path2keyword(operation);
1071 if (!error) 1031 if (!error)
1072 goto ok; 1032 goto ok;
1073 if (tomoyo_verbose_mode(domain)) 1033 if (tomoyo_verbose_mode(domain))
@@ -1076,7 +1036,7 @@ static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info *
1076 tomoyo_get_last_name(domain)); 1036 tomoyo_get_last_name(domain));
1077 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) { 1037 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) {
1078 const char *name = tomoyo_get_file_pattern(filename)->name; 1038 const char *name = tomoyo_get_file_pattern(filename)->name;
1079 tomoyo_update_single_path_acl(operation, name, domain, false); 1039 tomoyo_update_path_acl(operation, name, domain, false);
1080 } 1040 }
1081 if (!is_enforce) 1041 if (!is_enforce)
1082 error = 0; 1042 error = 0;
@@ -1086,9 +1046,9 @@ static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info *
1086 * we need to check "allow_rewrite" permission if the filename is 1046 * we need to check "allow_rewrite" permission if the filename is
1087 * specified by "deny_rewrite" keyword. 1047 * specified by "deny_rewrite" keyword.
1088 */ 1048 */
1089 if (!error && operation == TOMOYO_TYPE_TRUNCATE_ACL && 1049 if (!error && operation == TOMOYO_TYPE_TRUNCATE &&
1090 tomoyo_is_no_rewrite_file(filename)) { 1050 tomoyo_is_no_rewrite_file(filename)) {
1091 operation = TOMOYO_TYPE_REWRITE_ACL; 1051 operation = TOMOYO_TYPE_REWRITE;
1092 goto next; 1052 goto next;
1093 } 1053 }
1094 return error; 1054 return error;
@@ -1101,6 +1061,8 @@ static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info *
1101 * @filename: Check permission for "execute". 1061 * @filename: Check permission for "execute".
1102 * 1062 *
1103 * Returns 0 on success, negativevalue otherwise. 1063 * Returns 0 on success, negativevalue otherwise.
1064 *
1065 * Caller holds tomoyo_read_lock().
1104 */ 1066 */
1105int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, 1067int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain,
1106 const struct tomoyo_path_info *filename) 1068 const struct tomoyo_path_info *filename)
@@ -1129,6 +1091,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1129 struct tomoyo_path_info *buf; 1091 struct tomoyo_path_info *buf;
1130 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1092 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1131 const bool is_enforce = (mode == 3); 1093 const bool is_enforce = (mode == 3);
1094 int idx;
1132 1095
1133 if (!mode || !path->mnt) 1096 if (!mode || !path->mnt)
1134 return 0; 1097 return 0;
@@ -1140,6 +1103,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1140 * don't call me. 1103 * don't call me.
1141 */ 1104 */
1142 return 0; 1105 return 0;
1106 idx = tomoyo_read_lock();
1143 buf = tomoyo_get_path(path); 1107 buf = tomoyo_get_path(path);
1144 if (!buf) 1108 if (!buf)
1145 goto out; 1109 goto out;
@@ -1152,49 +1116,50 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1152 if ((acc_mode & MAY_WRITE) && 1116 if ((acc_mode & MAY_WRITE) &&
1153 ((flag & O_TRUNC) || !(flag & O_APPEND)) && 1117 ((flag & O_TRUNC) || !(flag & O_APPEND)) &&
1154 (tomoyo_is_no_rewrite_file(buf))) { 1118 (tomoyo_is_no_rewrite_file(buf))) {
1155 error = tomoyo_check_single_path_permission2(domain, 1119 error = tomoyo_path_permission2(domain, TOMOYO_TYPE_REWRITE,
1156 TOMOYO_TYPE_REWRITE_ACL, 1120 buf, mode);
1157 buf, mode);
1158 } 1121 }
1159 if (!error) 1122 if (!error)
1160 error = tomoyo_check_file_perm2(domain, buf, acc_mode, "open", 1123 error = tomoyo_check_file_perm2(domain, buf, acc_mode, "open",
1161 mode); 1124 mode);
1162 if (!error && (flag & O_TRUNC)) 1125 if (!error && (flag & O_TRUNC))
1163 error = tomoyo_check_single_path_permission2(domain, 1126 error = tomoyo_path_permission2(domain, TOMOYO_TYPE_TRUNCATE,
1164 TOMOYO_TYPE_TRUNCATE_ACL, 1127 buf, mode);
1165 buf, mode);
1166 out: 1128 out:
1167 tomoyo_free(buf); 1129 kfree(buf);
1130 tomoyo_read_unlock(idx);
1168 if (!is_enforce) 1131 if (!is_enforce)
1169 error = 0; 1132 error = 0;
1170 return error; 1133 return error;
1171} 1134}
1172 1135
1173/** 1136/**
1174 * 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".
1175 * 1138 *
1176 * @domain: Pointer to "struct tomoyo_domain_info".
1177 * @operation: Type of operation. 1139 * @operation: Type of operation.
1178 * @path: Pointer to "struct path". 1140 * @path: Pointer to "struct path".
1179 * 1141 *
1180 * Returns 0 on success, negative value otherwise. 1142 * Returns 0 on success, negative value otherwise.
1181 */ 1143 */
1182int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain, 1144int tomoyo_path_perm(const u8 operation, struct path *path)
1183 const u8 operation, struct path *path)
1184{ 1145{
1185 int error = -ENOMEM; 1146 int error = -ENOMEM;
1186 struct tomoyo_path_info *buf; 1147 struct tomoyo_path_info *buf;
1148 struct tomoyo_domain_info *domain = tomoyo_domain();
1187 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1149 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1188 const bool is_enforce = (mode == 3); 1150 const bool is_enforce = (mode == 3);
1151 int idx;
1189 1152
1190 if (!mode || !path->mnt) 1153 if (!mode || !path->mnt)
1191 return 0; 1154 return 0;
1155 idx = tomoyo_read_lock();
1192 buf = tomoyo_get_path(path); 1156 buf = tomoyo_get_path(path);
1193 if (!buf) 1157 if (!buf)
1194 goto out; 1158 goto out;
1195 switch (operation) { 1159 switch (operation) {
1196 case TOMOYO_TYPE_MKDIR_ACL: 1160 case TOMOYO_TYPE_MKDIR:
1197 case TOMOYO_TYPE_RMDIR_ACL: 1161 case TOMOYO_TYPE_RMDIR:
1162 case TOMOYO_TYPE_CHROOT:
1198 if (!buf->is_dir) { 1163 if (!buf->is_dir) {
1199 /* 1164 /*
1200 * tomoyo_get_path() reserves space for appending "/." 1165 * tomoyo_get_path() reserves space for appending "/."
@@ -1203,10 +1168,10 @@ int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain,
1203 tomoyo_fill_path_info(buf); 1168 tomoyo_fill_path_info(buf);
1204 } 1169 }
1205 } 1170 }
1206 error = tomoyo_check_single_path_permission2(domain, operation, buf, 1171 error = tomoyo_path_permission2(domain, operation, buf, mode);
1207 mode);
1208 out: 1172 out:
1209 tomoyo_free(buf); 1173 kfree(buf);
1174 tomoyo_read_unlock(idx);
1210 if (!is_enforce) 1175 if (!is_enforce)
1211 error = 0; 1176 error = 0;
1212 return error; 1177 return error;
@@ -1215,21 +1180,23 @@ int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain,
1215/** 1180/**
1216 * tomoyo_check_rewrite_permission - Check permission for "rewrite". 1181 * tomoyo_check_rewrite_permission - Check permission for "rewrite".
1217 * 1182 *
1218 * @domain: Pointer to "struct tomoyo_domain_info".
1219 * @filp: Pointer to "struct file". 1183 * @filp: Pointer to "struct file".
1220 * 1184 *
1221 * Returns 0 on success, negative value otherwise. 1185 * Returns 0 on success, negative value otherwise.
1222 */ 1186 */
1223int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain, 1187int tomoyo_check_rewrite_permission(struct file *filp)
1224 struct file *filp)
1225{ 1188{
1226 int error = -ENOMEM; 1189 int error = -ENOMEM;
1190 struct tomoyo_domain_info *domain = tomoyo_domain();
1227 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1191 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1228 const bool is_enforce = (mode == 3); 1192 const bool is_enforce = (mode == 3);
1229 struct tomoyo_path_info *buf; 1193 struct tomoyo_path_info *buf;
1194 int idx;
1230 1195
1231 if (!mode || !filp->f_path.mnt) 1196 if (!mode || !filp->f_path.mnt)
1232 return 0; 1197 return 0;
1198
1199 idx = tomoyo_read_lock();
1233 buf = tomoyo_get_path(&filp->f_path); 1200 buf = tomoyo_get_path(&filp->f_path);
1234 if (!buf) 1201 if (!buf)
1235 goto out; 1202 goto out;
@@ -1237,38 +1204,38 @@ int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain,
1237 error = 0; 1204 error = 0;
1238 goto out; 1205 goto out;
1239 } 1206 }
1240 error = tomoyo_check_single_path_permission2(domain, 1207 error = tomoyo_path_permission2(domain, TOMOYO_TYPE_REWRITE, buf, mode);
1241 TOMOYO_TYPE_REWRITE_ACL,
1242 buf, mode);
1243 out: 1208 out:
1244 tomoyo_free(buf); 1209 kfree(buf);
1210 tomoyo_read_unlock(idx);
1245 if (!is_enforce) 1211 if (!is_enforce)
1246 error = 0; 1212 error = 0;
1247 return error; 1213 return error;
1248} 1214}
1249 1215
1250/** 1216/**
1251 * tomoyo_check_2path_perm - Check permission for "rename" and "link". 1217 * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root".
1252 * 1218 *
1253 * @domain: Pointer to "struct tomoyo_domain_info".
1254 * @operation: Type of operation. 1219 * @operation: Type of operation.
1255 * @path1: Pointer to "struct path". 1220 * @path1: Pointer to "struct path".
1256 * @path2: Pointer to "struct path". 1221 * @path2: Pointer to "struct path".
1257 * 1222 *
1258 * Returns 0 on success, negative value otherwise. 1223 * Returns 0 on success, negative value otherwise.
1259 */ 1224 */
1260int tomoyo_check_2path_perm(struct tomoyo_domain_info * const domain, 1225int tomoyo_path2_perm(const u8 operation, struct path *path1,
1261 const u8 operation, struct path *path1, 1226 struct path *path2)
1262 struct path *path2)
1263{ 1227{
1264 int error = -ENOMEM; 1228 int error = -ENOMEM;
1265 struct tomoyo_path_info *buf1, *buf2; 1229 struct tomoyo_path_info *buf1, *buf2;
1230 struct tomoyo_domain_info *domain = tomoyo_domain();
1266 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1231 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1267 const bool is_enforce = (mode == 3); 1232 const bool is_enforce = (mode == 3);
1268 const char *msg; 1233 const char *msg;
1234 int idx;
1269 1235
1270 if (!mode || !path1->mnt || !path2->mnt) 1236 if (!mode || !path1->mnt || !path2->mnt)
1271 return 0; 1237 return 0;
1238 idx = tomoyo_read_lock();
1272 buf1 = tomoyo_get_path(path1); 1239 buf1 = tomoyo_get_path(path1);
1273 buf2 = tomoyo_get_path(path2); 1240 buf2 = tomoyo_get_path(path2);
1274 if (!buf1 || !buf2) 1241 if (!buf1 || !buf2)
@@ -1289,8 +1256,8 @@ int tomoyo_check_2path_perm(struct tomoyo_domain_info * const domain,
1289 } 1256 }
1290 } 1257 }
1291 } 1258 }
1292 error = tomoyo_check_double_path_acl(domain, operation, buf1, buf2); 1259 error = tomoyo_path2_acl(domain, operation, buf1, buf2);
1293 msg = tomoyo_dp2keyword(operation); 1260 msg = tomoyo_path22keyword(operation);
1294 if (!error) 1261 if (!error)
1295 goto out; 1262 goto out;
1296 if (tomoyo_verbose_mode(domain)) 1263 if (tomoyo_verbose_mode(domain))
@@ -1301,12 +1268,13 @@ int tomoyo_check_2path_perm(struct tomoyo_domain_info * const domain,
1301 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) { 1268 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) {
1302 const char *name1 = tomoyo_get_file_pattern(buf1)->name; 1269 const char *name1 = tomoyo_get_file_pattern(buf1)->name;
1303 const char *name2 = tomoyo_get_file_pattern(buf2)->name; 1270 const char *name2 = tomoyo_get_file_pattern(buf2)->name;
1304 tomoyo_update_double_path_acl(operation, name1, name2, domain, 1271 tomoyo_update_path2_acl(operation, name1, name2, domain,
1305 false); 1272 false);
1306 } 1273 }
1307 out: 1274 out:
1308 tomoyo_free(buf1); 1275 kfree(buf1);
1309 tomoyo_free(buf2); 1276 kfree(buf2);
1277 tomoyo_read_unlock(idx);
1310 if (!is_enforce) 1278 if (!is_enforce)
1311 error = 0; 1279 error = 0;
1312 return error; 1280 return error;
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c
new file mode 100644
index 00000000000..d9ad35bc7fa
--- /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 18369d497eb..c225c65ce42 100644
--- a/security/tomoyo/realpath.c
+++ b/security/tomoyo/realpath.c
@@ -14,9 +14,9 @@
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> 16#include <linux/hash.h>
17 17#include <linux/magic.h>
18#include <linux/slab.h>
18#include "common.h" 19#include "common.h"
19#include "realpath.h"
20 20
21/** 21/**
22 * tomoyo_encode: Convert binary string to ascii string. 22 * tomoyo_encode: Convert binary string to ascii string.
@@ -89,30 +89,15 @@ int tomoyo_realpath_from_path2(struct path *path, char *newname,
89 sp = dentry->d_op->d_dname(dentry, newname + offset, 89 sp = dentry->d_op->d_dname(dentry, newname + offset,
90 newname_len - offset); 90 newname_len - offset);
91 } else { 91 } else {
92 /* Taken from d_namespace_path(). */ 92 struct path ns_root = {.mnt = NULL, .dentry = NULL};
93 struct path root;
94 struct path ns_root = { };
95 struct path tmp;
96 93
97 read_lock(&current->fs->lock);
98 root = current->fs->root;
99 path_get(&root);
100 read_unlock(&current->fs->lock);
101 spin_lock(&vfsmount_lock);
102 if (root.mnt && root.mnt->mnt_ns)
103 ns_root.mnt = mntget(root.mnt->mnt_ns->root);
104 if (ns_root.mnt)
105 ns_root.dentry = dget(ns_root.mnt->mnt_root);
106 spin_unlock(&vfsmount_lock);
107 spin_lock(&dcache_lock); 94 spin_lock(&dcache_lock);
108 tmp = ns_root; 95 /* go to whatever namespace root we are under */
109 sp = __d_path(path, &tmp, newname, newname_len); 96 sp = __d_path(path, &ns_root, newname, newname_len);
110 spin_unlock(&dcache_lock); 97 spin_unlock(&dcache_lock);
111 path_put(&root);
112 path_put(&ns_root);
113 /* Prepend "/proc" prefix if using internal proc vfs mount. */ 98 /* Prepend "/proc" prefix if using internal proc vfs mount. */
114 if (!IS_ERR(sp) && (path->mnt->mnt_parent == path->mnt) && 99 if (!IS_ERR(sp) && (path->mnt->mnt_flags & MNT_INTERNAL) &&
115 (strcmp(path->mnt->mnt_sb->s_type->name, "proc") == 0)) { 100 (path->mnt->mnt_sb->s_magic == PROC_SUPER_MAGIC)) {
116 sp -= 5; 101 sp -= 5;
117 if (sp >= newname) 102 if (sp >= newname)
118 memcpy(sp, "/proc", 5); 103 memcpy(sp, "/proc", 5);
@@ -149,12 +134,12 @@ int tomoyo_realpath_from_path2(struct path *path, char *newname,
149 * 134 *
150 * Returns the realpath of the given @path on success, NULL otherwise. 135 * Returns the realpath of the given @path on success, NULL otherwise.
151 * 136 *
152 * These functions use tomoyo_alloc(), so the caller must call tomoyo_free() 137 * These functions use kzalloc(), so the caller must call kfree()
153 * if these functions didn't return NULL. 138 * if these functions didn't return NULL.
154 */ 139 */
155char *tomoyo_realpath_from_path(struct path *path) 140char *tomoyo_realpath_from_path(struct path *path)
156{ 141{
157 char *buf = tomoyo_alloc(sizeof(struct tomoyo_page_buffer)); 142 char *buf = kzalloc(sizeof(struct tomoyo_page_buffer), GFP_KERNEL);
158 143
159 BUILD_BUG_ON(sizeof(struct tomoyo_page_buffer) 144 BUILD_BUG_ON(sizeof(struct tomoyo_page_buffer)
160 <= TOMOYO_MAX_PATHNAME_LEN - 1); 145 <= TOMOYO_MAX_PATHNAME_LEN - 1);
@@ -163,7 +148,7 @@ char *tomoyo_realpath_from_path(struct path *path)
163 if (tomoyo_realpath_from_path2(path, buf, 148 if (tomoyo_realpath_from_path2(path, buf,
164 TOMOYO_MAX_PATHNAME_LEN - 1) == 0) 149 TOMOYO_MAX_PATHNAME_LEN - 1) == 0)
165 return buf; 150 return buf;
166 tomoyo_free(buf); 151 kfree(buf);
167 return NULL; 152 return NULL;
168} 153}
169 154
@@ -206,98 +191,47 @@ char *tomoyo_realpath_nofollow(const char *pathname)
206} 191}
207 192
208/* Memory allocated for non-string data. */ 193/* Memory allocated for non-string data. */
209static unsigned int tomoyo_allocated_memory_for_elements; 194static atomic_t tomoyo_policy_memory_size;
210/* Quota for holding non-string data. */ 195/* Quota for holding policy. */
211static unsigned int tomoyo_quota_for_elements; 196static unsigned int tomoyo_quota_for_policy;
212 197
213/** 198/**
214 * tomoyo_alloc_element - Allocate permanent memory for structures. 199 * tomoyo_memory_ok - Check memory quota.
215 * 200 *
216 * @size: Size in bytes. 201 * @ptr: Pointer to allocated memory.
217 * 202 *
218 * Returns pointer to allocated memory on success, NULL otherwise. 203 * Returns true on success, false otherwise.
219 * 204 *
220 * Memory has to be zeroed. 205 * Caller holds tomoyo_policy_lock.
221 * The RAM is chunked, so NEVER try to kfree() the returned pointer. 206 * Memory pointed by @ptr will be zeroed on success.
222 */ 207 */
223void *tomoyo_alloc_element(const unsigned int size) 208bool tomoyo_memory_ok(void *ptr)
224{ 209{
225 static char *buf; 210 int allocated_len = ptr ? ksize(ptr) : 0;
226 static DEFINE_MUTEX(lock); 211 atomic_add(allocated_len, &tomoyo_policy_memory_size);
227 static unsigned int buf_used_len = PATH_MAX; 212 if (ptr && (!tomoyo_quota_for_policy ||
228 char *ptr = NULL; 213 atomic_read(&tomoyo_policy_memory_size)
229 /*Assumes sizeof(void *) >= sizeof(long) is true. */ 214 <= tomoyo_quota_for_policy)) {
230 const unsigned int word_aligned_size 215 memset(ptr, 0, allocated_len);
231 = roundup(size, max(sizeof(void *), sizeof(long))); 216 return true;
232 if (word_aligned_size > PATH_MAX)
233 return NULL;
234 mutex_lock(&lock);
235 if (buf_used_len + word_aligned_size > PATH_MAX) {
236 if (!tomoyo_quota_for_elements ||
237 tomoyo_allocated_memory_for_elements
238 + PATH_MAX <= tomoyo_quota_for_elements)
239 ptr = kzalloc(PATH_MAX, GFP_KERNEL);
240 if (!ptr) {
241 printk(KERN_WARNING "ERROR: Out of memory "
242 "for tomoyo_alloc_element().\n");
243 if (!tomoyo_policy_loaded)
244 panic("MAC Initialization failed.\n");
245 } else {
246 buf = ptr;
247 tomoyo_allocated_memory_for_elements += PATH_MAX;
248 buf_used_len = word_aligned_size;
249 ptr = buf;
250 }
251 } else if (word_aligned_size) {
252 int i;
253 ptr = buf + buf_used_len;
254 buf_used_len += word_aligned_size;
255 for (i = 0; i < word_aligned_size; i++) {
256 if (!ptr[i])
257 continue;
258 printk(KERN_ERR "WARNING: Reserved memory was tainted! "
259 "The system might go wrong.\n");
260 ptr[i] = '\0';
261 }
262 } 217 }
263 mutex_unlock(&lock); 218 printk(KERN_WARNING "ERROR: Out of memory "
264 return ptr; 219 "for tomoyo_alloc_element().\n");
220 if (!tomoyo_policy_loaded)
221 panic("MAC Initialization failed.\n");
222 return false;
265} 223}
266 224
267/* Memory allocated for string data in bytes. */ 225/**
268static unsigned int tomoyo_allocated_memory_for_savename; 226 * tomoyo_memory_free - Free memory for elements.
269/* Quota for holding string data in bytes. */
270static unsigned int tomoyo_quota_for_savename;
271
272/*
273 * TOMOYO uses this hash only when appending a string into the string
274 * table. Frequency of appending strings is very low. So we don't need
275 * large (e.g. 64k) hash size. 256 will be sufficient.
276 */
277#define TOMOYO_HASH_BITS 8
278#define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS)
279
280/*
281 * tomoyo_name_entry is a structure which is used for linking
282 * "struct tomoyo_path_info" into tomoyo_name_list .
283 * 227 *
284 * Since tomoyo_name_list manages a list of strings which are shared by 228 * @ptr: Pointer to allocated memory.
285 * multiple processes (whereas "struct tomoyo_path_info" inside
286 * "struct tomoyo_path_info_with_data" is not shared), a reference counter will
287 * be added to "struct tomoyo_name_entry" rather than "struct tomoyo_path_info"
288 * when TOMOYO starts supporting garbage collector.
289 */ 229 */
290struct tomoyo_name_entry { 230void tomoyo_memory_free(void *ptr)
291 struct list_head list; 231{
292 struct tomoyo_path_info entry; 232 atomic_sub(ksize(ptr), &tomoyo_policy_memory_size);
293}; 233 kfree(ptr);
294 234}
295/* Structure for available memory region. */
296struct tomoyo_free_memory_block_list {
297 struct list_head list;
298 char *ptr; /* Pointer to a free area. */
299 int len; /* Length of the area. */
300};
301 235
302/* 236/*
303 * 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.
@@ -305,87 +239,58 @@ struct tomoyo_free_memory_block_list {
305 * "/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
306 * "const struct tomoyo_path_info *". 240 * "const struct tomoyo_path_info *".
307 */ 241 */
308static 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);
309 245
310/** 246/**
311 * tomoyo_save_name - Allocate permanent memory for string data. 247 * tomoyo_get_name - Allocate permanent memory for string data.
312 * 248 *
313 * @name: The string to store into the permernent memory. 249 * @name: The string to store into the permernent memory.
314 * 250 *
315 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. 251 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
316 *
317 * The RAM is shared, so NEVER try to modify or kfree() the returned name.
318 */ 252 */
319const struct tomoyo_path_info *tomoyo_save_name(const char *name) 253const struct tomoyo_path_info *tomoyo_get_name(const char *name)
320{ 254{
321 static LIST_HEAD(fmb_list);
322 static DEFINE_MUTEX(lock);
323 struct tomoyo_name_entry *ptr; 255 struct tomoyo_name_entry *ptr;
324 unsigned int hash; 256 unsigned int hash;
325 /* fmb contains available size in bytes.
326 fmb is removed from the fmb_list when fmb->len becomes 0. */
327 struct tomoyo_free_memory_block_list *fmb;
328 int len; 257 int len;
329 char *cp; 258 int allocated_len;
330 struct list_head *head; 259 struct list_head *head;
331 260
332 if (!name) 261 if (!name)
333 return NULL; 262 return NULL;
334 len = strlen(name) + 1; 263 len = strlen(name) + 1;
335 if (len > TOMOYO_MAX_PATHNAME_LEN) {
336 printk(KERN_WARNING "ERROR: Name too long "
337 "for tomoyo_save_name().\n");
338 return NULL;
339 }
340 hash = full_name_hash((const unsigned char *) name, len - 1); 264 hash = full_name_hash((const unsigned char *) name, len - 1);
341 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; 265 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
342 266 mutex_lock(&tomoyo_name_list_lock);
343 mutex_lock(&lock);
344 list_for_each_entry(ptr, head, list) { 267 list_for_each_entry(ptr, head, list) {
345 if (hash == ptr->entry.hash && !strcmp(name, ptr->entry.name)) 268 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
346 goto out; 269 continue;
347 } 270 atomic_inc(&ptr->users);
348 list_for_each_entry(fmb, &fmb_list, list) { 271 goto out;
349 if (len <= fmb->len)
350 goto ready;
351 } 272 }
352 if (!tomoyo_quota_for_savename || 273 ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL);
353 tomoyo_allocated_memory_for_savename + PATH_MAX 274 allocated_len = ptr ? ksize(ptr) : 0;
354 <= tomoyo_quota_for_savename) 275 if (!ptr || (tomoyo_quota_for_policy &&
355 cp = kzalloc(PATH_MAX, GFP_KERNEL); 276 atomic_read(&tomoyo_policy_memory_size) + allocated_len
356 else 277 > tomoyo_quota_for_policy)) {
357 cp = NULL; 278 kfree(ptr);
358 fmb = kzalloc(sizeof(*fmb), GFP_KERNEL);
359 if (!cp || !fmb) {
360 kfree(cp);
361 kfree(fmb);
362 printk(KERN_WARNING "ERROR: Out of memory " 279 printk(KERN_WARNING "ERROR: Out of memory "
363 "for tomoyo_save_name().\n"); 280 "for tomoyo_get_name().\n");
364 if (!tomoyo_policy_loaded) 281 if (!tomoyo_policy_loaded)
365 panic("MAC Initialization failed.\n"); 282 panic("MAC Initialization failed.\n");
366 ptr = NULL; 283 ptr = NULL;
367 goto out; 284 goto out;
368 } 285 }
369 tomoyo_allocated_memory_for_savename += PATH_MAX; 286 atomic_add(allocated_len, &tomoyo_policy_memory_size);
370 list_add(&fmb->list, &fmb_list); 287 ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
371 fmb->ptr = cp; 288 memmove((char *) ptr->entry.name, name, len);
372 fmb->len = PATH_MAX; 289 atomic_set(&ptr->users, 1);
373 ready:
374 ptr = tomoyo_alloc_element(sizeof(*ptr));
375 if (!ptr)
376 goto out;
377 ptr->entry.name = fmb->ptr;
378 memmove(fmb->ptr, name, len);
379 tomoyo_fill_path_info(&ptr->entry); 290 tomoyo_fill_path_info(&ptr->entry);
380 fmb->ptr += len;
381 fmb->len -= len;
382 list_add_tail(&ptr->list, head); 291 list_add_tail(&ptr->list, head);
383 if (fmb->len == 0) {
384 list_del(&fmb->list);
385 kfree(fmb);
386 }
387 out: 292 out:
388 mutex_unlock(&lock); 293 mutex_unlock(&tomoyo_name_list_lock);
389 return ptr ? &ptr->entry : NULL; 294 return ptr ? &ptr->entry : NULL;
390} 295}
391 296
@@ -400,45 +305,14 @@ void __init tomoyo_realpath_init(void)
400 for (i = 0; i < TOMOYO_MAX_HASH; i++) 305 for (i = 0; i < TOMOYO_MAX_HASH; i++)
401 INIT_LIST_HEAD(&tomoyo_name_list[i]); 306 INIT_LIST_HEAD(&tomoyo_name_list[i]);
402 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list); 307 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list);
403 tomoyo_kernel_domain.domainname = tomoyo_save_name(TOMOYO_ROOT_NAME); 308 tomoyo_kernel_domain.domainname = tomoyo_get_name(TOMOYO_ROOT_NAME);
404 list_add_tail(&tomoyo_kernel_domain.list, &tomoyo_domain_list); 309 /*
405 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);
406 if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain) 314 if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain)
407 panic("Can't register tomoyo_kernel_domain"); 315 panic("Can't register tomoyo_kernel_domain");
408 up_read(&tomoyo_domain_list_lock);
409}
410
411/* Memory allocated for temporary purpose. */
412static atomic_t tomoyo_dynamic_memory_size;
413
414/**
415 * tomoyo_alloc - Allocate memory for temporary purpose.
416 *
417 * @size: Size in bytes.
418 *
419 * Returns pointer to allocated memory on success, NULL otherwise.
420 */
421void *tomoyo_alloc(const size_t size)
422{
423 void *p = kzalloc(size, GFP_KERNEL);
424 if (p)
425 atomic_add(ksize(p), &tomoyo_dynamic_memory_size);
426 return p;
427}
428
429/**
430 * tomoyo_free - Release memory allocated by tomoyo_alloc().
431 *
432 * @p: Pointer returned by tomoyo_alloc(). May be NULL.
433 *
434 * Returns nothing.
435 */
436void tomoyo_free(const void *p)
437{
438 if (p) {
439 atomic_sub(ksize(p), &tomoyo_dynamic_memory_size);
440 kfree(p);
441 }
442} 316}
443 317
444/** 318/**
@@ -451,32 +325,19 @@ void tomoyo_free(const void *p)
451int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head) 325int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head)
452{ 326{
453 if (!head->read_eof) { 327 if (!head->read_eof) {
454 const unsigned int shared 328 const unsigned int policy
455 = tomoyo_allocated_memory_for_savename; 329 = atomic_read(&tomoyo_policy_memory_size);
456 const unsigned int private
457 = tomoyo_allocated_memory_for_elements;
458 const unsigned int dynamic
459 = atomic_read(&tomoyo_dynamic_memory_size);
460 char buffer[64]; 330 char buffer[64];
461 331
462 memset(buffer, 0, sizeof(buffer)); 332 memset(buffer, 0, sizeof(buffer));
463 if (tomoyo_quota_for_savename) 333 if (tomoyo_quota_for_policy)
464 snprintf(buffer, sizeof(buffer) - 1,
465 " (Quota: %10u)",
466 tomoyo_quota_for_savename);
467 else
468 buffer[0] = '\0';
469 tomoyo_io_printf(head, "Shared: %10u%s\n", shared, buffer);
470 if (tomoyo_quota_for_elements)
471 snprintf(buffer, sizeof(buffer) - 1, 334 snprintf(buffer, sizeof(buffer) - 1,
472 " (Quota: %10u)", 335 " (Quota: %10u)",
473 tomoyo_quota_for_elements); 336 tomoyo_quota_for_policy);
474 else 337 else
475 buffer[0] = '\0'; 338 buffer[0] = '\0';
476 tomoyo_io_printf(head, "Private: %10u%s\n", private, buffer); 339 tomoyo_io_printf(head, "Policy: %10u%s\n", policy, buffer);
477 tomoyo_io_printf(head, "Dynamic: %10u\n", dynamic); 340 tomoyo_io_printf(head, "Total: %10u\n", policy);
478 tomoyo_io_printf(head, "Total: %10u\n",
479 shared + private + dynamic);
480 head->read_eof = true; 341 head->read_eof = true;
481 } 342 }
482 return 0; 343 return 0;
@@ -494,9 +355,7 @@ int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head)
494 char *data = head->write_buf; 355 char *data = head->write_buf;
495 unsigned int size; 356 unsigned int size;
496 357
497 if (sscanf(data, "Shared: %u", &size) == 1) 358 if (sscanf(data, "Policy: %u", &size) == 1)
498 tomoyo_quota_for_savename = size; 359 tomoyo_quota_for_policy = size;
499 else if (sscanf(data, "Private: %u", &size) == 1)
500 tomoyo_quota_for_elements = size;
501 return 0; 360 return 0;
502} 361}
diff --git a/security/tomoyo/realpath.h b/security/tomoyo/realpath.h
deleted file mode 100644
index 78217a37960..00000000000
--- 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 2aceebf5f35..dedd97d0c16 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,8 +84,12 @@ 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 */ 95 */
@@ -87,67 +99,56 @@ static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
87static int tomoyo_path_truncate(struct path *path, loff_t length, 99static int tomoyo_path_truncate(struct path *path, loff_t length,
88 unsigned int time_attrs) 100 unsigned int time_attrs)
89{ 101{
90 return tomoyo_check_1path_perm(tomoyo_domain(), 102 return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path);
91 TOMOYO_TYPE_TRUNCATE_ACL,
92 path);
93} 103}
94 104
95static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry) 105static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry)
96{ 106{
97 struct path path = { parent->mnt, dentry }; 107 struct path path = { parent->mnt, dentry };
98 return tomoyo_check_1path_perm(tomoyo_domain(), 108 return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path);
99 TOMOYO_TYPE_UNLINK_ACL,
100 &path);
101} 109}
102 110
103static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry, 111static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry,
104 int mode) 112 int mode)
105{ 113{
106 struct path path = { parent->mnt, dentry }; 114 struct path path = { parent->mnt, dentry };
107 return tomoyo_check_1path_perm(tomoyo_domain(), 115 return tomoyo_path_perm(TOMOYO_TYPE_MKDIR, &path);
108 TOMOYO_TYPE_MKDIR_ACL,
109 &path);
110} 116}
111 117
112static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry) 118static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry)
113{ 119{
114 struct path path = { parent->mnt, dentry }; 120 struct path path = { parent->mnt, dentry };
115 return tomoyo_check_1path_perm(tomoyo_domain(), 121 return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path);
116 TOMOYO_TYPE_RMDIR_ACL,
117 &path);
118} 122}
119 123
120static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry, 124static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry,
121 const char *old_name) 125 const char *old_name)
122{ 126{
123 struct path path = { parent->mnt, dentry }; 127 struct path path = { parent->mnt, dentry };
124 return tomoyo_check_1path_perm(tomoyo_domain(), 128 return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path);
125 TOMOYO_TYPE_SYMLINK_ACL,
126 &path);
127} 129}
128 130
129static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry, 131static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry,
130 int mode, unsigned int dev) 132 int mode, unsigned int dev)
131{ 133{
132 struct path path = { parent->mnt, dentry }; 134 struct path path = { parent->mnt, dentry };
133 int type = TOMOYO_TYPE_CREATE_ACL; 135 int type = TOMOYO_TYPE_CREATE;
134 136
135 switch (mode & S_IFMT) { 137 switch (mode & S_IFMT) {
136 case S_IFCHR: 138 case S_IFCHR:
137 type = TOMOYO_TYPE_MKCHAR_ACL; 139 type = TOMOYO_TYPE_MKCHAR;
138 break; 140 break;
139 case S_IFBLK: 141 case S_IFBLK:
140 type = TOMOYO_TYPE_MKBLOCK_ACL; 142 type = TOMOYO_TYPE_MKBLOCK;
141 break; 143 break;
142 case S_IFIFO: 144 case S_IFIFO:
143 type = TOMOYO_TYPE_MKFIFO_ACL; 145 type = TOMOYO_TYPE_MKFIFO;
144 break; 146 break;
145 case S_IFSOCK: 147 case S_IFSOCK:
146 type = TOMOYO_TYPE_MKSOCK_ACL; 148 type = TOMOYO_TYPE_MKSOCK;
147 break; 149 break;
148 } 150 }
149 return tomoyo_check_1path_perm(tomoyo_domain(), 151 return tomoyo_path_perm(type, &path);
150 type, &path);
151} 152}
152 153
153static 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,
@@ -155,9 +156,7 @@ static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir,
155{ 156{
156 struct path path1 = { new_dir->mnt, old_dentry }; 157 struct path path1 = { new_dir->mnt, old_dentry };
157 struct path path2 = { new_dir->mnt, new_dentry }; 158 struct path path2 = { new_dir->mnt, new_dentry };
158 return tomoyo_check_2path_perm(tomoyo_domain(), 159 return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2);
159 TOMOYO_TYPE_LINK_ACL,
160 &path1, &path2);
161} 160}
162 161
163static int tomoyo_path_rename(struct path *old_parent, 162static int tomoyo_path_rename(struct path *old_parent,
@@ -167,16 +166,14 @@ static int tomoyo_path_rename(struct path *old_parent,
167{ 166{
168 struct path path1 = { old_parent->mnt, old_dentry }; 167 struct path path1 = { old_parent->mnt, old_dentry };
169 struct path path2 = { new_parent->mnt, new_dentry }; 168 struct path path2 = { new_parent->mnt, new_dentry };
170 return tomoyo_check_2path_perm(tomoyo_domain(), 169 return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2);
171 TOMOYO_TYPE_RENAME_ACL,
172 &path1, &path2);
173} 170}
174 171
175static int tomoyo_file_fcntl(struct file *file, unsigned int cmd, 172static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
176 unsigned long arg) 173 unsigned long arg)
177{ 174{
178 if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)) 175 if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND))
179 return tomoyo_check_rewrite_permission(tomoyo_domain(), file); 176 return tomoyo_check_rewrite_permission(file);
180 return 0; 177 return 0;
181} 178}
182 179
@@ -189,6 +186,51 @@ static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
189 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags); 186 return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags);
190} 187}
191 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
192/* 234/*
193 * 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
194 * registering TOMOYO. 236 * registering TOMOYO.
@@ -198,6 +240,7 @@ static struct security_operations tomoyo_security_ops = {
198 .cred_alloc_blank = tomoyo_cred_alloc_blank, 240 .cred_alloc_blank = tomoyo_cred_alloc_blank,
199 .cred_prepare = tomoyo_cred_prepare, 241 .cred_prepare = tomoyo_cred_prepare,
200 .cred_transfer = tomoyo_cred_transfer, 242 .cred_transfer = tomoyo_cred_transfer,
243 .cred_free = tomoyo_cred_free,
201 .bprm_set_creds = tomoyo_bprm_set_creds, 244 .bprm_set_creds = tomoyo_bprm_set_creds,
202 .bprm_check_security = tomoyo_bprm_check_security, 245 .bprm_check_security = tomoyo_bprm_check_security,
203 .file_fcntl = tomoyo_file_fcntl, 246 .file_fcntl = tomoyo_file_fcntl,
@@ -210,8 +253,18 @@ static struct security_operations tomoyo_security_ops = {
210 .path_mknod = tomoyo_path_mknod, 253 .path_mknod = tomoyo_path_mknod,
211 .path_link = tomoyo_path_link, 254 .path_link = tomoyo_path_link,
212 .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,
213}; 263};
214 264
265/* Lock for GC. */
266struct srcu_struct tomoyo_ss;
267
215static int __init tomoyo_init(void) 268static int __init tomoyo_init(void)
216{ 269{
217 struct cred *cred = (struct cred *) current_cred(); 270 struct cred *cred = (struct cred *) current_cred();
@@ -219,7 +272,8 @@ static int __init tomoyo_init(void)
219 if (!security_module_enable(&tomoyo_security_ops)) 272 if (!security_module_enable(&tomoyo_security_ops))
220 return 0; 273 return 0;
221 /* register ourselves with the security framework */ 274 /* register ourselves with the security framework */
222 if (register_security(&tomoyo_security_ops)) 275 if (register_security(&tomoyo_security_ops) ||
276 init_srcu_struct(&tomoyo_ss))
223 panic("Failure registering TOMOYO Linux"); 277 panic("Failure registering TOMOYO Linux");
224 printk(KERN_INFO "TOMOYO Linux initialized\n"); 278 printk(KERN_INFO "TOMOYO Linux initialized\n");
225 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 ed758325b1a..00000000000
--- a/security/tomoyo/tomoyo.h
+++ /dev/null
@@ -1,94 +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_exec_perm(struct tomoyo_domain_info *domain,
22 const struct tomoyo_path_info *filename);
23int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
24 struct path *path, const int flag);
25int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain,
26 const u8 operation, struct path *path);
27int tomoyo_check_2path_perm(struct tomoyo_domain_info *domain,
28 const u8 operation, struct path *path1,
29 struct path *path2);
30int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain,
31 struct file *filp);
32int tomoyo_find_next_domain(struct linux_binprm *bprm);
33
34/* Index numbers for Access Controls. */
35
36#define TOMOYO_TYPE_SINGLE_PATH_ACL 0
37#define TOMOYO_TYPE_DOUBLE_PATH_ACL 1
38
39/* Index numbers for File Controls. */
40
41/*
42 * TYPE_READ_WRITE_ACL is special. TYPE_READ_WRITE_ACL is automatically set
43 * if both TYPE_READ_ACL and TYPE_WRITE_ACL are set. Both TYPE_READ_ACL and
44 * TYPE_WRITE_ACL are automatically set if TYPE_READ_WRITE_ACL is set.
45 * TYPE_READ_WRITE_ACL is automatically cleared if either TYPE_READ_ACL or
46 * TYPE_WRITE_ACL is cleared. Both TYPE_READ_ACL and TYPE_WRITE_ACL are
47 * automatically cleared if TYPE_READ_WRITE_ACL is cleared.
48 */
49
50#define TOMOYO_TYPE_READ_WRITE_ACL 0
51#define TOMOYO_TYPE_EXECUTE_ACL 1
52#define TOMOYO_TYPE_READ_ACL 2
53#define TOMOYO_TYPE_WRITE_ACL 3
54#define TOMOYO_TYPE_CREATE_ACL 4
55#define TOMOYO_TYPE_UNLINK_ACL 5
56#define TOMOYO_TYPE_MKDIR_ACL 6
57#define TOMOYO_TYPE_RMDIR_ACL 7
58#define TOMOYO_TYPE_MKFIFO_ACL 8
59#define TOMOYO_TYPE_MKSOCK_ACL 9
60#define TOMOYO_TYPE_MKBLOCK_ACL 10
61#define TOMOYO_TYPE_MKCHAR_ACL 11
62#define TOMOYO_TYPE_TRUNCATE_ACL 12
63#define TOMOYO_TYPE_SYMLINK_ACL 13
64#define TOMOYO_TYPE_REWRITE_ACL 14
65#define TOMOYO_MAX_SINGLE_PATH_OPERATION 15
66
67#define TOMOYO_TYPE_LINK_ACL 0
68#define TOMOYO_TYPE_RENAME_ACL 1
69#define TOMOYO_MAX_DOUBLE_PATH_OPERATION 2
70
71#define TOMOYO_DOMAINPOLICY 0
72#define TOMOYO_EXCEPTIONPOLICY 1
73#define TOMOYO_DOMAIN_STATUS 2
74#define TOMOYO_PROCESS_STATUS 3
75#define TOMOYO_MEMINFO 4
76#define TOMOYO_SELFDOMAIN 5
77#define TOMOYO_VERSION 6
78#define TOMOYO_PROFILE 7
79#define TOMOYO_MANAGER 8
80
81extern struct tomoyo_domain_info tomoyo_kernel_domain;
82
83static inline struct tomoyo_domain_info *tomoyo_domain(void)
84{
85 return current_cred()->security;
86}
87
88static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct
89 *task)
90{
91 return task_cred_xxx(task, security);
92}
93
94#endif /* !defined(_SECURITY_TOMOYO_TOMOYO_H) */