aboutsummaryrefslogtreecommitdiffstats
path: root/security/tomoyo/file.c
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2009-12-07 19:34:43 -0500
committerJames Morris <jmorris@namei.org>2009-12-14 23:46:31 -0500
commitfdb8ebb729bbb640e64028a4f579a02ebc405727 (patch)
tree9dfca7422cb858cd05208734affab31d980030fe /security/tomoyo/file.c
parent86fc80f16e8a2449d5827bf1a9838b7fd9f70097 (diff)
TOMOYO: Use RCU primitives for list operation
Replace list operation with RCU primitives and replace down_read()/up_read() with srcu_read_lock()/srcu_read_unlock(). Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/file.c')
-rw-r--r--security/tomoyo/file.c110
1 files changed, 77 insertions, 33 deletions
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 482f0e7ed997..3c472867634f 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -213,6 +213,8 @@ static DECLARE_RWSEM(tomoyo_globally_readable_list_lock);
213 * @is_delete: True if it is a delete request. 213 * @is_delete: True if it is a delete request.
214 * 214 *
215 * Returns 0 on success, negative value otherwise. 215 * Returns 0 on success, negative value otherwise.
216 *
217 * Caller holds tomoyo_read_lock().
216 */ 218 */
217static int tomoyo_update_globally_readable_entry(const char *filename, 219static int tomoyo_update_globally_readable_entry(const char *filename,
218 const bool is_delete) 220 const bool is_delete)
@@ -228,7 +230,7 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
228 if (!saved_filename) 230 if (!saved_filename)
229 return -ENOMEM; 231 return -ENOMEM;
230 down_write(&tomoyo_globally_readable_list_lock); 232 down_write(&tomoyo_globally_readable_list_lock);
231 list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) { 233 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
232 if (ptr->filename != saved_filename) 234 if (ptr->filename != saved_filename)
233 continue; 235 continue;
234 ptr->is_deleted = is_delete; 236 ptr->is_deleted = is_delete;
@@ -243,7 +245,7 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
243 if (!new_entry) 245 if (!new_entry)
244 goto out; 246 goto out;
245 new_entry->filename = saved_filename; 247 new_entry->filename = saved_filename;
246 list_add_tail(&new_entry->list, &tomoyo_globally_readable_list); 248 list_add_tail_rcu(&new_entry->list, &tomoyo_globally_readable_list);
247 error = 0; 249 error = 0;
248 out: 250 out:
249 up_write(&tomoyo_globally_readable_list_lock); 251 up_write(&tomoyo_globally_readable_list_lock);
@@ -256,21 +258,22 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
256 * @filename: The filename to check. 258 * @filename: The filename to check.
257 * 259 *
258 * Returns true if any domain can open @filename for reading, false otherwise. 260 * Returns true if any domain can open @filename for reading, false otherwise.
261 *
262 * Caller holds tomoyo_read_lock().
259 */ 263 */
260static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info * 264static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info *
261 filename) 265 filename)
262{ 266{
263 struct tomoyo_globally_readable_file_entry *ptr; 267 struct tomoyo_globally_readable_file_entry *ptr;
264 bool found = false; 268 bool found = false;
265 down_read(&tomoyo_globally_readable_list_lock); 269
266 list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) { 270 list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
267 if (!ptr->is_deleted && 271 if (!ptr->is_deleted &&
268 tomoyo_path_matches_pattern(filename, ptr->filename)) { 272 tomoyo_path_matches_pattern(filename, ptr->filename)) {
269 found = true; 273 found = true;
270 break; 274 break;
271 } 275 }
272 } 276 }
273 up_read(&tomoyo_globally_readable_list_lock);
274 return found; 277 return found;
275} 278}
276 279
@@ -281,6 +284,8 @@ static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info *
281 * @is_delete: True if it is a delete request. 284 * @is_delete: True if it is a delete request.
282 * 285 *
283 * Returns 0 on success, negative value otherwise. 286 * Returns 0 on success, negative value otherwise.
287 *
288 * Caller holds tomoyo_read_lock().
284 */ 289 */
285int tomoyo_write_globally_readable_policy(char *data, const bool is_delete) 290int tomoyo_write_globally_readable_policy(char *data, const bool is_delete)
286{ 291{
@@ -293,13 +298,14 @@ int tomoyo_write_globally_readable_policy(char *data, const bool is_delete)
293 * @head: Pointer to "struct tomoyo_io_buffer". 298 * @head: Pointer to "struct tomoyo_io_buffer".
294 * 299 *
295 * Returns true on success, false otherwise. 300 * Returns true on success, false otherwise.
301 *
302 * Caller holds tomoyo_read_lock().
296 */ 303 */
297bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head) 304bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
298{ 305{
299 struct list_head *pos; 306 struct list_head *pos;
300 bool done = true; 307 bool done = true;
301 308
302 down_read(&tomoyo_globally_readable_list_lock);
303 list_for_each_cookie(pos, head->read_var2, 309 list_for_each_cookie(pos, head->read_var2,
304 &tomoyo_globally_readable_list) { 310 &tomoyo_globally_readable_list) {
305 struct tomoyo_globally_readable_file_entry *ptr; 311 struct tomoyo_globally_readable_file_entry *ptr;
@@ -313,7 +319,6 @@ bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
313 if (!done) 319 if (!done)
314 break; 320 break;
315 } 321 }
316 up_read(&tomoyo_globally_readable_list_lock);
317 return done; 322 return done;
318} 323}
319 324
@@ -356,6 +361,8 @@ static DECLARE_RWSEM(tomoyo_pattern_list_lock);
356 * @is_delete: True if it is a delete request. 361 * @is_delete: True if it is a delete request.
357 * 362 *
358 * Returns 0 on success, negative value otherwise. 363 * Returns 0 on success, negative value otherwise.
364 *
365 * Caller holds tomoyo_read_lock().
359 */ 366 */
360static int tomoyo_update_file_pattern_entry(const char *pattern, 367static int tomoyo_update_file_pattern_entry(const char *pattern,
361 const bool is_delete) 368 const bool is_delete)
@@ -371,7 +378,7 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
371 if (!saved_pattern) 378 if (!saved_pattern)
372 return -ENOMEM; 379 return -ENOMEM;
373 down_write(&tomoyo_pattern_list_lock); 380 down_write(&tomoyo_pattern_list_lock);
374 list_for_each_entry(ptr, &tomoyo_pattern_list, list) { 381 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
375 if (saved_pattern != ptr->pattern) 382 if (saved_pattern != ptr->pattern)
376 continue; 383 continue;
377 ptr->is_deleted = is_delete; 384 ptr->is_deleted = is_delete;
@@ -386,7 +393,7 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
386 if (!new_entry) 393 if (!new_entry)
387 goto out; 394 goto out;
388 new_entry->pattern = saved_pattern; 395 new_entry->pattern = saved_pattern;
389 list_add_tail(&new_entry->list, &tomoyo_pattern_list); 396 list_add_tail_rcu(&new_entry->list, &tomoyo_pattern_list);
390 error = 0; 397 error = 0;
391 out: 398 out:
392 up_write(&tomoyo_pattern_list_lock); 399 up_write(&tomoyo_pattern_list_lock);
@@ -399,6 +406,8 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
399 * @filename: The filename to find patterned pathname. 406 * @filename: The filename to find patterned pathname.
400 * 407 *
401 * Returns pointer to pathname pattern if matched, @filename otherwise. 408 * Returns pointer to pathname pattern if matched, @filename otherwise.
409 *
410 * Caller holds tomoyo_read_lock().
402 */ 411 */
403static const struct tomoyo_path_info * 412static const struct tomoyo_path_info *
404tomoyo_get_file_pattern(const struct tomoyo_path_info *filename) 413tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
@@ -406,8 +415,7 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
406 struct tomoyo_pattern_entry *ptr; 415 struct tomoyo_pattern_entry *ptr;
407 const struct tomoyo_path_info *pattern = NULL; 416 const struct tomoyo_path_info *pattern = NULL;
408 417
409 down_read(&tomoyo_pattern_list_lock); 418 list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
410 list_for_each_entry(ptr, &tomoyo_pattern_list, list) {
411 if (ptr->is_deleted) 419 if (ptr->is_deleted)
412 continue; 420 continue;
413 if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) 421 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
@@ -420,7 +428,6 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
420 break; 428 break;
421 } 429 }
422 } 430 }
423 up_read(&tomoyo_pattern_list_lock);
424 if (pattern) 431 if (pattern)
425 filename = pattern; 432 filename = pattern;
426 return filename; 433 return filename;
@@ -433,6 +440,8 @@ tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
433 * @is_delete: True if it is a delete request. 440 * @is_delete: True if it is a delete request.
434 * 441 *
435 * Returns 0 on success, negative value otherwise. 442 * Returns 0 on success, negative value otherwise.
443 *
444 * Caller holds tomoyo_read_lock().
436 */ 445 */
437int tomoyo_write_pattern_policy(char *data, const bool is_delete) 446int tomoyo_write_pattern_policy(char *data, const bool is_delete)
438{ 447{
@@ -445,13 +454,14 @@ int tomoyo_write_pattern_policy(char *data, const bool is_delete)
445 * @head: Pointer to "struct tomoyo_io_buffer". 454 * @head: Pointer to "struct tomoyo_io_buffer".
446 * 455 *
447 * Returns true on success, false otherwise. 456 * Returns true on success, false otherwise.
457 *
458 * Caller holds tomoyo_read_lock().
448 */ 459 */
449bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head) 460bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
450{ 461{
451 struct list_head *pos; 462 struct list_head *pos;
452 bool done = true; 463 bool done = true;
453 464
454 down_read(&tomoyo_pattern_list_lock);
455 list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) { 465 list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) {
456 struct tomoyo_pattern_entry *ptr; 466 struct tomoyo_pattern_entry *ptr;
457 ptr = list_entry(pos, struct tomoyo_pattern_entry, list); 467 ptr = list_entry(pos, struct tomoyo_pattern_entry, list);
@@ -462,7 +472,6 @@ bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
462 if (!done) 472 if (!done)
463 break; 473 break;
464 } 474 }
465 up_read(&tomoyo_pattern_list_lock);
466 return done; 475 return done;
467} 476}
468 477
@@ -505,6 +514,8 @@ static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock);
505 * @is_delete: True if it is a delete request. 514 * @is_delete: True if it is a delete request.
506 * 515 *
507 * Returns 0 on success, negative value otherwise. 516 * Returns 0 on success, negative value otherwise.
517 *
518 * Caller holds tomoyo_read_lock().
508 */ 519 */
509static int tomoyo_update_no_rewrite_entry(const char *pattern, 520static int tomoyo_update_no_rewrite_entry(const char *pattern,
510 const bool is_delete) 521 const bool is_delete)
@@ -519,7 +530,7 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
519 if (!saved_pattern) 530 if (!saved_pattern)
520 return -ENOMEM; 531 return -ENOMEM;
521 down_write(&tomoyo_no_rewrite_list_lock); 532 down_write(&tomoyo_no_rewrite_list_lock);
522 list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) { 533 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
523 if (ptr->pattern != saved_pattern) 534 if (ptr->pattern != saved_pattern)
524 continue; 535 continue;
525 ptr->is_deleted = is_delete; 536 ptr->is_deleted = is_delete;
@@ -534,7 +545,7 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
534 if (!new_entry) 545 if (!new_entry)
535 goto out; 546 goto out;
536 new_entry->pattern = saved_pattern; 547 new_entry->pattern = saved_pattern;
537 list_add_tail(&new_entry->list, &tomoyo_no_rewrite_list); 548 list_add_tail_rcu(&new_entry->list, &tomoyo_no_rewrite_list);
538 error = 0; 549 error = 0;
539 out: 550 out:
540 up_write(&tomoyo_no_rewrite_list_lock); 551 up_write(&tomoyo_no_rewrite_list_lock);
@@ -548,14 +559,15 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
548 * 559 *
549 * Returns true if @filename is specified by "deny_rewrite" directive, 560 * Returns true if @filename is specified by "deny_rewrite" directive,
550 * false otherwise. 561 * false otherwise.
562 *
563 * Caller holds tomoyo_read_lock().
551 */ 564 */
552static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename) 565static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
553{ 566{
554 struct tomoyo_no_rewrite_entry *ptr; 567 struct tomoyo_no_rewrite_entry *ptr;
555 bool found = false; 568 bool found = false;
556 569
557 down_read(&tomoyo_no_rewrite_list_lock); 570 list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
558 list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) {
559 if (ptr->is_deleted) 571 if (ptr->is_deleted)
560 continue; 572 continue;
561 if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) 573 if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
@@ -563,7 +575,6 @@ static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
563 found = true; 575 found = true;
564 break; 576 break;
565 } 577 }
566 up_read(&tomoyo_no_rewrite_list_lock);
567 return found; 578 return found;
568} 579}
569 580
@@ -574,6 +585,8 @@ static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
574 * @is_delete: True if it is a delete request. 585 * @is_delete: True if it is a delete request.
575 * 586 *
576 * Returns 0 on success, negative value otherwise. 587 * Returns 0 on success, negative value otherwise.
588 *
589 * Caller holds tomoyo_read_lock().
577 */ 590 */
578int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete) 591int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete)
579{ 592{
@@ -586,13 +599,14 @@ int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete)
586 * @head: Pointer to "struct tomoyo_io_buffer". 599 * @head: Pointer to "struct tomoyo_io_buffer".
587 * 600 *
588 * Returns true on success, false otherwise. 601 * Returns true on success, false otherwise.
602 *
603 * Caller holds tomoyo_read_lock().
589 */ 604 */
590bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head) 605bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
591{ 606{
592 struct list_head *pos; 607 struct list_head *pos;
593 bool done = true; 608 bool done = true;
594 609
595 down_read(&tomoyo_no_rewrite_list_lock);
596 list_for_each_cookie(pos, head->read_var2, &tomoyo_no_rewrite_list) { 610 list_for_each_cookie(pos, head->read_var2, &tomoyo_no_rewrite_list) {
597 struct tomoyo_no_rewrite_entry *ptr; 611 struct tomoyo_no_rewrite_entry *ptr;
598 ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list); 612 ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list);
@@ -603,7 +617,6 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
603 if (!done) 617 if (!done)
604 break; 618 break;
605 } 619 }
606 up_read(&tomoyo_no_rewrite_list_lock);
607 return done; 620 return done;
608} 621}
609 622
@@ -621,6 +634,8 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
621 * Current policy syntax uses "allow_read/write" instead of "6", 634 * Current policy syntax uses "allow_read/write" instead of "6",
622 * "allow_read" instead of "4", "allow_write" instead of "2", 635 * "allow_read" instead of "4", "allow_write" instead of "2",
623 * "allow_execute" instead of "1". 636 * "allow_execute" instead of "1".
637 *
638 * Caller holds tomoyo_read_lock().
624 */ 639 */
625static int tomoyo_update_file_acl(const char *filename, u8 perm, 640static int tomoyo_update_file_acl(const char *filename, u8 perm,
626 struct tomoyo_domain_info * const domain, 641 struct tomoyo_domain_info * const domain,
@@ -658,6 +673,8 @@ static int tomoyo_update_file_acl(const char *filename, u8 perm,
658 * @may_use_pattern: True if patterned ACL is permitted. 673 * @may_use_pattern: True if patterned ACL is permitted.
659 * 674 *
660 * Returns 0 on success, -EPERM otherwise. 675 * Returns 0 on success, -EPERM otherwise.
676 *
677 * Caller holds tomoyo_read_lock().
661 */ 678 */
662static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info * 679static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info *
663 domain, 680 domain,
@@ -669,8 +686,7 @@ static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info *
669 struct tomoyo_acl_info *ptr; 686 struct tomoyo_acl_info *ptr;
670 int error = -EPERM; 687 int error = -EPERM;
671 688
672 down_read(&tomoyo_domain_acl_info_list_lock); 689 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
673 list_for_each_entry(ptr, &domain->acl_info_list, list) {
674 struct tomoyo_single_path_acl_record *acl; 690 struct tomoyo_single_path_acl_record *acl;
675 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL) 691 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL)
676 continue; 692 continue;
@@ -693,7 +709,6 @@ static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info *
693 error = 0; 709 error = 0;
694 break; 710 break;
695 } 711 }
696 up_read(&tomoyo_domain_acl_info_list_lock);
697 return error; 712 return error;
698} 713}
699 714
@@ -705,6 +720,8 @@ static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info *
705 * @operation: Mode ("read" or "write" or "read/write" or "execute"). 720 * @operation: Mode ("read" or "write" or "read/write" or "execute").
706 * 721 *
707 * Returns 0 on success, -EPERM otherwise. 722 * Returns 0 on success, -EPERM otherwise.
723 *
724 * Caller holds tomoyo_read_lock().
708 */ 725 */
709static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain, 726static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain,
710 const struct tomoyo_path_info *filename, 727 const struct tomoyo_path_info *filename,
@@ -738,6 +755,8 @@ static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain,
738 * @mode: Access control mode. 755 * @mode: Access control mode.
739 * 756 *
740 * Returns 0 on success, negative value otherwise. 757 * Returns 0 on success, negative value otherwise.
758 *
759 * Caller holds tomoyo_read_lock().
741 */ 760 */
742static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain, 761static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
743 const struct tomoyo_path_info *filename, 762 const struct tomoyo_path_info *filename,
@@ -791,6 +810,8 @@ static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
791 * @is_delete: True if it is a delete request. 810 * @is_delete: True if it is a delete request.
792 * 811 *
793 * Returns 0 on success, negative value otherwise. 812 * Returns 0 on success, negative value otherwise.
813 *
814 * Caller holds tomoyo_read_lock().
794 */ 815 */
795int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain, 816int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
796 const bool is_delete) 817 const bool is_delete)
@@ -838,6 +859,8 @@ int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
838 * @is_delete: True if it is a delete request. 859 * @is_delete: True if it is a delete request.
839 * 860 *
840 * Returns 0 on success, negative value otherwise. 861 * Returns 0 on success, negative value otherwise.
862 *
863 * Caller holds tomoyo_read_lock().
841 */ 864 */
842static int tomoyo_update_single_path_acl(const u8 type, const char *filename, 865static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
843 struct tomoyo_domain_info * 866 struct tomoyo_domain_info *
@@ -861,7 +884,7 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
861 down_write(&tomoyo_domain_acl_info_list_lock); 884 down_write(&tomoyo_domain_acl_info_list_lock);
862 if (is_delete) 885 if (is_delete)
863 goto delete; 886 goto delete;
864 list_for_each_entry(ptr, &domain->acl_info_list, list) { 887 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
865 if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL) 888 if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL)
866 continue; 889 continue;
867 acl = container_of(ptr, struct tomoyo_single_path_acl_record, 890 acl = container_of(ptr, struct tomoyo_single_path_acl_record,
@@ -894,12 +917,12 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
894 if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL)) 917 if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL))
895 acl->perm |= rw_mask; 918 acl->perm |= rw_mask;
896 acl->filename = saved_filename; 919 acl->filename = saved_filename;
897 list_add_tail(&acl->head.list, &domain->acl_info_list); 920 list_add_tail_rcu(&acl->head.list, &domain->acl_info_list);
898 error = 0; 921 error = 0;
899 goto out; 922 goto out;
900 delete: 923 delete:
901 error = -ENOENT; 924 error = -ENOENT;
902 list_for_each_entry(ptr, &domain->acl_info_list, list) { 925 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
903 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL) 926 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL)
904 continue; 927 continue;
905 acl = container_of(ptr, struct tomoyo_single_path_acl_record, 928 acl = container_of(ptr, struct tomoyo_single_path_acl_record,
@@ -934,6 +957,8 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
934 * @is_delete: True if it is a delete request. 957 * @is_delete: True if it is a delete request.
935 * 958 *
936 * Returns 0 on success, negative value otherwise. 959 * Returns 0 on success, negative value otherwise.
960 *
961 * Caller holds tomoyo_read_lock().
937 */ 962 */
938static int tomoyo_update_double_path_acl(const u8 type, const char *filename1, 963static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
939 const char *filename2, 964 const char *filename2,
@@ -959,7 +984,7 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
959 down_write(&tomoyo_domain_acl_info_list_lock); 984 down_write(&tomoyo_domain_acl_info_list_lock);
960 if (is_delete) 985 if (is_delete)
961 goto delete; 986 goto delete;
962 list_for_each_entry(ptr, &domain->acl_info_list, list) { 987 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
963 if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL) 988 if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
964 continue; 989 continue;
965 acl = container_of(ptr, struct tomoyo_double_path_acl_record, 990 acl = container_of(ptr, struct tomoyo_double_path_acl_record,
@@ -982,12 +1007,12 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
982 acl->perm = perm; 1007 acl->perm = perm;
983 acl->filename1 = saved_filename1; 1008 acl->filename1 = saved_filename1;
984 acl->filename2 = saved_filename2; 1009 acl->filename2 = saved_filename2;
985 list_add_tail(&acl->head.list, &domain->acl_info_list); 1010 list_add_tail_rcu(&acl->head.list, &domain->acl_info_list);
986 error = 0; 1011 error = 0;
987 goto out; 1012 goto out;
988 delete: 1013 delete:
989 error = -ENOENT; 1014 error = -ENOENT;
990 list_for_each_entry(ptr, &domain->acl_info_list, list) { 1015 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
991 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL) 1016 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
992 continue; 1017 continue;
993 acl = container_of(ptr, struct tomoyo_double_path_acl_record, 1018 acl = container_of(ptr, struct tomoyo_double_path_acl_record,
@@ -1014,6 +1039,8 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
1014 * @filename: Filename to check. 1039 * @filename: Filename to check.
1015 * 1040 *
1016 * Returns 0 on success, negative value otherwise. 1041 * Returns 0 on success, negative value otherwise.
1042 *
1043 * Caller holds tomoyo_read_lock().
1017 */ 1044 */
1018static int tomoyo_check_single_path_acl(struct tomoyo_domain_info *domain, 1045static int tomoyo_check_single_path_acl(struct tomoyo_domain_info *domain,
1019 const u8 type, 1046 const u8 type,
@@ -1033,6 +1060,8 @@ static int tomoyo_check_single_path_acl(struct tomoyo_domain_info *domain,
1033 * @filename2: Second filename to check. 1060 * @filename2: Second filename to check.
1034 * 1061 *
1035 * Returns 0 on success, -EPERM otherwise. 1062 * Returns 0 on success, -EPERM otherwise.
1063 *
1064 * Caller holds tomoyo_read_lock().
1036 */ 1065 */
1037static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain, 1066static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
1038 const u8 type, 1067 const u8 type,
@@ -1047,8 +1076,7 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
1047 1076
1048 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) 1077 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
1049 return 0; 1078 return 0;
1050 down_read(&tomoyo_domain_acl_info_list_lock); 1079 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
1051 list_for_each_entry(ptr, &domain->acl_info_list, list) {
1052 struct tomoyo_double_path_acl_record *acl; 1080 struct tomoyo_double_path_acl_record *acl;
1053 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL) 1081 if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
1054 continue; 1082 continue;
@@ -1063,7 +1091,6 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
1063 error = 0; 1091 error = 0;
1064 break; 1092 break;
1065 } 1093 }
1066 up_read(&tomoyo_domain_acl_info_list_lock);
1067 return error; 1094 return error;
1068} 1095}
1069 1096
@@ -1076,6 +1103,8 @@ static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
1076 * @mode: Access control mode. 1103 * @mode: Access control mode.
1077 * 1104 *
1078 * Returns 0 on success, negative value otherwise. 1105 * Returns 0 on success, negative value otherwise.
1106 *
1107 * Caller holds tomoyo_read_lock().
1079 */ 1108 */
1080static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info * 1109static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info *
1081 const domain, u8 operation, 1110 const domain, u8 operation,
@@ -1124,6 +1153,8 @@ static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info *
1124 * @filename: Check permission for "execute". 1153 * @filename: Check permission for "execute".
1125 * 1154 *
1126 * Returns 0 on success, negativevalue otherwise. 1155 * Returns 0 on success, negativevalue otherwise.
1156 *
1157 * Caller holds tomoyo_read_lock().
1127 */ 1158 */
1128int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, 1159int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain,
1129 const struct tomoyo_path_info *filename) 1160 const struct tomoyo_path_info *filename)
@@ -1152,6 +1183,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1152 struct tomoyo_path_info *buf; 1183 struct tomoyo_path_info *buf;
1153 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1184 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1154 const bool is_enforce = (mode == 3); 1185 const bool is_enforce = (mode == 3);
1186 int idx;
1155 1187
1156 if (!mode || !path->mnt) 1188 if (!mode || !path->mnt)
1157 return 0; 1189 return 0;
@@ -1163,6 +1195,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1163 * don't call me. 1195 * don't call me.
1164 */ 1196 */
1165 return 0; 1197 return 0;
1198 idx = tomoyo_read_lock();
1166 buf = tomoyo_get_path(path); 1199 buf = tomoyo_get_path(path);
1167 if (!buf) 1200 if (!buf)
1168 goto out; 1201 goto out;
@@ -1188,6 +1221,7 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1188 buf, mode); 1221 buf, mode);
1189 out: 1222 out:
1190 tomoyo_free(buf); 1223 tomoyo_free(buf);
1224 tomoyo_read_unlock(idx);
1191 if (!is_enforce) 1225 if (!is_enforce)
1192 error = 0; 1226 error = 0;
1193 return error; 1227 return error;
@@ -1209,9 +1243,11 @@ int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain,
1209 struct tomoyo_path_info *buf; 1243 struct tomoyo_path_info *buf;
1210 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1244 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1211 const bool is_enforce = (mode == 3); 1245 const bool is_enforce = (mode == 3);
1246 int idx;
1212 1247
1213 if (!mode || !path->mnt) 1248 if (!mode || !path->mnt)
1214 return 0; 1249 return 0;
1250 idx = tomoyo_read_lock();
1215 buf = tomoyo_get_path(path); 1251 buf = tomoyo_get_path(path);
1216 if (!buf) 1252 if (!buf)
1217 goto out; 1253 goto out;
@@ -1231,6 +1267,7 @@ int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain,
1231 mode); 1267 mode);
1232 out: 1268 out:
1233 tomoyo_free(buf); 1269 tomoyo_free(buf);
1270 tomoyo_read_unlock(idx);
1234 if (!is_enforce) 1271 if (!is_enforce)
1235 error = 0; 1272 error = 0;
1236 return error; 1273 return error;
@@ -1251,9 +1288,12 @@ int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain,
1251 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1288 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1252 const bool is_enforce = (mode == 3); 1289 const bool is_enforce = (mode == 3);
1253 struct tomoyo_path_info *buf; 1290 struct tomoyo_path_info *buf;
1291 int idx;
1254 1292
1255 if (!mode || !filp->f_path.mnt) 1293 if (!mode || !filp->f_path.mnt)
1256 return 0; 1294 return 0;
1295
1296 idx = tomoyo_read_lock();
1257 buf = tomoyo_get_path(&filp->f_path); 1297 buf = tomoyo_get_path(&filp->f_path);
1258 if (!buf) 1298 if (!buf)
1259 goto out; 1299 goto out;
@@ -1266,6 +1306,7 @@ int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain,
1266 buf, mode); 1306 buf, mode);
1267 out: 1307 out:
1268 tomoyo_free(buf); 1308 tomoyo_free(buf);
1309 tomoyo_read_unlock(idx);
1269 if (!is_enforce) 1310 if (!is_enforce)
1270 error = 0; 1311 error = 0;
1271 return error; 1312 return error;
@@ -1290,9 +1331,11 @@ int tomoyo_check_2path_perm(struct tomoyo_domain_info * const domain,
1290 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1331 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1291 const bool is_enforce = (mode == 3); 1332 const bool is_enforce = (mode == 3);
1292 const char *msg; 1333 const char *msg;
1334 int idx;
1293 1335
1294 if (!mode || !path1->mnt || !path2->mnt) 1336 if (!mode || !path1->mnt || !path2->mnt)
1295 return 0; 1337 return 0;
1338 idx = tomoyo_read_lock();
1296 buf1 = tomoyo_get_path(path1); 1339 buf1 = tomoyo_get_path(path1);
1297 buf2 = tomoyo_get_path(path2); 1340 buf2 = tomoyo_get_path(path2);
1298 if (!buf1 || !buf2) 1341 if (!buf1 || !buf2)
@@ -1331,6 +1374,7 @@ int tomoyo_check_2path_perm(struct tomoyo_domain_info * const domain,
1331 out: 1374 out:
1332 tomoyo_free(buf1); 1375 tomoyo_free(buf1);
1333 tomoyo_free(buf2); 1376 tomoyo_free(buf2);
1377 tomoyo_read_unlock(idx);
1334 if (!is_enforce) 1378 if (!is_enforce)
1335 error = 0; 1379 error = 0;
1336 return error; 1380 return error;