aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/tomoyo/common.c22
-rw-r--r--security/tomoyo/common.h27
-rw-r--r--security/tomoyo/domain.c2
-rw-r--r--security/tomoyo/file.c315
-rw-r--r--security/tomoyo/tomoyo.c2
5 files changed, 162 insertions, 206 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index d82c2978b1be..34d65871096c 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -985,21 +985,6 @@ static const char *tomoyo_get_exe(void)
985} 985}
986 986
987/** 987/**
988 * tomoyo_get_msg - Get warning message.
989 *
990 * @is_enforce: Is it enforcing mode?
991 *
992 * Returns "ERROR" or "WARNING".
993 */
994const char *tomoyo_get_msg(const bool is_enforce)
995{
996 if (is_enforce)
997 return "ERROR";
998 else
999 return "WARNING";
1000}
1001
1002/**
1003 * tomoyo_check_flags - Check mode for specified functionality. 988 * tomoyo_check_flags - Check mode for specified functionality.
1004 * 989 *
1005 * @domain: Pointer to "struct tomoyo_domain_info". 990 * @domain: Pointer to "struct tomoyo_domain_info".
@@ -1040,17 +1025,20 @@ bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain)
1040/** 1025/**
1041 * tomoyo_domain_quota_is_ok - Check for domain's quota. 1026 * tomoyo_domain_quota_is_ok - Check for domain's quota.
1042 * 1027 *
1043 * @domain: Pointer to "struct tomoyo_domain_info". 1028 * @r: Pointer to "struct tomoyo_request_info".
1044 * 1029 *
1045 * Returns true if the domain is not exceeded quota, false otherwise. 1030 * Returns true if the domain is not exceeded quota, false otherwise.
1046 * 1031 *
1047 * Caller holds tomoyo_read_lock(). 1032 * Caller holds tomoyo_read_lock().
1048 */ 1033 */
1049bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain) 1034bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
1050{ 1035{
1051 unsigned int count = 0; 1036 unsigned int count = 0;
1037 struct tomoyo_domain_info *domain = r->domain;
1052 struct tomoyo_acl_info *ptr; 1038 struct tomoyo_acl_info *ptr;
1053 1039
1040 if (r->mode != TOMOYO_CONFIG_LEARNING)
1041 return false;
1054 if (!domain) 1042 if (!domain)
1055 return true; 1043 return true;
1056 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 1044 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 33d3072f9bb4..91e2bcfd56e3 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -44,6 +44,13 @@ struct linux_binprm;
44/* Profile number is an integer between 0 and 255. */ 44/* Profile number is an integer between 0 and 255. */
45#define TOMOYO_MAX_PROFILES 256 45#define TOMOYO_MAX_PROFILES 256
46 46
47enum tomoyo_mode_index {
48 TOMOYO_CONFIG_DISABLED,
49 TOMOYO_CONFIG_LEARNING,
50 TOMOYO_CONFIG_PERMISSIVE,
51 TOMOYO_CONFIG_ENFORCING
52};
53
47/* Keywords for ACLs. */ 54/* Keywords for ACLs. */
48#define TOMOYO_KEYWORD_ALIAS "alias " 55#define TOMOYO_KEYWORD_ALIAS "alias "
49#define TOMOYO_KEYWORD_ALLOW_READ "allow_read " 56#define TOMOYO_KEYWORD_ALLOW_READ "allow_read "
@@ -153,6 +160,17 @@ struct tomoyo_page_buffer {
153}; 160};
154 161
155/* 162/*
163 * tomoyo_request_info is a structure which is used for holding
164 *
165 * (1) Domain information of current process.
166 * (2) Access control mode of the profile.
167 */
168struct tomoyo_request_info {
169 struct tomoyo_domain_info *domain;
170 u8 mode; /* One of tomoyo_mode_index . */
171};
172
173/*
156 * tomoyo_path_info is a structure which is used for holding a string data 174 * tomoyo_path_info is a structure which is used for holding a string data
157 * used by TOMOYO. 175 * used by TOMOYO.
158 * This structure has several fields for supporting pattern matching. 176 * This structure has several fields for supporting pattern matching.
@@ -332,8 +350,8 @@ struct tomoyo_domain_info {
332 * "allow_read", "allow_write", "allow_create", "allow_unlink", "allow_mkdir", 350 * "allow_read", "allow_write", "allow_create", "allow_unlink", "allow_mkdir",
333 * "allow_rmdir", "allow_mkfifo", "allow_mksock", "allow_mkblock", 351 * "allow_rmdir", "allow_mkfifo", "allow_mksock", "allow_mkblock",
334 * "allow_mkchar", "allow_truncate", "allow_symlink", "allow_rewrite", 352 * "allow_mkchar", "allow_truncate", "allow_symlink", "allow_rewrite",
335 * "allow_chmod", "allow_chown", "allow_chgrp", "allow_chroot", "allow_mount" 353 * "allow_ioctl", "allow_chmod", "allow_chown", "allow_chgrp", "allow_chroot",
336 * and "allow_unmount". 354 * "allow_mount" and "allow_unmount".
337 */ 355 */
338struct tomoyo_path_acl { 356struct tomoyo_path_acl {
339 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_ACL */ 357 struct tomoyo_acl_info head; /* type = TOMOYO_TYPE_PATH_ACL */
@@ -567,7 +585,7 @@ struct tomoyo_policy_manager_entry {
567bool tomoyo_compare_name_union(const struct tomoyo_path_info *name, 585bool tomoyo_compare_name_union(const struct tomoyo_path_info *name,
568 const struct tomoyo_name_union *ptr); 586 const struct tomoyo_name_union *ptr);
569/* Check whether the domain has too many ACL entries to hold. */ 587/* Check whether the domain has too many ACL entries to hold. */
570bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain); 588bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r);
571/* Transactional sprintf() for policy dump. */ 589/* Transactional sprintf() for policy dump. */
572bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...) 590bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
573 __attribute__ ((format(printf, 2, 3))); 591 __attribute__ ((format(printf, 2, 3)));
@@ -623,8 +641,6 @@ bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain);
623const char *tomoyo_path22keyword(const u8 operation); 641const char *tomoyo_path22keyword(const u8 operation);
624/* Get the last component of the given domainname. */ 642/* Get the last component of the given domainname. */
625const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain); 643const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain);
626/* Get warning message. */
627const char *tomoyo_get_msg(const bool is_enforce);
628/* Convert single path operation to operation name. */ 644/* Convert single path operation to operation name. */
629const char *tomoyo_path2keyword(const u8 operation); 645const char *tomoyo_path2keyword(const u8 operation);
630/* Create "alias" entry in exception policy. */ 646/* Create "alias" entry in exception policy. */
@@ -723,7 +739,6 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
723int tomoyo_path_perm(const u8 operation, struct path *path); 739int tomoyo_path_perm(const u8 operation, struct path *path);
724int tomoyo_path2_perm(const u8 operation, struct path *path1, 740int tomoyo_path2_perm(const u8 operation, struct path *path1,
725 struct path *path2); 741 struct path *path2);
726int tomoyo_check_rewrite_permission(struct file *filp);
727int tomoyo_find_next_domain(struct linux_binprm *bprm); 742int tomoyo_find_next_domain(struct linux_binprm *bprm);
728 743
729/* Drop refcount on tomoyo_name_union. */ 744/* Drop refcount on tomoyo_name_union. */
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index cd8ba4446763..afdf26128bfe 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -691,7 +691,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)
691 char *real_program_name = NULL; 691 char *real_program_name = NULL;
692 char *symlink_program_name = NULL; 692 char *symlink_program_name = NULL;
693 const u8 mode = tomoyo_check_flags(old_domain, TOMOYO_MAC_FOR_FILE); 693 const u8 mode = tomoyo_check_flags(old_domain, TOMOYO_MAC_FOR_FILE);
694 const bool is_enforce = (mode == 3); 694 const bool is_enforce = (mode == TOMOYO_CONFIG_ENFORCING);
695 int retval = -ENOMEM; 695 int retval = -ENOMEM;
696 struct tomoyo_path_info r; /* real name */ 696 struct tomoyo_path_info r; /* real name */
697 struct tomoyo_path_info s; /* symlink name */ 697 struct tomoyo_path_info s; /* symlink name */
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 2dffe0730918..f1d2adfd33bc 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -91,6 +91,61 @@ bool tomoyo_compare_number_union(const unsigned long value,
91} 91}
92 92
93/** 93/**
94 * tomoyo_init_request_info - Initialize "struct tomoyo_request_info" members.
95 *
96 * @r: Pointer to "struct tomoyo_request_info" to initialize.
97 * @domain: Pointer to "struct tomoyo_domain_info". NULL for tomoyo_domain().
98 *
99 * Returns mode.
100 */
101static int tomoyo_init_request_info(struct tomoyo_request_info *r,
102 struct tomoyo_domain_info *domain)
103{
104 memset(r, 0, sizeof(*r));
105 if (!domain)
106 domain = tomoyo_domain();
107 r->domain = domain;
108 r->mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
109 return r->mode;
110}
111
112static void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...)
113 __attribute__ ((format(printf, 2, 3)));
114/**
115 * tomoyo_warn_log - Print warning or error message on console.
116 *
117 * @r: Pointer to "struct tomoyo_request_info".
118 * @fmt: The printf()'s format string, followed by parameters.
119 */
120static void tomoyo_warn_log(struct tomoyo_request_info *r, const char *fmt, ...)
121{
122 int len = PAGE_SIZE;
123 va_list args;
124 char *buffer;
125 if (!tomoyo_verbose_mode(r->domain))
126 return;
127 while (1) {
128 int len2;
129 buffer = kmalloc(len, GFP_NOFS);
130 if (!buffer)
131 return;
132 va_start(args, fmt);
133 len2 = vsnprintf(buffer, len - 1, fmt, args);
134 va_end(args);
135 if (len2 <= len - 1) {
136 buffer[len2] = '\0';
137 break;
138 }
139 len = len2 + 1;
140 kfree(buffer);
141 }
142 printk(KERN_WARNING "TOMOYO-%s: Access %s denied for %s\n",
143 r->mode == TOMOYO_CONFIG_ENFORCING ? "ERROR" : "WARNING",
144 buffer, tomoyo_get_last_name(r->domain));
145 kfree(buffer);
146}
147
148/**
94 * tomoyo_path2keyword - Get the name of single path operation. 149 * tomoyo_path2keyword - Get the name of single path operation.
95 * 150 *
96 * @operation: Type of operation. 151 * @operation: Type of operation.
@@ -652,9 +707,9 @@ static int tomoyo_update_file_acl(const char *filename, u8 perm,
652} 707}
653 708
654/** 709/**
655 * tomoyo_path_acl2 - Check permission for single path operation. 710 * tomoyo_path_acl - Check permission for single path operation.
656 * 711 *
657 * @domain: Pointer to "struct tomoyo_domain_info". 712 * @r: Pointer to "struct tomoyo_request_info".
658 * @filename: Filename to check. 713 * @filename: Filename to check.
659 * @perm: Permission. 714 * @perm: Permission.
660 * @may_use_pattern: True if patterned ACL is permitted. 715 * @may_use_pattern: True if patterned ACL is permitted.
@@ -663,10 +718,11 @@ static int tomoyo_update_file_acl(const char *filename, u8 perm,
663 * 718 *
664 * Caller holds tomoyo_read_lock(). 719 * Caller holds tomoyo_read_lock().
665 */ 720 */
666static int tomoyo_path_acl2(const struct tomoyo_domain_info *domain, 721static int tomoyo_path_acl(const struct tomoyo_request_info *r,
667 const struct tomoyo_path_info *filename, 722 const struct tomoyo_path_info *filename,
668 const u32 perm, const bool may_use_pattern) 723 const u32 perm, const bool may_use_pattern)
669{ 724{
725 struct tomoyo_domain_info *domain = r->domain;
670 struct tomoyo_acl_info *ptr; 726 struct tomoyo_acl_info *ptr;
671 int error = -EPERM; 727 int error = -EPERM;
672 728
@@ -692,89 +748,56 @@ static int tomoyo_path_acl2(const struct tomoyo_domain_info *domain,
692} 748}
693 749
694/** 750/**
695 * tomoyo_check_file_acl - Check permission for opening files. 751 * tomoyo_file_perm - Check permission for opening files.
696 * 752 *
697 * @domain: Pointer to "struct tomoyo_domain_info". 753 * @r: Pointer to "struct tomoyo_request_info".
698 * @filename: Filename to check. 754 * @filename: Filename to check.
699 * @operation: Mode ("read" or "write" or "read/write" or "execute"). 755 * @mode: Mode ("read" or "write" or "read/write" or "execute").
700 *
701 * Returns 0 on success, -EPERM otherwise.
702 *
703 * Caller holds tomoyo_read_lock().
704 */
705static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain,
706 const struct tomoyo_path_info *filename,
707 const u8 operation)
708{
709 u32 perm = 0;
710
711 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
712 return 0;
713 if (operation == 6)
714 perm = 1 << TOMOYO_TYPE_READ_WRITE;
715 else if (operation == 4)
716 perm = 1 << TOMOYO_TYPE_READ;
717 else if (operation == 2)
718 perm = 1 << TOMOYO_TYPE_WRITE;
719 else if (operation == 1)
720 perm = 1 << TOMOYO_TYPE_EXECUTE;
721 else
722 BUG();
723 return tomoyo_path_acl2(domain, filename, perm, operation != 1);
724}
725
726/**
727 * tomoyo_check_file_perm2 - Check permission for opening files.
728 *
729 * @domain: Pointer to "struct tomoyo_domain_info".
730 * @filename: Filename to check.
731 * @perm: Mode ("read" or "write" or "read/write" or "execute").
732 * @operation: Operation name passed used for verbose mode.
733 * @mode: Access control mode.
734 * 756 *
735 * Returns 0 on success, negative value otherwise. 757 * Returns 0 on success, negative value otherwise.
736 * 758 *
737 * Caller holds tomoyo_read_lock(). 759 * Caller holds tomoyo_read_lock().
738 */ 760 */
739static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain, 761static int tomoyo_file_perm(struct tomoyo_request_info *r,
740 const struct tomoyo_path_info *filename, 762 const struct tomoyo_path_info *filename,
741 const u8 perm, const char *operation, 763 const u8 mode)
742 const u8 mode)
743{ 764{
744 const bool is_enforce = (mode == 3);
745 const char *msg = "<unknown>"; 765 const char *msg = "<unknown>";
746 int error = 0; 766 int error = 0;
767 u32 perm = 0;
747 768
748 if (!filename) 769 if (!filename)
749 return 0; 770 return 0;
750 error = tomoyo_check_file_acl(domain, filename, perm); 771
751 if (error && perm == 4 && !domain->ignore_global_allow_read 772 if (mode == 6) {
752 && tomoyo_is_globally_readable_file(filename))
753 error = 0;
754 if (perm == 6)
755 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ_WRITE); 773 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ_WRITE);
756 else if (perm == 4) 774 perm = 1 << TOMOYO_TYPE_READ_WRITE;
775 } else if (mode == 4) {
757 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ); 776 msg = tomoyo_path2keyword(TOMOYO_TYPE_READ);
758 else if (perm == 2) 777 perm = 1 << TOMOYO_TYPE_READ;
778 } else if (mode == 2) {
759 msg = tomoyo_path2keyword(TOMOYO_TYPE_WRITE); 779 msg = tomoyo_path2keyword(TOMOYO_TYPE_WRITE);
760 else if (perm == 1) 780 perm = 1 << TOMOYO_TYPE_WRITE;
781 } else if (mode == 1) {
761 msg = tomoyo_path2keyword(TOMOYO_TYPE_EXECUTE); 782 msg = tomoyo_path2keyword(TOMOYO_TYPE_EXECUTE);
762 else 783 perm = 1 << TOMOYO_TYPE_EXECUTE;
784 } else
763 BUG(); 785 BUG();
786 error = tomoyo_path_acl(r, filename, perm, mode != 1);
787 if (error && mode == 4 && !r->domain->ignore_global_allow_read
788 && tomoyo_is_globally_readable_file(filename))
789 error = 0;
764 if (!error) 790 if (!error)
765 return 0; 791 return 0;
766 if (tomoyo_verbose_mode(domain)) 792 tomoyo_warn_log(r, "%s %s", msg, filename->name);
767 printk(KERN_WARNING "TOMOYO-%s: Access '%s(%s) %s' denied " 793 if (r->mode == TOMOYO_CONFIG_ENFORCING)
768 "for %s\n", tomoyo_get_msg(is_enforce), msg, operation,
769 filename->name, tomoyo_get_last_name(domain));
770 if (is_enforce)
771 return error; 794 return error;
772 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) { 795 if (tomoyo_domain_quota_is_ok(r)) {
773 /* Don't use patterns for execute permission. */ 796 /* Don't use patterns for execute permission. */
774 const struct tomoyo_path_info *patterned_file = (perm != 1) ? 797 const struct tomoyo_path_info *patterned_file = (mode != 1) ?
775 tomoyo_get_file_pattern(filename) : filename; 798 tomoyo_get_file_pattern(filename) : filename;
776 tomoyo_update_file_acl(patterned_file->name, perm, 799 tomoyo_update_file_acl(patterned_file->name, mode,
777 domain, false); 800 r->domain, false);
778 } 801 }
779 return 0; 802 return 0;
780} 803}
@@ -966,28 +989,9 @@ static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
966} 989}
967 990
968/** 991/**
969 * tomoyo_path_acl - Check permission for single path operation.
970 *
971 * @domain: Pointer to "struct tomoyo_domain_info".
972 * @type: Type of operation.
973 * @filename: Filename to check.
974 *
975 * Returns 0 on success, negative value otherwise.
976 *
977 * Caller holds tomoyo_read_lock().
978 */
979static int tomoyo_path_acl(struct tomoyo_domain_info *domain, const u8 type,
980 const struct tomoyo_path_info *filename)
981{
982 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
983 return 0;
984 return tomoyo_path_acl2(domain, filename, 1 << type, 1);
985}
986
987/**
988 * tomoyo_path2_acl - Check permission for double path operation. 992 * tomoyo_path2_acl - Check permission for double path operation.
989 * 993 *
990 * @domain: Pointer to "struct tomoyo_domain_info". 994 * @r: Pointer to "struct tomoyo_request_info".
991 * @type: Type of operation. 995 * @type: Type of operation.
992 * @filename1: First filename to check. 996 * @filename1: First filename to check.
993 * @filename2: Second filename to check. 997 * @filename2: Second filename to check.
@@ -996,17 +1000,15 @@ static int tomoyo_path_acl(struct tomoyo_domain_info *domain, const u8 type,
996 * 1000 *
997 * Caller holds tomoyo_read_lock(). 1001 * Caller holds tomoyo_read_lock().
998 */ 1002 */
999static int tomoyo_path2_acl(const struct tomoyo_domain_info *domain, 1003static int tomoyo_path2_acl(const struct tomoyo_request_info *r, const u8 type,
1000 const u8 type,
1001 const struct tomoyo_path_info *filename1, 1004 const struct tomoyo_path_info *filename1,
1002 const struct tomoyo_path_info *filename2) 1005 const struct tomoyo_path_info *filename2)
1003{ 1006{
1007 const struct tomoyo_domain_info *domain = r->domain;
1004 struct tomoyo_acl_info *ptr; 1008 struct tomoyo_acl_info *ptr;
1005 const u8 perm = 1 << type; 1009 const u8 perm = 1 << type;
1006 int error = -EPERM; 1010 int error = -EPERM;
1007 1011
1008 if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
1009 return 0;
1010 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 1012 list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
1011 struct tomoyo_path2_acl *acl; 1013 struct tomoyo_path2_acl *acl;
1012 if (ptr->type != TOMOYO_TYPE_PATH2_ACL) 1014 if (ptr->type != TOMOYO_TYPE_PATH2_ACL)
@@ -1025,42 +1027,32 @@ static int tomoyo_path2_acl(const struct tomoyo_domain_info *domain,
1025} 1027}
1026 1028
1027/** 1029/**
1028 * tomoyo_path_permission2 - Check permission for single path operation. 1030 * tomoyo_path_permission - Check permission for single path operation.
1029 * 1031 *
1030 * @domain: Pointer to "struct tomoyo_domain_info". 1032 * @r: Pointer to "struct tomoyo_request_info".
1031 * @operation: Type of operation. 1033 * @operation: Type of operation.
1032 * @filename: Filename to check. 1034 * @filename: Filename to check.
1033 * @mode: Access control mode.
1034 * 1035 *
1035 * Returns 0 on success, negative value otherwise. 1036 * Returns 0 on success, negative value otherwise.
1036 * 1037 *
1037 * Caller holds tomoyo_read_lock(). 1038 * Caller holds tomoyo_read_lock().
1038 */ 1039 */
1039static int tomoyo_path_permission2(struct tomoyo_domain_info *const domain, 1040static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
1040 u8 operation, 1041 const struct tomoyo_path_info *filename)
1041 const struct tomoyo_path_info *filename,
1042 const u8 mode)
1043{ 1042{
1044 const char *msg;
1045 int error; 1043 int error;
1046 const bool is_enforce = (mode == 3);
1047 1044
1048 if (!mode)
1049 return 0;
1050 next: 1045 next:
1051 error = tomoyo_path_acl(domain, operation, filename); 1046 error = tomoyo_path_acl(r, filename, 1 << operation, 1);
1052 msg = tomoyo_path2keyword(operation);
1053 if (!error) 1047 if (!error)
1054 goto ok; 1048 goto ok;
1055 if (tomoyo_verbose_mode(domain)) 1049 tomoyo_warn_log(r, "%s %s", tomoyo_path2keyword(operation),
1056 printk(KERN_WARNING "TOMOYO-%s: Access '%s %s' denied for %s\n", 1050 filename->name);
1057 tomoyo_get_msg(is_enforce), msg, filename->name, 1051 if (tomoyo_domain_quota_is_ok(r)) {
1058 tomoyo_get_last_name(domain));
1059 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) {
1060 const char *name = tomoyo_get_file_pattern(filename)->name; 1052 const char *name = tomoyo_get_file_pattern(filename)->name;
1061 tomoyo_update_path_acl(operation, name, domain, false); 1053 tomoyo_update_path_acl(operation, name, r->domain, false);
1062 } 1054 }
1063 if (!is_enforce) 1055 if (r->mode != TOMOYO_CONFIG_ENFORCING)
1064 error = 0; 1056 error = 0;
1065 ok: 1057 ok:
1066 /* 1058 /*
@@ -1089,11 +1081,11 @@ static int tomoyo_path_permission2(struct tomoyo_domain_info *const domain,
1089int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, 1081int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain,
1090 const struct tomoyo_path_info *filename) 1082 const struct tomoyo_path_info *filename)
1091{ 1083{
1092 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1084 struct tomoyo_request_info r;
1093 1085
1094 if (!mode) 1086 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED)
1095 return 0; 1087 return 0;
1096 return tomoyo_check_file_perm2(domain, filename, 1, "do_execve", mode); 1088 return tomoyo_file_perm(&r, filename, 1);
1097} 1089}
1098 1090
1099/** 1091/**
@@ -1111,11 +1103,11 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1111 const u8 acc_mode = ACC_MODE(flag); 1103 const u8 acc_mode = ACC_MODE(flag);
1112 int error = -ENOMEM; 1104 int error = -ENOMEM;
1113 struct tomoyo_path_info *buf; 1105 struct tomoyo_path_info *buf;
1114 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1106 struct tomoyo_request_info r;
1115 const bool is_enforce = (mode == 3);
1116 int idx; 1107 int idx;
1117 1108
1118 if (!mode || !path->mnt) 1109 if (tomoyo_init_request_info(&r, domain) == TOMOYO_CONFIG_DISABLED ||
1110 !path->mnt)
1119 return 0; 1111 return 0;
1120 if (acc_mode == 0) 1112 if (acc_mode == 0)
1121 return 0; 1113 return 0;
@@ -1138,25 +1130,22 @@ int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
1138 if ((acc_mode & MAY_WRITE) && 1130 if ((acc_mode & MAY_WRITE) &&
1139 ((flag & O_TRUNC) || !(flag & O_APPEND)) && 1131 ((flag & O_TRUNC) || !(flag & O_APPEND)) &&
1140 (tomoyo_is_no_rewrite_file(buf))) { 1132 (tomoyo_is_no_rewrite_file(buf))) {
1141 error = tomoyo_path_permission2(domain, TOMOYO_TYPE_REWRITE, 1133 error = tomoyo_path_permission(&r, TOMOYO_TYPE_REWRITE, buf);
1142 buf, mode);
1143 } 1134 }
1144 if (!error) 1135 if (!error)
1145 error = tomoyo_check_file_perm2(domain, buf, acc_mode, "open", 1136 error = tomoyo_file_perm(&r, buf, acc_mode);
1146 mode);
1147 if (!error && (flag & O_TRUNC)) 1137 if (!error && (flag & O_TRUNC))
1148 error = tomoyo_path_permission2(domain, TOMOYO_TYPE_TRUNCATE, 1138 error = tomoyo_path_permission(&r, TOMOYO_TYPE_TRUNCATE, buf);
1149 buf, mode);
1150 out: 1139 out:
1151 kfree(buf); 1140 kfree(buf);
1152 tomoyo_read_unlock(idx); 1141 tomoyo_read_unlock(idx);
1153 if (!is_enforce) 1142 if (r.mode != TOMOYO_CONFIG_ENFORCING)
1154 error = 0; 1143 error = 0;
1155 return error; 1144 return error;
1156} 1145}
1157 1146
1158/** 1147/**
1159 * tomoyo_path_perm - Check permission for "create", "unlink", "mkdir", "rmdir", "mkfifo", "mksock", "mkblock", "mkchar", "truncate", "symlink", "ioctl", "chmod", "chown", "chgrp", "chroot", "mount" and "unmount". 1148 * tomoyo_path_perm - Check permission for "create", "unlink", "mkdir", "rmdir", "mkfifo", "mksock", "mkblock", "mkchar", "truncate", "symlink", "rewrite", "ioctl", "chmod", "chown", "chgrp", "chroot", "mount" and "unmount".
1160 * 1149 *
1161 * @operation: Type of operation. 1150 * @operation: Type of operation.
1162 * @path: Pointer to "struct path". 1151 * @path: Pointer to "struct path".
@@ -1167,18 +1156,23 @@ int tomoyo_path_perm(const u8 operation, struct path *path)
1167{ 1156{
1168 int error = -ENOMEM; 1157 int error = -ENOMEM;
1169 struct tomoyo_path_info *buf; 1158 struct tomoyo_path_info *buf;
1170 struct tomoyo_domain_info *domain = tomoyo_domain(); 1159 struct tomoyo_request_info r;
1171 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1172 const bool is_enforce = (mode == 3);
1173 int idx; 1160 int idx;
1174 1161
1175 if (!mode || !path->mnt) 1162 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED ||
1163 !path->mnt)
1176 return 0; 1164 return 0;
1177 idx = tomoyo_read_lock(); 1165 idx = tomoyo_read_lock();
1178 buf = tomoyo_get_path(path); 1166 buf = tomoyo_get_path(path);
1179 if (!buf) 1167 if (!buf)
1180 goto out; 1168 goto out;
1181 switch (operation) { 1169 switch (operation) {
1170 case TOMOYO_TYPE_REWRITE:
1171 if (!tomoyo_is_no_rewrite_file(buf)) {
1172 error = 0;
1173 goto out;
1174 }
1175 break;
1182 case TOMOYO_TYPE_MKDIR: 1176 case TOMOYO_TYPE_MKDIR:
1183 case TOMOYO_TYPE_RMDIR: 1177 case TOMOYO_TYPE_RMDIR:
1184 case TOMOYO_TYPE_CHROOT: 1178 case TOMOYO_TYPE_CHROOT:
@@ -1190,47 +1184,11 @@ int tomoyo_path_perm(const u8 operation, struct path *path)
1190 tomoyo_fill_path_info(buf); 1184 tomoyo_fill_path_info(buf);
1191 } 1185 }
1192 } 1186 }
1193 error = tomoyo_path_permission2(domain, operation, buf, mode); 1187 error = tomoyo_path_permission(&r, operation, buf);
1194 out:
1195 kfree(buf);
1196 tomoyo_read_unlock(idx);
1197 if (!is_enforce)
1198 error = 0;
1199 return error;
1200}
1201
1202/**
1203 * tomoyo_check_rewrite_permission - Check permission for "rewrite".
1204 *
1205 * @filp: Pointer to "struct file".
1206 *
1207 * Returns 0 on success, negative value otherwise.
1208 */
1209int tomoyo_check_rewrite_permission(struct file *filp)
1210{
1211 int error = -ENOMEM;
1212 struct tomoyo_domain_info *domain = tomoyo_domain();
1213 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
1214 const bool is_enforce = (mode == 3);
1215 struct tomoyo_path_info *buf;
1216 int idx;
1217
1218 if (!mode || !filp->f_path.mnt)
1219 return 0;
1220
1221 idx = tomoyo_read_lock();
1222 buf = tomoyo_get_path(&filp->f_path);
1223 if (!buf)
1224 goto out;
1225 if (!tomoyo_is_no_rewrite_file(buf)) {
1226 error = 0;
1227 goto out;
1228 }
1229 error = tomoyo_path_permission2(domain, TOMOYO_TYPE_REWRITE, buf, mode);
1230 out: 1188 out:
1231 kfree(buf); 1189 kfree(buf);
1232 tomoyo_read_unlock(idx); 1190 tomoyo_read_unlock(idx);
1233 if (!is_enforce) 1191 if (r.mode != TOMOYO_CONFIG_ENFORCING)
1234 error = 0; 1192 error = 0;
1235 return error; 1193 return error;
1236} 1194}
@@ -1248,14 +1206,13 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
1248 struct path *path2) 1206 struct path *path2)
1249{ 1207{
1250 int error = -ENOMEM; 1208 int error = -ENOMEM;
1251 struct tomoyo_path_info *buf1, *buf2; 1209 struct tomoyo_path_info *buf1;
1252 struct tomoyo_domain_info *domain = tomoyo_domain(); 1210 struct tomoyo_path_info *buf2;
1253 const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE); 1211 struct tomoyo_request_info r;
1254 const bool is_enforce = (mode == 3);
1255 const char *msg;
1256 int idx; 1212 int idx;
1257 1213
1258 if (!mode || !path1->mnt || !path2->mnt) 1214 if (tomoyo_init_request_info(&r, NULL) == TOMOYO_CONFIG_DISABLED ||
1215 !path1->mnt || !path2->mnt)
1259 return 0; 1216 return 0;
1260 idx = tomoyo_read_lock(); 1217 idx = tomoyo_read_lock();
1261 buf1 = tomoyo_get_path(path1); 1218 buf1 = tomoyo_get_path(path1);
@@ -1278,26 +1235,22 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
1278 } 1235 }
1279 } 1236 }
1280 } 1237 }
1281 error = tomoyo_path2_acl(domain, operation, buf1, buf2); 1238 error = tomoyo_path2_acl(&r, operation, buf1, buf2);
1282 msg = tomoyo_path22keyword(operation);
1283 if (!error) 1239 if (!error)
1284 goto out; 1240 goto out;
1285 if (tomoyo_verbose_mode(domain)) 1241 tomoyo_warn_log(&r, "%s %s %s", tomoyo_path22keyword(operation),
1286 printk(KERN_WARNING "TOMOYO-%s: Access '%s %s %s' " 1242 buf1->name, buf2->name);
1287 "denied for %s\n", tomoyo_get_msg(is_enforce), 1243 if (tomoyo_domain_quota_is_ok(&r)) {
1288 msg, buf1->name, buf2->name,
1289 tomoyo_get_last_name(domain));
1290 if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) {
1291 const char *name1 = tomoyo_get_file_pattern(buf1)->name; 1244 const char *name1 = tomoyo_get_file_pattern(buf1)->name;
1292 const char *name2 = tomoyo_get_file_pattern(buf2)->name; 1245 const char *name2 = tomoyo_get_file_pattern(buf2)->name;
1293 tomoyo_update_path2_acl(operation, name1, name2, domain, 1246 tomoyo_update_path2_acl(operation, name1, name2, r.domain,
1294 false); 1247 false);
1295 } 1248 }
1296 out: 1249 out:
1297 kfree(buf1); 1250 kfree(buf1);
1298 kfree(buf2); 1251 kfree(buf2);
1299 tomoyo_read_unlock(idx); 1252 tomoyo_read_unlock(idx);
1300 if (!is_enforce) 1253 if (r.mode != TOMOYO_CONFIG_ENFORCING)
1301 error = 0; 1254 error = 0;
1302 return error; 1255 return error;
1303} 1256}
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index dedd97d0c163..4120f5a0e1bc 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -173,7 +173,7 @@ static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
173 unsigned long arg) 173 unsigned long arg)
174{ 174{
175 if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)) 175 if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND))
176 return tomoyo_check_rewrite_permission(file); 176 return tomoyo_path_perm(TOMOYO_TYPE_REWRITE, &file->f_path);
177 return 0; 177 return 0;
178} 178}
179 179