aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/file.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /security/tomoyo/file.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'security/tomoyo/file.c')
-rw-r--r--security/tomoyo/file.c754
1 files changed, 350 insertions, 404 deletions
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 5ae3a571559f..6f3fe76a1fde 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -10,109 +10,65 @@
10 */ 10 */
11 11
12#include "common.h" 12#include "common.h"
13#include "tomoyo.h" 13#include <linux/slab.h>
14#include "realpath.h"
15#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
16
17/*
18 * tomoyo_globally_readable_file_entry is a structure which is used for holding
19 * "allow_read" entries.
20 * It has following fields.
21 *
22 * (1) "list" which is linked to tomoyo_globally_readable_list .
23 * (2) "filename" is a pathname which is allowed to open(O_RDONLY).
24 * (3) "is_deleted" is a bool which is true if marked as deleted, false
25 * otherwise.
26 */
27struct tomoyo_globally_readable_file_entry {
28 struct list_head list;
29 const struct tomoyo_path_info *filename;
30 bool is_deleted;
31};
32
33/*
34 * tomoyo_pattern_entry is a structure which is used for holding
35 * "tomoyo_pattern_list" entries.
36 * It has following fields.
37 *
38 * (1) "list" which is linked to tomoyo_pattern_list .
39 * (2) "pattern" is a pathname pattern which is used for converting pathnames
40 * to pathname patterns during learning mode.
41 * (3) "is_deleted" is a bool which is true if marked as deleted, false
42 * otherwise.
43 */
44struct tomoyo_pattern_entry {
45 struct list_head list;
46 const struct tomoyo_path_info *pattern;
47 bool is_deleted;
48};
49
50/*
51 * tomoyo_no_rewrite_entry is a structure which is used for holding
52 * "deny_rewrite" entries.
53 * It has following fields.
54 *
55 * (1) "list" which is linked to tomoyo_no_rewrite_list .
56 * (2) "pattern" is a pathname which is by default not permitted to modify
57 * already existing content.
58 * (3) "is_deleted" is a bool which is true if marked as deleted, false
59 * otherwise.
60 */
61struct tomoyo_no_rewrite_entry {
62 struct list_head list;
63 const struct tomoyo_path_info *pattern;
64 bool is_deleted;
65};
66 14
67/* Keyword array for single path operations. */ 15/* Keyword array for single path operations. */
68static const char *tomoyo_sp_keyword[TOMOYO_MAX_SINGLE_PATH_OPERATION] = { 16static const char *tomoyo_path_keyword[TOMOYO_MAX_PATH_OPERATION] = {
69 [TOMOYO_TYPE_READ_WRITE_ACL] = "read/write", 17 [TOMOYO_TYPE_READ_WRITE] = "read/write",
70 [TOMOYO_TYPE_EXECUTE_ACL] = "execute", 18 [TOMOYO_TYPE_EXECUTE] = "execute",
71 [TOMOYO_TYPE_READ_ACL] = "read", 19 [TOMOYO_TYPE_READ] = "read",
72 [TOMOYO_TYPE_WRITE_ACL] = "write", 20 [TOMOYO_TYPE_WRITE] = "write",
73 [TOMOYO_TYPE_CREATE_ACL] = "create", 21 [TOMOYO_TYPE_CREATE] = "create",
74 [TOMOYO_TYPE_UNLINK_ACL] = "unlink", 22 [TOMOYO_TYPE_UNLINK] = "unlink",
75 [TOMOYO_TYPE_MKDIR_ACL] = "mkdir", 23 [TOMOYO_TYPE_MKDIR] = "mkdir",
76 [TOMOYO_TYPE_RMDIR_ACL] = "rmdir", 24 [TOMOYO_TYPE_RMDIR] = "rmdir",
77 [TOMOYO_TYPE_MKFIFO_ACL] = "mkfifo", 25 [TOMOYO_TYPE_MKFIFO] = "mkfifo",
78 [TOMOYO_TYPE_MKSOCK_ACL] = "mksock", 26 [TOMOYO_TYPE_MKSOCK] = "mksock",
79 [TOMOYO_TYPE_MKBLOCK_ACL] = "mkblock", 27 [TOMOYO_TYPE_MKBLOCK] = "mkblock",
80 [TOMOYO_TYPE_MKCHAR_ACL] = "mkchar", 28 [TOMOYO_TYPE_MKCHAR] = "mkchar",
81 [TOMOYO_TYPE_TRUNCATE_ACL] = "truncate", 29 [TOMOYO_TYPE_TRUNCATE] = "truncate",
82 [TOMOYO_TYPE_SYMLINK_ACL] = "symlink", 30 [TOMOYO_TYPE_SYMLINK] = "symlink",
83 [TOMOYO_TYPE_REWRITE_ACL] = "rewrite", 31 [TOMOYO_TYPE_REWRITE] = "rewrite",
32 [TOMOYO_TYPE_IOCTL] = "ioctl",
33 [TOMOYO_TYPE_CHMOD] = "chmod",
34 [TOMOYO_TYPE_CHOWN] = "chown",
35 [TOMOYO_TYPE_CHGRP] = "chgrp",
36 [TOMOYO_TYPE_CHROOT] = "chroot",
37 [TOMOYO_TYPE_MOUNT] = "mount",
38 [TOMOYO_TYPE_UMOUNT] = "unmount",
84}; 39};
85 40
86/* Keyword array for double path operations. */ 41/* Keyword array for double path operations. */
87static const char *tomoyo_dp_keyword[TOMOYO_MAX_DOUBLE_PATH_OPERATION] = { 42static const char *tomoyo_path2_keyword[TOMOYO_MAX_PATH2_OPERATION] = {
88 [TOMOYO_TYPE_LINK_ACL] = "link", 43 [TOMOYO_TYPE_LINK] = "link",
89 [TOMOYO_TYPE_RENAME_ACL] = "rename", 44 [TOMOYO_TYPE_RENAME] = "rename",
45 [TOMOYO_TYPE_PIVOT_ROOT] = "pivot_root",
90}; 46};
91 47
92/** 48/**
93 * tomoyo_sp2keyword - Get the name of single path operation. 49 * tomoyo_path2keyword - Get the name of single path operation.
94 * 50 *
95 * @operation: Type of operation. 51 * @operation: Type of operation.
96 * 52 *
97 * Returns the name of single path operation. 53 * Returns the name of single path operation.
98 */ 54 */
99const char *tomoyo_sp2keyword(const u8 operation) 55const char *tomoyo_path2keyword(const u8 operation)
100{ 56{
101 return (operation < TOMOYO_MAX_SINGLE_PATH_OPERATION) 57 return (operation < TOMOYO_MAX_PATH_OPERATION)
102 ? tomoyo_sp_keyword[operation] : NULL; 58 ? tomoyo_path_keyword[operation] : NULL;
103} 59}
104 60
105/** 61/**
106 * tomoyo_dp2keyword - Get the name of double path operation. 62 * tomoyo_path22keyword - Get the name of double path operation.
107 * 63 *
108 * @operation: Type of operation. 64 * @operation: Type of operation.
109 * 65 *
110 * Returns the name of double path operation. 66 * Returns the name of double path operation.
111 */ 67 */
112const char *tomoyo_dp2keyword(const u8 operation) 68const char *tomoyo_path22keyword(const u8 operation)
113{ 69{
114 return (operation < TOMOYO_MAX_DOUBLE_PATH_OPERATION) 70 return (operation < TOMOYO_MAX_PATH2_OPERATION)
115 ? tomoyo_dp_keyword[operation] : NULL; 71 ? tomoyo_path2_keyword[operation] : NULL;
116} 72}
117 73
118/** 74/**
@@ -143,7 +99,8 @@ static bool tomoyo_strendswith(const char *name, const char *tail)
143static struct tomoyo_path_info *tomoyo_get_path(struct path *path) 99static struct tomoyo_path_info *tomoyo_get_path(struct path *path)
144{ 100{
145 int error; 101 int error;
146 struct tomoyo_path_info_with_data *buf = tomoyo_alloc(sizeof(*buf)); 102 struct tomoyo_path_info_with_data *buf = kzalloc(sizeof(*buf),
103 GFP_KERNEL);
147 104
148 if (!buf) 105 if (!buf)
149 return NULL; 106 return NULL;
@@ -155,20 +112,17 @@ static struct tomoyo_path_info *tomoyo_get_path(struct path *path)
155 tomoyo_fill_path_info(&buf->head); 112 tomoyo_fill_path_info(&buf->head);
156 return &buf->head; 113 return &buf->head;
157 } 114 }
158 tomoyo_free(buf); 115 kfree(buf);
159 return NULL; 116 return NULL;
160} 117}
161 118
162/* Lock for domain->acl_info_list. */ 119static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
163DECLARE_RWSEM(tomoyo_domain_acl_info_list_lock); 120 const char *filename2,
164 121 struct tomoyo_domain_info *const domain,
165static int tomoyo_update_double_path_acl(const u8 type, const char *filename1, 122 const bool is_delete);
166 const char *filename2, 123static int tomoyo_update_path_acl(const u8 type, const char *filename,
167 struct tomoyo_domain_info * 124 struct tomoyo_domain_info *const domain,
168 const domain, const bool is_delete); 125 const bool is_delete);
169static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
170 struct tomoyo_domain_info *
171 const domain, const bool is_delete);
172 126
173/* 127/*
174 * tomoyo_globally_readable_list is used for holding list of pathnames which 128 * tomoyo_globally_readable_list is used for holding list of pathnames which
@@ -195,8 +149,7 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
195 * given "allow_read /lib/libc-2.5.so" to the domain which current process 149 * given "allow_read /lib/libc-2.5.so" to the domain which current process
196 * belongs to. 150 * belongs to.
197 */ 151 */
198static LIST_HEAD(tomoyo_globally_readable_list); 152LIST_HEAD(tomoyo_globally_readable_list);
199static DECLARE_RWSEM(tomoyo_globally_readable_list_lock);
200 153
201/** 154/**
202 * tomoyo_update_globally_readable_entry - Update "struct tomoyo_globally_readable_file_entry" list. 155 * tomoyo_update_globally_readable_entry - Update "struct tomoyo_globally_readable_file_entry" list.
@@ -205,40 +158,42 @@ static DECLARE_RWSEM(tomoyo_globally_readable_list_lock);
205 * @is_delete: True if it is a delete request. 158 * @is_delete: True if it is a delete request.
206 * 159 *
207 * Returns 0 on success, negative value otherwise. 160 * Returns 0 on success, negative value otherwise.
161 *
162 * Caller holds tomoyo_read_lock().
208 */ 163 */
209static int tomoyo_update_globally_readable_entry(const char *filename, 164static int tomoyo_update_globally_readable_entry(const char *filename,
210 const bool is_delete) 165 const bool is_delete)
211{ 166{
212 struct tomoyo_globally_readable_file_entry *new_entry; 167 struct tomoyo_globally_readable_file_entry *entry = NULL;
213 struct tomoyo_globally_readable_file_entry *ptr; 168 struct tomoyo_globally_readable_file_entry *ptr;
214 const struct tomoyo_path_info *saved_filename; 169 const struct tomoyo_path_info *saved_filename;
215 int error = -ENOMEM; 170 int error = is_delete ? -ENOENT : -ENOMEM;
216 171
217 if (!tomoyo_is_correct_path(filename, 1, 0, -1, __func__)) 172 if (!tomoyo_is_correct_path(filename, 1, 0, -1))
218 return -EINVAL; 173 return -EINVAL;
219 saved_filename = tomoyo_save_name(filename); 174 saved_filename = tomoyo_get_name(filename);
220 if (!saved_filename) 175 if (!saved_filename)
221 return -ENOMEM; 176 return -ENOMEM;
222 down_write(&tomoyo_globally_readable_list_lock); 177 if (!is_delete)
223 list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) { 178 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
179 mutex_lock(&tomoyo_policy_lock);
180 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
224 if (ptr->filename != saved_filename) 181 if (ptr->filename != saved_filename)
225 continue; 182 continue;
226 ptr->is_deleted = is_delete; 183 ptr->is_deleted = is_delete;
227 error = 0; 184 error = 0;
228 goto out; 185 break;
229 } 186 }
230 if (is_delete) { 187 if (!is_delete && error && tomoyo_memory_ok(entry)) {
231 error = -ENOENT; 188 entry->filename = saved_filename;
232 goto out; 189 saved_filename = NULL;
190 list_add_tail_rcu(&entry->list, &tomoyo_globally_readable_list);
191 entry = NULL;
192 error = 0;
233 } 193 }
234 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 194 mutex_unlock(&tomoyo_policy_lock);
235 if (!new_entry) 195 tomoyo_put_name(saved_filename);
236 goto out; 196 kfree(entry);
237 new_entry->filename = saved_filename;
238 list_add_tail(&new_entry->list, &tomoyo_globally_readable_list);
239 error = 0;
240 out:
241 up_write(&tomoyo_globally_readable_list_lock);
242 return error; 197 return error;
243} 198}
244 199
@@ -248,21 +203,22 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
248 * @filename: The filename to check. 203 * @filename: The filename to check.
249 * 204 *
250 * Returns true if any domain can open @filename for reading, false otherwise. 205 * Returns true if any domain can open @filename for reading, false otherwise.
206 *
207 * Caller holds tomoyo_read_lock().
251 */ 208 */
252static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info * 209static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info *
253 filename) 210 filename)
254{ 211{
255 struct tomoyo_globally_readable_file_entry *ptr; 212 struct tomoyo_globally_readable_file_entry *ptr;
256 bool found = false; 213 bool found = false;
257 down_read(&tomoyo_globally_readable_list_lock); 214
258 list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) { 215 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
259 if (!ptr->is_deleted && 216 if (!ptr->is_deleted &&
260 tomoyo_path_matches_pattern(filename, ptr->filename)) { 217 tomoyo_path_matches_pattern(filename, ptr->filename)) {
261 found = true; 218 found = true;
262 break; 219 break;
263 } 220 }
264 } 221 }
265 up_read(&tomoyo_globally_readable_list_lock);
266 return found; 222 return found;
267} 223}
268 224
@@ -273,6 +229,8 @@ static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info *
273 * @is_delete: True if it is a delete request. 229 * @is_delete: True if it is a delete request.
274 * 230 *
275 * Returns 0 on success, negative value otherwise. 231 * Returns 0 on success, negative value otherwise.
232 *
233 * Caller holds tomoyo_read_lock().
276 */ 234 */
277int tomoyo_write_globally_readable_policy(char *data, const bool is_delete) 235int tomoyo_write_globally_readable_policy(char *data, const bool is_delete)
278{ 236{
@@ -285,13 +243,14 @@ int tomoyo_write_globally_readable_policy(char *data, const bool is_delete)
285 * @head: Pointer to "struct tomoyo_io_buffer". 243 * @head: Pointer to "struct tomoyo_io_buffer".
286 * 244 *
287 * Returns true on success, false otherwise. 245 * Returns true on success, false otherwise.
246 *
247 * Caller holds tomoyo_read_lock().
288 */ 248 */
289bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head) 249bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
290{ 250{
291 struct list_head *pos; 251 struct list_head *pos;
292 bool done = true; 252 bool done = true;
293 253
294 down_read(&tomoyo_globally_readable_list_lock);
295 list_for_each_cookie(pos, head->read_var2, 254 list_for_each_cookie(pos, head->read_var2,
296 &tomoyo_globally_readable_list) { 255 &tomoyo_globally_readable_list) {
297 struct tomoyo_globally_readable_file_entry *ptr; 256 struct tomoyo_globally_readable_file_entry *ptr;
@@ -305,7 +264,6 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
305 if (!done) 264 if (!done)
306 break; 265 break;
307 } 266 }
308 up_read(&tomoyo_globally_readable_list_lock);
309 return done; 267 return done;
310} 268}
311 269
@@ -338,8 +296,7 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
338 * which pretends as if /proc/self/ is not a symlink; so that we can forbid 296 * which pretends as if /proc/self/ is not a symlink; so that we can forbid
339 * current process from accessing other process's information. 297 * current process from accessing other process's information.
340 */ 298 */
341static LIST_HEAD(tomoyo_pattern_list); 299LIST_HEAD(tomoyo_pattern_list);
342static DECLARE_RWSEM(tomoyo_pattern_list_lock);
343 300
344/** 301/**
345 * tomoyo_update_file_pattern_entry - Update "struct tomoyo_pattern_entry" list. 302 * tomoyo_update_file_pattern_entry - Update "struct tomoyo_pattern_entry" list.
@@ -348,40 +305,43 @@ static DECLARE_RWSEM(tomoyo_pattern_list_lock);
348 * @is_delete: True if it is a delete request. 305 * @is_delete: True if it is a delete request.
349 * 306 *
350 * Returns 0 on success, negative value otherwise. 307 * Returns 0 on success, negative value otherwise.
308 *
309 * Caller holds tomoyo_read_lock().
351 */ 310 */
352static int tomoyo_update_file_pattern_entry(const char *pattern, 311static int tomoyo_update_file_pattern_entry(const char *pattern,
353 const bool is_delete) 312 const bool is_delete)
354{ 313{
355 struct tomoyo_pattern_entry *new_entry; 314 struct tomoyo_pattern_entry *entry = NULL;
356 struct tomoyo_pattern_entry *ptr; 315 struct tomoyo_pattern_entry *ptr;
357 const struct tomoyo_path_info *saved_pattern; 316 const struct tomoyo_path_info *saved_pattern;
358 int error = -ENOMEM; 317 int error = is_delete ? -ENOENT : -ENOMEM;
359 318
360 if (!tomoyo_is_correct_path(pattern, 0, 1, 0, __func__)) 319 saved_pattern = tomoyo_get_name(pattern);
361 return -EINVAL;
362 saved_pattern = tomoyo_save_name(pattern);
363 if (!saved_pattern) 320 if (!saved_pattern)
364 return -ENOMEM; 321 return error;
365 down_write(&tomoyo_pattern_list_lock); 322 if (!saved_pattern->is_patterned)
366 list_for_each_entry(ptr, &tomoyo_pattern_list, list) { 323 goto out;
324 if (!is_delete)
325 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
326 mutex_lock(&tomoyo_policy_lock);
327 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
367 if (saved_pattern != ptr->pattern) 328 if (saved_pattern != ptr->pattern)
368 continue; 329 continue;
369 ptr->is_deleted = is_delete; 330 ptr->is_deleted = is_delete;
370 error = 0; 331 error = 0;
371 goto out; 332 break;
372 } 333 }
373 if (is_delete) { 334 if (!is_delete && error && tomoyo_memory_ok(entry)) {
374 error = -ENOENT; 335 entry->pattern = saved_pattern;
375 goto out; 336 saved_pattern = NULL;
337 list_add_tail_rcu(&entry->list, &tomoyo_pattern_list);
338 entry = NULL;
339 error = 0;
376 } 340 }
377 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 341 mutex_unlock(&tomoyo_policy_lock);
378 if (!new_entry)
379 goto out;
380 new_entry->pattern = saved_pattern;
381 list_add_tail(&new_entry->list, &tomoyo_pattern_list);
382 error = 0;
383 out: 342 out:
384 up_write(&tomoyo_pattern_list_lock); 343 kfree(entry);
344 tomoyo_put_name(saved_pattern);
385 return error; 345 return error;
386} 346}
387 347
@@ -391,6 +351,8 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
391 * @filename: The filename to find patterned pathname. 351 * @filename: The filename to find patterned pathname.
392 * 352 *
393 * Returns pointer to pathname pattern if matched, @filename otherwise. 353 * Returns pointer to pathname pattern if matched, @filename otherwise.
354 *
355 * Caller holds tomoyo_read_lock().
394 */ 356 */
395static const struct tomoyo_path_info * 357static const struct tomoyo_path_info *
396tomoyo_get_file_pattern(const struct tomoyo_path_info *filename) 358tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
@@ -398,8 +360,7 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
398 struct tomoyo_pattern_entry *ptr; 360 struct tomoyo_pattern_entry *ptr;
399 const struct tomoyo_path_info *pattern = NULL; 361 const struct tomoyo_path_info *pattern = NULL;
400 362
401 down_read(&tomoyo_pattern_list_lock); 363 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
402 list_for_each_entry(ptr, &tomoyo_pattern_list, list) {
403 if (ptr->is_deleted) 364 if (ptr->is_deleted)
404 continue; 365 continue;
405 if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) 366 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
@@ -412,7 +373,6 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
412 break; 373 break;
413 } 374 }
414 } 375 }
415 up_read(&tomoyo_pattern_list_lock);
416 if (pattern) 376 if (pattern)
417 filename = pattern; 377 filename = pattern;
418 return filename; 378 return filename;
@@ -425,6 +385,8 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
425 * @is_delete: True if it is a delete request. 385 * @is_delete: True if it is a delete request.
426 * 386 *
427 * Returns 0 on success, negative value otherwise. 387 * Returns 0 on success, negative value otherwise.
388 *
389 * Caller holds tomoyo_read_lock().
428 */ 390 */
429int tomoyo_write_pattern_policy(char *data, const bool is_delete) 391int tomoyo_write_pattern_policy(char *data, const bool is_delete)
430{ 392{
@@ -437,13 +399,14 @@ int tomoyo_write_pattern_policy(char *data, const bool is_delete)
437 * @head: Pointer to "struct tomoyo_io_buffer". 399 * @head: Pointer to "struct tomoyo_io_buffer".
438 * 400 *
439 * Returns true on success, false otherwise. 401 * Returns true on success, false otherwise.
402 *
403 * Caller holds tomoyo_read_lock().
440 */ 404 */
441bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head) 405bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
442{ 406{
443 struct list_head *pos; 407 struct list_head *pos;
444 bool done = true; 408 bool done = true;
445 409
446 down_read(&tomoyo_pattern_list_lock);
447 list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) { 410 list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) {
448 struct tomoyo_pattern_entry *ptr; 411 struct tomoyo_pattern_entry *ptr;
449 ptr = list_entry(pos, struct tomoyo_pattern_entry, list); 412 ptr = list_entry(pos, struct tomoyo_pattern_entry, list);
@@ -454,7 +417,6 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
454 if (!done) 417 if (!done)
455 break; 418 break;
456 } 419 }
457 up_read(&tomoyo_pattern_list_lock);
458 return done; 420 return done;
459} 421}
460 422
@@ -487,8 +449,7 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
487 * " (deleted)" suffix if the file is already unlink()ed; so that we don't 449 * " (deleted)" suffix if the file is already unlink()ed; so that we don't
488 * need to worry whether the file is already unlink()ed or not. 450 * need to worry whether the file is already unlink()ed or not.
489 */ 451 */
490static LIST_HEAD(tomoyo_no_rewrite_list); 452LIST_HEAD(tomoyo_no_rewrite_list);
491static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock);
492 453
493/** 454/**
494 * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite_entry" list. 455 * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite_entry" list.
@@ -497,39 +458,42 @@ static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock);
497 * @is_delete: True if it is a delete request. 458 * @is_delete: True if it is a delete request.
498 * 459 *
499 * Returns 0 on success, negative value otherwise. 460 * Returns 0 on success, negative value otherwise.
461 *
462 * Caller holds tomoyo_read_lock().
500 */ 463 */
501static int tomoyo_update_no_rewrite_entry(const char *pattern, 464static int tomoyo_update_no_rewrite_entry(const char *pattern,
502 const bool is_delete) 465 const bool is_delete)
503{ 466{
504 struct tomoyo_no_rewrite_entry *new_entry, *ptr; 467 struct tomoyo_no_rewrite_entry *entry = NULL;
468 struct tomoyo_no_rewrite_entry *ptr;
505 const struct tomoyo_path_info *saved_pattern; 469 const struct tomoyo_path_info *saved_pattern;
506 int error = -ENOMEM; 470 int error = is_delete ? -ENOENT : -ENOMEM;
507 471
508 if (!tomoyo_is_correct_path(pattern, 0, 0, 0, __func__)) 472 if (!tomoyo_is_correct_path(pattern, 0, 0, 0))
509 return -EINVAL; 473 return -EINVAL;
510 saved_pattern = tomoyo_save_name(pattern); 474 saved_pattern = tomoyo_get_name(pattern);
511 if (!saved_pattern) 475 if (!saved_pattern)
512 return -ENOMEM; 476 return error;
513 down_write(&tomoyo_no_rewrite_list_lock); 477 if (!is_delete)
514 list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) { 478 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
479 mutex_lock(&tomoyo_policy_lock);
480 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
515 if (ptr->pattern != saved_pattern) 481 if (ptr->pattern != saved_pattern)
516 continue; 482 continue;
517 ptr->is_deleted = is_delete; 483 ptr->is_deleted = is_delete;
518 error = 0; 484 error = 0;
519 goto out; 485 break;
520 } 486 }
521 if (is_delete) { 487 if (!is_delete && error && tomoyo_memory_ok(entry)) {
522 error = -ENOENT; 488 entry->pattern = saved_pattern;
523 goto out; 489 saved_pattern = NULL;
490 list_add_tail_rcu(&entry->list, &tomoyo_no_rewrite_list);
491 entry = NULL;
492 error = 0;
524 } 493 }
525 new_entry = tomoyo_alloc_element(sizeof(*new_entry)); 494 mutex_unlock(&tomoyo_policy_lock);
526 if (!new_entry) 495 tomoyo_put_name(saved_pattern);
527 goto out; 496 kfree(entry);
528 new_entry->pattern = saved_pattern;
529 list_add_tail(&new_entry->list, &tomoyo_no_rewrite_list);
530 error = 0;
531 out:
532 up_write(&tomoyo_no_rewrite_list_lock);
533 return error; 497 return error;
534} 498}
535 499
@@ -540,14 +504,15 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
540 * 504 *
541 * Returns true if @filename is specified by "deny_rewrite" directive, 505 * Returns true if @filename is specified by "deny_rewrite" directive,
542 * false otherwise. 506 * false otherwise.
507 *
508 * Caller holds tomoyo_read_lock().
543 */ 509 */
544static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename) 510static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
545{ 511{
546 struct tomoyo_no_rewrite_entry *ptr; 512 struct tomoyo_no_rewrite_entry *ptr;
547 bool found = false; 513 bool found = false;
548 514
549 down_read(&tomoyo_no_rewrite_list_lock); 515 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
550 list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) {
551 if (ptr->is_deleted) 516 if (ptr->is_deleted)
552 continue; 517 continue;
553 if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) 518 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
@@ -555,7 +520,6 @@ static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
555 found = true; 520 found = true;
556 break; 521 break;
557 } 522 }
558 up_read(&tomoyo_no_rewrite_list_lock);
559 return found; 523 return found;
560} 524}
561 525
@@ -566,6 +530,8 @@ static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
566 * @is_delete: True if it is a delete request. 530 * @is_delete: True if it is a delete request.
567 * 531 *
568 * Returns 0 on success, negative value otherwise. 532 * Returns 0 on success, negative value otherwise.
533 *
534 * Caller holds tomoyo_read_lock().
569 */ 535 */
570int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete) 536int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete)
571{ 537{
@@ -578,13 +544,14 @@ int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete)
578 * @head: Pointer to "struct tomoyo_io_buffer". 544 * @head: Pointer to "struct tomoyo_io_buffer".
579 * 545 *
580 * Returns true on success, false otherwise. 546 * Returns true on success, false otherwise.
547 *
548 * Caller holds tomoyo_read_lock().
581 */ 549 */
582bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head) 550bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
583{ 551{
584 struct list_head *pos; 552 struct list_head *pos;
585 bool done = true; 553 bool done = true;
586 554
587 down_read(&tomoyo_no_rewrite_list_lock);
588 list_for_each_cookie(pos, head->read_var2, &tomoyo_no_rewrite_list) { 555 list_for_each_cookie(pos, head->read_var2, &tomoyo_no_rewrite_list) {
589 struct tomoyo_no_rewrite_entry *ptr; 556 struct tomoyo_no_rewrite_entry *ptr;
590 ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list); 557 ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list);
@@ -595,7 +562,6 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
595 if (!done) 562 if (!done)
596 break; 563 break;
597 } 564 }
598 up_read(&tomoyo_no_rewrite_list_lock);
599 return done; 565 return done;
600} 566}
601 567
@@ -613,6 +579,8 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
613 * Current policy syntax uses "allow_read/write" instead of "6", 579 * Current policy syntax uses "allow_read/write" instead of "6",
614 * "allow_read" instead of "4", "allow_write" instead of "2", 580 * "allow_read" instead of "4", "allow_write" instead of "2",
615 * "allow_execute" instead of "1". 581 * "allow_execute" instead of "1".
582 *
583 * Caller holds tomoyo_read_lock().
616 */ 584 */
617static int tomoyo_update_file_acl(const char *filename, u8 perm, 585static int tomoyo_update_file_acl(const char *filename, u8 perm,
618 struct tomoyo_domain_info * const domain, 586 struct tomoyo_domain_info * const domain,
@@ -630,19 +598,19 @@ static int tomoyo_update_file_acl(const char *filename, u8 perm,
630 */ 598 */
631 return 0; 599 return 0;
632 if (perm & 4) 600 if (perm & 4)
633 tomoyo_update_single_path_acl(TOMOYO_TYPE_READ_ACL, filename, 601 tomoyo_update_path_acl(TOMOYO_TYPE_READ, filename, domain,
634 domain, is_delete); 602 is_delete);
635 if (perm & 2) 603 if (perm & 2)
636 tomoyo_update_single_path_acl(TOMOYO_TYPE_WRITE_ACL, filename, 604 tomoyo_update_path_acl(TOMOYO_TYPE_WRITE, filename, domain,
637 domain, is_delete); 605 is_delete);
638 if (perm & 1) 606 if (perm & 1)
639 tomoyo_update_single_path_acl(TOMOYO_TYPE_EXECUTE_ACL, 607 tomoyo_update_path_acl(TOMOYO_TYPE_EXECUTE, filename, domain,
640 filename, domain, is_delete); 608 is_delete);
641 return 0; 609 return 0;
642} 610}
643 611
644/** 612/**
645 * tomoyo_check_single_path_acl2 - Check permission for single path operation. 613 * tomoyo_path_acl2 - Check permission for single path operation.
646 * 614 *
647 * @domain: Pointer to "struct tomoyo_domain_info". 615 * @domain: Pointer to "struct tomoyo_domain_info".
648 * @filename: Filename to check. 616 * @filename: Filename to check.
@@ -650,26 +618,28 @@ static int tomoyo_update_file_acl(const char *filename, u8 perm,
650 * @may_use_pattern: True if patterned ACL is permitted. 618 * @may_use_pattern: True if patterned ACL is permitted.
651 * 619 *
652 * Returns 0 on success, -EPERM otherwise. 620 * Returns 0 on success, -EPERM otherwise.
621 *
622 * Caller holds tomoyo_read_lock().
653 */ 623 */
654static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info * 624static int tomoyo_path_acl2(const struct tomoyo_domain_info *domain,
655 domain, 625 const struct tomoyo_path_info *filename,
656 const struct tomoyo_path_info * 626 const u32 perm, const bool may_use_pattern)
657 filename,
658 const u16 perm,
659 const bool may_use_pattern)
660{ 627{
661 struct tomoyo_acl_info *ptr; 628 struct tomoyo_acl_info *ptr;
662 int error = -EPERM; 629 int error = -EPERM;
663 630
664 down_read(&tomoyo_domain_acl_info_list_lock); 631 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
665 list_for_each_entry(ptr, &domain->acl_info_list, list) { 632 struct tomoyo_path_acl *acl;
666 struct tomoyo_single_path_acl_record *acl; 633 if (ptr->type != TOMOYO_TYPE_PATH_ACL)
667 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL)
668 continue;
669 acl = container_of(ptr, struct tomoyo_single_path_acl_record,
670 head);
671 if (!(acl->perm & perm))
672 continue; 634 continue;
635 acl = container_of(ptr, struct tomoyo_path_acl, head);
636 if (perm <= 0xFFFF) {
637 if (!(acl->perm & perm))
638 continue;
639 } else {
640 if (!(acl->perm_high & (perm >> 16)))
641 continue;
642 }
673 if (may_use_pattern || !acl->filename->is_patterned) { 643 if (may_use_pattern || !acl->filename->is_patterned) {
674 if (!tomoyo_path_matches_pattern(filename, 644 if (!tomoyo_path_matches_pattern(filename,
675 acl->filename)) 645 acl->filename))
@@ -680,7 +650,6 @@ static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info *
680 error = 0; 650 error = 0;
681 break; 651 break;
682 } 652 }
683 up_read(&tomoyo_domain_acl_info_list_lock);
684 return error; 653 return error;
685} 654}
686 655
@@ -692,27 +661,28 @@ static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info *
692 * @operation: Mode ("read" or "write" or "read/write" or "execute"). 661 * @operation: Mode ("read" or "write" or "read/write" or "execute").
693 * 662 *
694 * Returns 0 on success, -EPERM otherwise. 663 * Returns 0 on success, -EPERM otherwise.
664 *
665 * Caller holds tomoyo_read_lock().
695 */ 666 */
696static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain, 667static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain,
697 const struct tomoyo_path_info *filename, 668 const struct tomoyo_path_info *filename,
698 const u8 operation) 669 const u8 operation)
699{ 670{
700 u16 perm = 0; 671 u32 perm = 0;
701 672
702 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) 673 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
703 return 0; 674 return 0;
704 if (operation == 6) 675 if (operation == 6)
705 perm = 1 << TOMOYO_TYPE_READ_WRITE_ACL; 676 perm = 1 << TOMOYO_TYPE_READ_WRITE;
706 else if (operation == 4) 677 else if (operation == 4)
707 perm = 1 << TOMOYO_TYPE_READ_ACL; 678 perm = 1 << TOMOYO_TYPE_READ;
708 else if (operation == 2) 679 else if (operation == 2)
709 perm = 1 << TOMOYO_TYPE_WRITE_ACL; 680 perm = 1 << TOMOYO_TYPE_WRITE;
710 else if (operation == 1) 681 else if (operation == 1)
711 perm = 1 << TOMOYO_TYPE_EXECUTE_ACL; 682 perm = 1 << TOMOYO_TYPE_EXECUTE;
712 else 683 else
713 BUG(); 684 BUG();
714 return tomoyo_check_single_path_acl2(domain, filename, perm, 685 return tomoyo_path_acl2(domain, filename, perm, operation != 1);
715 operation != 1);
716} 686}
717 687
718/** 688/**
@@ -725,6 +695,8 @@ static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain,
725 * @mode: Access control mode. 695 * @mode: Access control mode.
726 * 696 *
727 * Returns 0 on success, negative value otherwise. 697 * Returns 0 on success, negative value otherwise.
698 *
699 * Caller holds tomoyo_read_lock().
728 */ 700 */
729static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain, 701static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
730 const struct tomoyo_path_info *filename, 702 const struct tomoyo_path_info *filename,
@@ -738,18 +710,17 @@ static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
738 if (!filename) 710 if (!filename)
739 return 0; 711 return 0;
740 error = tomoyo_check_file_acl(domain, filename, perm); 712 error = tomoyo_check_file_acl(domain, filename, perm);
741 if (error && perm == 4 && 713 if (error && perm == 4 && !domain->ignore_global_allow_read
742 (domain->flags & TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ) == 0
743 && tomoyo_is_globally_readable_file(filename)) 714 && tomoyo_is_globally_readable_file(filename))
744 error = 0; 715 error = 0;
745 if (perm == 6) 716 if (perm == 6)
746 msg = tomoyo_sp2keyword(TOMOYO_TYPE_READ_WRITE_ACL); 717 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ_WRITE);
747 else if (perm == 4) 718 else if (perm == 4)
748 msg = tomoyo_sp2keyword(TOMOYO_TYPE_READ_ACL); 719 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ);
749 else if (perm == 2) 720 else if (perm == 2)
750 msg = tomoyo_sp2keyword(TOMOYO_TYPE_WRITE_ACL); 721 msg = tomoyo_path2keyword(TOMOYO_TYPE_WRITE);
751 else if (perm == 1) 722 else if (perm == 1)
752 msg = tomoyo_sp2keyword(TOMOYO_TYPE_EXECUTE_ACL); 723 msg = tomoyo_path2keyword(TOMOYO_TYPE_EXECUTE);
753 else 724 else
754 BUG(); 725 BUG();
755 if (!error) 726 if (!error)
@@ -778,6 +749,8 @@ static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
778 * @is_delete: True if it is a delete request. 749 * @is_delete: True if it is a delete request.
779 * 750 *
780 * Returns 0 on success, negative value otherwise. 751 * Returns 0 on success, negative value otherwise.
752 *
753 * Caller holds tomoyo_read_lock().
781 */ 754 */
782int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain, 755int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
783 const bool is_delete) 756 const bool is_delete)
@@ -796,28 +769,28 @@ int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
796 if (strncmp(data, "allow_", 6)) 769 if (strncmp(data, "allow_", 6))
797 goto out; 770 goto out;
798 data += 6; 771 data += 6;
799 for (type = 0; type < TOMOYO_MAX_SINGLE_PATH_OPERATION; type++) { 772 for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++) {
800 if (strcmp(data, tomoyo_sp_keyword[type])) 773 if (strcmp(data, tomoyo_path_keyword[type]))
801 continue; 774 continue;
802 return tomoyo_update_single_path_acl(type, filename, 775 return tomoyo_update_path_acl(type, filename, domain,
803 domain, is_delete); 776 is_delete);
804 } 777 }
805 filename2 = strchr(filename, ' '); 778 filename2 = strchr(filename, ' ');
806 if (!filename2) 779 if (!filename2)
807 goto out; 780 goto out;
808 *filename2++ = '\0'; 781 *filename2++ = '\0';
809 for (type = 0; type < TOMOYO_MAX_DOUBLE_PATH_OPERATION; type++) { 782 for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++) {
810 if (strcmp(data, tomoyo_dp_keyword[type])) 783 if (strcmp(data, tomoyo_path2_keyword[type]))
811 continue; 784 continue;
812 return tomoyo_update_double_path_acl(type, filename, filename2, 785 return tomoyo_update_path2_acl(type, filename, filename2,
813 domain, is_delete); 786 domain, is_delete);
814 } 787 }
815 out: 788 out:
816 return -EINVAL; 789 return -EINVAL;
817} 790}
818 791
819/** 792/**
820 * tomoyo_update_single_path_acl - Update "struct tomoyo_single_path_acl_record" list. 793 * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list.
821 * 794 *
822 * @type: Type of operation. 795 * @type: Type of operation.
823 * @filename: Filename. 796 * @filename: Filename.
@@ -825,85 +798,82 @@ int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
825 * @is_delete: True if it is a delete request. 798 * @is_delete: True if it is a delete request.
826 * 799 *
827 * Returns 0 on success, negative value otherwise. 800 * Returns 0 on success, negative value otherwise.
801 *
802 * Caller holds tomoyo_read_lock().
828 */ 803 */
829static int tomoyo_update_single_path_acl(const u8 type, const char *filename, 804static int tomoyo_update_path_acl(const u8 type, const char *filename,
830 struct tomoyo_domain_info * 805 struct tomoyo_domain_info *const domain,
831 const domain, const bool is_delete) 806 const bool is_delete)
832{ 807{
833 static const u16 rw_mask = 808 static const u32 rw_mask =
834 (1 << TOMOYO_TYPE_READ_ACL) | (1 << TOMOYO_TYPE_WRITE_ACL); 809 (1 << TOMOYO_TYPE_READ) | (1 << TOMOYO_TYPE_WRITE);
835 const struct tomoyo_path_info *saved_filename; 810 const struct tomoyo_path_info *saved_filename;
836 struct tomoyo_acl_info *ptr; 811 struct tomoyo_acl_info *ptr;
837 struct tomoyo_single_path_acl_record *acl; 812 struct tomoyo_path_acl *entry = NULL;
838 int error = -ENOMEM; 813 int error = is_delete ? -ENOENT : -ENOMEM;
839 const u16 perm = 1 << type; 814 const u32 perm = 1 << type;
840 815
841 if (!domain) 816 if (!domain)
842 return -EINVAL; 817 return -EINVAL;
843 if (!tomoyo_is_correct_path(filename, 0, 0, 0, __func__)) 818 if (!tomoyo_is_correct_path(filename, 0, 0, 0))
844 return -EINVAL; 819 return -EINVAL;
845 saved_filename = tomoyo_save_name(filename); 820 saved_filename = tomoyo_get_name(filename);
846 if (!saved_filename) 821 if (!saved_filename)
847 return -ENOMEM; 822 return -ENOMEM;
848 down_write(&tomoyo_domain_acl_info_list_lock); 823 if (!is_delete)
849 if (is_delete) 824 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
850 goto delete; 825 mutex_lock(&tomoyo_policy_lock);
851 list_for_each_entry(ptr, &domain->acl_info_list, list) { 826 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
852 if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL) 827 struct tomoyo_path_acl *acl =
828 container_of(ptr, struct tomoyo_path_acl, head);
829 if (ptr->type != TOMOYO_TYPE_PATH_ACL)
853 continue; 830 continue;
854 acl = container_of(ptr, struct tomoyo_single_path_acl_record,
855 head);
856 if (acl->filename != saved_filename) 831 if (acl->filename != saved_filename)
857 continue; 832 continue;
858 /* Special case. Clear all bits if marked as deleted. */ 833 if (is_delete) {
859 if (ptr->type & TOMOYO_ACL_DELETED) 834 if (perm <= 0xFFFF)
860 acl->perm = 0; 835 acl->perm &= ~perm;
861 acl->perm |= perm; 836 else
862 if ((acl->perm & rw_mask) == rw_mask) 837 acl->perm_high &= ~(perm >> 16);
863 acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE_ACL; 838 if ((acl->perm & rw_mask) != rw_mask)
864 else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)) 839 acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE);
865 acl->perm |= rw_mask; 840 else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE)))
866 ptr->type &= ~TOMOYO_ACL_DELETED; 841 acl->perm &= ~rw_mask;
842 } else {
843 if (perm <= 0xFFFF)
844 acl->perm |= perm;
845 else
846 acl->perm_high |= (perm >> 16);
847 if ((acl->perm & rw_mask) == rw_mask)
848 acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE;
849 else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE))
850 acl->perm |= rw_mask;
851 }
867 error = 0; 852 error = 0;
868 goto out; 853 break;
869 } 854 }
870 /* Not found. Append it to the tail. */ 855 if (!is_delete && error && tomoyo_memory_ok(entry)) {
871 acl = tomoyo_alloc_acl_element(TOMOYO_TYPE_SINGLE_PATH_ACL); 856 entry->head.type = TOMOYO_TYPE_PATH_ACL;
872 if (!acl) 857 if (perm <= 0xFFFF)
873 goto out; 858 entry->perm = perm;
874 acl->perm = perm; 859 else
875 if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL)) 860 entry->perm_high = (perm >> 16);
876 acl->perm |= rw_mask; 861 if (perm == (1 << TOMOYO_TYPE_READ_WRITE))
877 acl->filename = saved_filename; 862 entry->perm |= rw_mask;
878 list_add_tail(&acl->head.list, &domain->acl_info_list); 863 entry->filename = saved_filename;
879 error = 0; 864 saved_filename = NULL;
880 goto out; 865 list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
881 delete: 866 entry = NULL;
882 error = -ENOENT;
883 list_for_each_entry(ptr, &domain->acl_info_list, list) {
884 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL)
885 continue;
886 acl = container_of(ptr, struct tomoyo_single_path_acl_record,
887 head);
888 if (acl->filename != saved_filename)
889 continue;
890 acl->perm &= ~perm;
891 if ((acl->perm & rw_mask) != rw_mask)
892 acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE_ACL);
893 else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)))
894 acl->perm &= ~rw_mask;
895 if (!acl->perm)
896 ptr->type |= TOMOYO_ACL_DELETED;
897 error = 0; 867 error = 0;
898 break;
899 } 868 }
900 out: 869 mutex_unlock(&tomoyo_policy_lock);
901 up_write(&tomoyo_domain_acl_info_list_lock); 870 kfree(entry);
871 tomoyo_put_name(saved_filename);
902 return error; 872 return error;
903} 873}
904 874
905/** 875/**
906 * tomoyo_update_double_path_acl - Update "struct tomoyo_double_path_acl_record" list. 876 * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list.
907 * 877 *
908 * @type: Type of operation. 878 * @type: Type of operation.
909 * @filename1: First filename. 879 * @filename1: First filename.
@@ -912,98 +882,88 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
912 * @is_delete: True if it is a delete request. 882 * @is_delete: True if it is a delete request.
913 * 883 *
914 * Returns 0 on success, negative value otherwise. 884 * Returns 0 on success, negative value otherwise.
885 *
886 * Caller holds tomoyo_read_lock().
915 */ 887 */
916static int tomoyo_update_double_path_acl(const u8 type, const char *filename1, 888static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
917 const char *filename2, 889 const char *filename2,
918 struct tomoyo_domain_info * 890 struct tomoyo_domain_info *const domain,
919 const domain, const bool is_delete) 891 const bool is_delete)
920{ 892{
921 const struct tomoyo_path_info *saved_filename1; 893 const struct tomoyo_path_info *saved_filename1;
922 const struct tomoyo_path_info *saved_filename2; 894 const struct tomoyo_path_info *saved_filename2;
923 struct tomoyo_acl_info *ptr; 895 struct tomoyo_acl_info *ptr;
924 struct tomoyo_double_path_acl_record *acl; 896 struct tomoyo_path2_acl *entry = NULL;
925 int error = -ENOMEM; 897 int error = is_delete ? -ENOENT : -ENOMEM;
926 const u8 perm = 1 << type; 898 const u8 perm = 1 << type;
927 899
928 if (!domain) 900 if (!domain)
929 return -EINVAL; 901 return -EINVAL;
930 if (!tomoyo_is_correct_path(filename1, 0, 0, 0, __func__) || 902 if (!tomoyo_is_correct_path(filename1, 0, 0, 0) ||
931 !tomoyo_is_correct_path(filename2, 0, 0, 0, __func__)) 903 !tomoyo_is_correct_path(filename2, 0, 0, 0))
932 return -EINVAL; 904 return -EINVAL;
933 saved_filename1 = tomoyo_save_name(filename1); 905 saved_filename1 = tomoyo_get_name(filename1);
934 saved_filename2 = tomoyo_save_name(filename2); 906 saved_filename2 = tomoyo_get_name(filename2);
935 if (!saved_filename1 || !saved_filename2) 907 if (!saved_filename1 || !saved_filename2)
936 return -ENOMEM;
937 down_write(&tomoyo_domain_acl_info_list_lock);
938 if (is_delete)
939 goto delete;
940 list_for_each_entry(ptr, &domain->acl_info_list, list) {
941 if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
942 continue;
943 acl = container_of(ptr, struct tomoyo_double_path_acl_record,
944 head);
945 if (acl->filename1 != saved_filename1 ||
946 acl->filename2 != saved_filename2)
947 continue;
948 /* Special case. Clear all bits if marked as deleted. */
949 if (ptr->type & TOMOYO_ACL_DELETED)
950 acl->perm = 0;
951 acl->perm |= perm;
952 ptr->type &= ~TOMOYO_ACL_DELETED;
953 error = 0;
954 goto out; 908 goto out;
955 } 909 if (!is_delete)
956 /* Not found. Append it to the tail. */ 910 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
957 acl = tomoyo_alloc_acl_element(TOMOYO_TYPE_DOUBLE_PATH_ACL); 911 mutex_lock(&tomoyo_policy_lock);
958 if (!acl) 912 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
959 goto out; 913 struct tomoyo_path2_acl *acl =
960 acl->perm = perm; 914 container_of(ptr, struct tomoyo_path2_acl, head);
961 acl->filename1 = saved_filename1; 915 if (ptr->type != TOMOYO_TYPE_PATH2_ACL)
962 acl->filename2 = saved_filename2;
963 list_add_tail(&acl->head.list, &domain->acl_info_list);
964 error = 0;
965 goto out;
966 delete:
967 error = -ENOENT;
968 list_for_each_entry(ptr, &domain->acl_info_list, list) {
969 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
970 continue; 916 continue;
971 acl = container_of(ptr, struct tomoyo_double_path_acl_record,
972 head);
973 if (acl->filename1 != saved_filename1 || 917 if (acl->filename1 != saved_filename1 ||
974 acl->filename2 != saved_filename2) 918 acl->filename2 != saved_filename2)
975 continue; 919 continue;
976 acl->perm &= ~perm; 920 if (is_delete)
977 if (!acl->perm) 921 acl->perm &= ~perm;
978 ptr->type |= TOMOYO_ACL_DELETED; 922 else
923 acl->perm |= perm;
979 error = 0; 924 error = 0;
980 break; 925 break;
981 } 926 }
927 if (!is_delete && error && tomoyo_memory_ok(entry)) {
928 entry->head.type = TOMOYO_TYPE_PATH2_ACL;
929 entry->perm = perm;
930 entry->filename1 = saved_filename1;
931 saved_filename1 = NULL;
932 entry->filename2 = saved_filename2;
933 saved_filename2 = NULL;
934 list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
935 entry = NULL;
936 error = 0;
937 }
938 mutex_unlock(&tomoyo_policy_lock);
982 out: 939 out:
983 up_write(&tomoyo_domain_acl_info_list_lock); 940 tomoyo_put_name(saved_filename1);
941 tomoyo_put_name(saved_filename2);
942 kfree(entry);
984 return error; 943 return error;
985} 944}
986 945
987/** 946/**
988 * tomoyo_check_single_path_acl - Check permission for single path operation. 947 * tomoyo_path_acl - Check permission for single path operation.
989 * 948 *
990 * @domain: Pointer to "struct tomoyo_domain_info". 949 * @domain: Pointer to "struct tomoyo_domain_info".
991 * @type: Type of operation. 950 * @type: Type of operation.
992 * @filename: Filename to check. 951 * @filename: Filename to check.
993 * 952 *
994 * Returns 0 on success, negative value otherwise. 953 * Returns 0 on success, negative value otherwise.
954 *
955 * Caller holds tomoyo_read_lock().
995 */ 956 */
996static int tomoyo_check_single_path_acl(struct tomoyo_domain_info *domain, 957static int tomoyo_path_acl(struct tomoyo_domain_info *domain, const u8 type,
997 const u8 type, 958 const struct tomoyo_path_info *filename)
998 const struct tomoyo_path_info *filename)
999{ 959{
1000 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) 960 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
1001 return 0; 961 return 0;
1002 return tomoyo_check_single_path_acl2(domain, filename, 1 << type, 1); 962 return tomoyo_path_acl2(domain, filename, 1 << type, 1);
1003} 963}
1004 964
1005/** 965/**
1006 * tomoyo_check_double_path_acl - Check permission for double path operation. 966 * tomoyo_path2_acl - Check permission for double path operation.
1007 * 967 *
1008 * @domain: Pointer to "struct tomoyo_domain_info". 968 * @domain: Pointer to "struct tomoyo_domain_info".
1009 * @type: Type of operation. 969 * @type: Type of operation.
@@ -1011,13 +971,13 @@ static int tomoyo_check_single_path_acl(struct tomoyo_domain_info *domain,
1011 * @filename2: Second filename to check. 971 * @filename2: Second filename to check.
1012 * 972 *
1013 * Returns 0 on success, -EPERM otherwise. 973 * Returns 0 on success, -EPERM otherwise.
974 *
975 * Caller holds tomoyo_read_lock().
1014 */ 976 */
1015static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain, 977static int tomoyo_path2_acl(const struct tomoyo_domain_info *domain,
1016 const u8 type, 978 const u8 type,
1017 const struct tomoyo_path_info * 979 const struct tomoyo_path_info *filename1,
1018 filename1, 980 const struct tomoyo_path_info *filename2)
1019 const struct tomoyo_path_info *
1020 filename2)
1021{ 981{
1022 struct tomoyo_acl_info *ptr; 982 struct tomoyo_acl_info *ptr;
1023 const u8 perm = 1 << type; 983 const u8 perm = 1 << type;
@@ -1025,13 +985,11 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
1025 985
1026 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) 986 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
1027 return 0; 987 return 0;
1028 down_read(&tomoyo_domain_acl_info_list_lock); 988 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
1029 list_for_each_entry(ptr, &domain->acl_info_list, list) { 989 struct tomoyo_path2_acl *acl;
1030 struct tomoyo_double_path_acl_record *acl; 990 if (ptr->type != TOMOYO_TYPE_PATH2_ACL)
1031 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
1032 continue; 991 continue;
1033 acl = container_of(ptr, struct tomoyo_double_path_acl_record, 992 acl = container_of(ptr, struct tomoyo_path2_acl, head);
1034 head);
1035 if (!(acl->perm & perm)) 993 if (!(acl->perm & perm))
1036 continue; 994 continue;
1037 if (!tomoyo_path_matches_pattern(filename1, acl->filename1)) 995 if (!tomoyo_path_matches_pattern(filename1, acl->filename1))
@@ -1041,12 +999,11 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
1041 error = 0; 999 error = 0;
1042 break; 1000 break;
1043 } 1001 }
1044 up_read(&tomoyo_domain_acl_info_list_lock);
1045 return error; 1002 return error;
1046} 1003}
1047 1004
1048/** 1005/**
1049 * tomoyo_check_single_path_permission2 - Check permission for single path operation. 1006 * tomoyo_path_permission2 - Check permission for single path operation.
1050 * 1007 *
1051 * @domain: Pointer to "struct tomoyo_domain_info". 1008 * @domain: Pointer to "struct tomoyo_domain_info".
1052 * @operation: Type of operation. 1009 * @operation: Type of operation.
@@ -1054,11 +1011,13 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
1054 * @mode: Access control mode. 1011 * @mode: Access control mode.
1055 * 1012 *
1056 * Returns 0 on success, negative value otherwise. 1013 * Returns 0 on success, negative value otherwise.
1014 *
1015 * Caller holds tomoyo_read_lock().
1057 */ 1016 */
1058static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info * 1017static int tomoyo_path_permission2(struct tomoyo_domain_info *const domain,
1059 const domain, u8 operation, 1018 u8 operation,
1060 const struct tomoyo_path_info * 1019 const struct tomoyo_path_info *filename,
1061 filename, const u8 mode) 1020 const u8 mode)
1062{ 1021{
1063 const char *msg; 1022 const char *msg;
1064 int error; 1023 int error;
@@ -1067,8 +1026,8 @@ static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info *
1067 if (!mode) 1026 if (!mode)
1068 return 0; 1027 return 0;
1069 next: 1028 next:
1070 error = tomoyo_check_single_path_acl(domain, operation, filename); 1029 error = tomoyo_path_acl(domain, operation, filename);
1071 msg = tomoyo_sp2keyword(operation); 1030 msg = tomoyo_path2keyword(operation);
1072 if (!error) 1031 if (!error)
1073 goto ok; 1032 goto ok;
1074 if (tomoyo_verbose_mode(domain)) 1033 if (tomoyo_verbose_mode(domain))
@@ -1077,7 +1036,7 @@ static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info *
1077 tomoyo_get_last_name(domain)); 1036 tomoyo_get_last_name(domain));
1078 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) { 1037 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) {
1079 const char *name = tomoyo_get_file_pattern(filename)->name; 1038 const char *name = tomoyo_get_file_pattern(filename)->name;
1080 tomoyo_update_single_path_acl(operation, name, domain, false); 1039 tomoyo_update_path_acl(operation, name, domain, false);
1081 } 1040 }
1082 if (!is_enforce) 1041 if (!is_enforce)
1083 error = 0; 1042 error = 0;
@@ -1087,42 +1046,23 @@ static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info *
1087 * we need to check "allow_rewrite" permission if the filename is 1046 * we need to check "allow_rewrite" permission if the filename is
1088 * specified by "deny_rewrite" keyword. 1047 * specified by "deny_rewrite" keyword.
1089 */ 1048 */
1090 if (!error && operation == TOMOYO_TYPE_TRUNCATE_ACL && 1049 if (!error && operation == TOMOYO_TYPE_TRUNCATE &&
1091 tomoyo_is_no_rewrite_file(filename)) { 1050 tomoyo_is_no_rewrite_file(filename)) {
1092 operation = TOMOYO_TYPE_REWRITE_ACL; 1051 operation = TOMOYO_TYPE_REWRITE;
1093 goto next; 1052 goto next;
1094 } 1053 }
1095 return error; 1054 return error;
1096} 1055}
1097 1056
1098/** 1057/**
1099 * tomoyo_check_file_perm - Check permission for sysctl()'s "read" and "write".
1100 *
1101 * @domain: Pointer to "struct tomoyo_domain_info".
1102 * @filename: Filename to check.
1103 * @perm: Mode ("read" or "write" or "read/write").
1104 * Returns 0 on success, negative value otherwise.
1105 */
1106int tomoyo_check_file_perm(struct tomoyo_domain_info *domain,
1107 const char *filename, const u8 perm)
1108{
1109 struct tomoyo_path_info name;
1110 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1111
1112 if (!mode)
1113 return 0;
1114 name.name = filename;
1115 tomoyo_fill_path_info(&name);
1116 return tomoyo_check_file_perm2(domain, &name, perm, "sysctl", mode);
1117}
1118
1119/**
1120 * tomoyo_check_exec_perm - Check permission for "execute". 1058 * tomoyo_check_exec_perm - Check permission for "execute".
1121 * 1059 *
1122 * @domain: Pointer to "struct tomoyo_domain_info". 1060 * @domain: Pointer to "struct tomoyo_domain_info".
1123 * @filename: Check permission for "execute". 1061 * @filename: Check permission for "execute".
1124 * 1062 *
1125 * Returns 0 on success, negativevalue otherwise. 1063 * Returns 0 on success, negativevalue otherwise.
1064 *
1065 * Caller holds tomoyo_read_lock().
1126 */ 1066 */
1127int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, 1067int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain,
1128 const struct tomoyo_path_info *filename) 1068 const struct tomoyo_path_info *filename)
@@ -1151,6 +1091,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1151 struct tomoyo_path_info *buf; 1091 struct tomoyo_path_info *buf;
1152 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1092 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1153 const bool is_enforce = (mode == 3); 1093 const bool is_enforce = (mode == 3);
1094 int idx;
1154 1095
1155 if (!mode || !path->mnt) 1096 if (!mode || !path->mnt)
1156 return 0; 1097 return 0;
@@ -1162,6 +1103,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1162 * don't call me. 1103 * don't call me.
1163 */ 1104 */
1164 return 0; 1105 return 0;
1106 idx = tomoyo_read_lock();
1165 buf = tomoyo_get_path(path); 1107 buf = tomoyo_get_path(path);
1166 if (!buf) 1108 if (!buf)
1167 goto out; 1109 goto out;
@@ -1174,49 +1116,50 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1174 if ((acc_mode & MAY_WRITE) && 1116 if ((acc_mode & MAY_WRITE) &&
1175 ((flag & O_TRUNC) || !(flag & O_APPEND)) && 1117 ((flag & O_TRUNC) || !(flag & O_APPEND)) &&
1176 (tomoyo_is_no_rewrite_file(buf))) { 1118 (tomoyo_is_no_rewrite_file(buf))) {
1177 error = tomoyo_check_single_path_permission2(domain, 1119 error = tomoyo_path_permission2(domain, TOMOYO_TYPE_REWRITE,
1178 TOMOYO_TYPE_REWRITE_ACL, 1120 buf, mode);
1179 buf, mode);
1180 } 1121 }
1181 if (!error) 1122 if (!error)
1182 error = tomoyo_check_file_perm2(domain, buf, acc_mode, "open", 1123 error = tomoyo_check_file_perm2(domain, buf, acc_mode, "open",
1183 mode); 1124 mode);
1184 if (!error && (flag & O_TRUNC)) 1125 if (!error && (flag & O_TRUNC))
1185 error = tomoyo_check_single_path_permission2(domain, 1126 error = tomoyo_path_permission2(domain, TOMOYO_TYPE_TRUNCATE,
1186 TOMOYO_TYPE_TRUNCATE_ACL, 1127 buf, mode);
1187 buf, mode);
1188 out: 1128 out:
1189 tomoyo_free(buf); 1129 kfree(buf);
1130 tomoyo_read_unlock(idx);
1190 if (!is_enforce) 1131 if (!is_enforce)
1191 error = 0; 1132 error = 0;
1192 return error; 1133 return error;
1193} 1134}
1194 1135
1195/** 1136/**
1196 * tomoyo_check_1path_perm - Check permission for "create", "unlink", "mkdir", "rmdir", "mkfifo", "mksock", "mkblock", "mkchar", "truncate" and "symlink". 1137 * tomoyo_path_perm - Check permission for "create", "unlink", "mkdir", "rmdir", "mkfifo", "mksock", "mkblock", "mkchar", "truncate", "symlink", "ioctl", "chmod", "chown", "chgrp", "chroot", "mount" and "unmount".
1197 * 1138 *
1198 * @domain: Pointer to "struct tomoyo_domain_info".
1199 * @operation: Type of operation. 1139 * @operation: Type of operation.
1200 * @path: Pointer to "struct path". 1140 * @path: Pointer to "struct path".
1201 * 1141 *
1202 * Returns 0 on success, negative value otherwise. 1142 * Returns 0 on success, negative value otherwise.
1203 */ 1143 */
1204int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain, 1144int tomoyo_path_perm(const u8 operation, struct path *path)
1205 const u8 operation, struct path *path)
1206{ 1145{
1207 int error = -ENOMEM; 1146 int error = -ENOMEM;
1208 struct tomoyo_path_info *buf; 1147 struct tomoyo_path_info *buf;
1148 struct tomoyo_domain_info *domain = tomoyo_domain();
1209 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1149 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1210 const bool is_enforce = (mode == 3); 1150 const bool is_enforce = (mode == 3);
1151 int idx;
1211 1152
1212 if (!mode || !path->mnt) 1153 if (!mode || !path->mnt)
1213 return 0; 1154 return 0;
1155 idx = tomoyo_read_lock();
1214 buf = tomoyo_get_path(path); 1156 buf = tomoyo_get_path(path);
1215 if (!buf) 1157 if (!buf)
1216 goto out; 1158 goto out;
1217 switch (operation) { 1159 switch (operation) {
1218 case TOMOYO_TYPE_MKDIR_ACL: 1160 case TOMOYO_TYPE_MKDIR:
1219 case TOMOYO_TYPE_RMDIR_ACL: 1161 case TOMOYO_TYPE_RMDIR:
1162 case TOMOYO_TYPE_CHROOT:
1220 if (!buf->is_dir) { 1163 if (!buf->is_dir) {
1221 /* 1164 /*
1222 * tomoyo_get_path() reserves space for appending "/." 1165 * tomoyo_get_path() reserves space for appending "/."
@@ -1225,10 +1168,10 @@ int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain,
1225 tomoyo_fill_path_info(buf); 1168 tomoyo_fill_path_info(buf);
1226 } 1169 }
1227 } 1170 }
1228 error = tomoyo_check_single_path_permission2(domain, operation, buf, 1171 error = tomoyo_path_permission2(domain, operation, buf, mode);
1229 mode);
1230 out: 1172 out:
1231 tomoyo_free(buf); 1173 kfree(buf);
1174 tomoyo_read_unlock(idx);
1232 if (!is_enforce) 1175 if (!is_enforce)
1233 error = 0; 1176 error = 0;
1234 return error; 1177 return error;
@@ -1237,21 +1180,23 @@ int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain,
1237/** 1180/**
1238 * tomoyo_check_rewrite_permission - Check permission for "rewrite". 1181 * tomoyo_check_rewrite_permission - Check permission for "rewrite".
1239 * 1182 *
1240 * @domain: Pointer to "struct tomoyo_domain_info".
1241 * @filp: Pointer to "struct file". 1183 * @filp: Pointer to "struct file".
1242 * 1184 *
1243 * Returns 0 on success, negative value otherwise. 1185 * Returns 0 on success, negative value otherwise.
1244 */ 1186 */
1245int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain, 1187int tomoyo_check_rewrite_permission(struct file *filp)
1246 struct file *filp)
1247{ 1188{
1248 int error = -ENOMEM; 1189 int error = -ENOMEM;
1190 struct tomoyo_domain_info *domain = tomoyo_domain();
1249 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1191 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1250 const bool is_enforce = (mode == 3); 1192 const bool is_enforce = (mode == 3);
1251 struct tomoyo_path_info *buf; 1193 struct tomoyo_path_info *buf;
1194 int idx;
1252 1195
1253 if (!mode || !filp->f_path.mnt) 1196 if (!mode || !filp->f_path.mnt)
1254 return 0; 1197 return 0;
1198
1199 idx = tomoyo_read_lock();
1255 buf = tomoyo_get_path(&filp->f_path); 1200 buf = tomoyo_get_path(&filp->f_path);
1256 if (!buf) 1201 if (!buf)
1257 goto out; 1202 goto out;
@@ -1259,38 +1204,38 @@ int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain,
1259 error = 0; 1204 error = 0;
1260 goto out; 1205 goto out;
1261 } 1206 }
1262 error = tomoyo_check_single_path_permission2(domain, 1207 error = tomoyo_path_permission2(domain, TOMOYO_TYPE_REWRITE, buf, mode);
1263 TOMOYO_TYPE_REWRITE_ACL,
1264 buf, mode);
1265 out: 1208 out:
1266 tomoyo_free(buf); 1209 kfree(buf);
1210 tomoyo_read_unlock(idx);
1267 if (!is_enforce) 1211 if (!is_enforce)
1268 error = 0; 1212 error = 0;
1269 return error; 1213 return error;
1270} 1214}
1271 1215
1272/** 1216/**
1273 * tomoyo_check_2path_perm - Check permission for "rename" and "link". 1217 * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root".
1274 * 1218 *
1275 * @domain: Pointer to "struct tomoyo_domain_info".
1276 * @operation: Type of operation. 1219 * @operation: Type of operation.
1277 * @path1: Pointer to "struct path". 1220 * @path1: Pointer to "struct path".
1278 * @path2: Pointer to "struct path". 1221 * @path2: Pointer to "struct path".
1279 * 1222 *
1280 * Returns 0 on success, negative value otherwise. 1223 * Returns 0 on success, negative value otherwise.
1281 */ 1224 */
1282int tomoyo_check_2path_perm(struct tomoyo_domain_info * const domain, 1225int tomoyo_path2_perm(const u8 operation, struct path *path1,
1283 const u8 operation, struct path *path1, 1226 struct path *path2)
1284 struct path *path2)
1285{ 1227{
1286 int error = -ENOMEM; 1228 int error = -ENOMEM;
1287 struct tomoyo_path_info *buf1, *buf2; 1229 struct tomoyo_path_info *buf1, *buf2;
1230 struct tomoyo_domain_info *domain = tomoyo_domain();
1288 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1231 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1289 const bool is_enforce = (mode == 3); 1232 const bool is_enforce = (mode == 3);
1290 const char *msg; 1233 const char *msg;
1234 int idx;
1291 1235
1292 if (!mode || !path1->mnt || !path2->mnt) 1236 if (!mode || !path1->mnt || !path2->mnt)
1293 return 0; 1237 return 0;
1238 idx = tomoyo_read_lock();
1294 buf1 = tomoyo_get_path(path1); 1239 buf1 = tomoyo_get_path(path1);
1295 buf2 = tomoyo_get_path(path2); 1240 buf2 = tomoyo_get_path(path2);
1296 if (!buf1 || !buf2) 1241 if (!buf1 || !buf2)
@@ -1311,8 +1256,8 @@ int tomoyo_check_2path_perm(struct tomoyo_domain_info * const domain,
1311 } 1256 }
1312 } 1257 }
1313 } 1258 }
1314 error = tomoyo_check_double_path_acl(domain, operation, buf1, buf2); 1259 error = tomoyo_path2_acl(domain, operation, buf1, buf2);
1315 msg = tomoyo_dp2keyword(operation); 1260 msg = tomoyo_path22keyword(operation);
1316 if (!error) 1261 if (!error)
1317 goto out; 1262 goto out;
1318 if (tomoyo_verbose_mode(domain)) 1263 if (tomoyo_verbose_mode(domain))
@@ -1323,12 +1268,13 @@ int tomoyo_check_2path_perm(struct tomoyo_domain_info * const domain,
1323 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) { 1268 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) {
1324 const char *name1 = tomoyo_get_file_pattern(buf1)->name; 1269 const char *name1 = tomoyo_get_file_pattern(buf1)->name;
1325 const char *name2 = tomoyo_get_file_pattern(buf2)->name; 1270 const char *name2 = tomoyo_get_file_pattern(buf2)->name;
1326 tomoyo_update_double_path_acl(operation, name1, name2, domain, 1271 tomoyo_update_path2_acl(operation, name1, name2, domain,
1327 false); 1272 false);
1328 } 1273 }
1329 out: 1274 out:
1330 tomoyo_free(buf1); 1275 kfree(buf1);
1331 tomoyo_free(buf2); 1276 kfree(buf2);
1277 tomoyo_read_unlock(idx);
1332 if (!is_enforce) 1278 if (!is_enforce)
1333 error = 0; 1279 error = 0;
1334 return error; 1280 return error;