diff options
Diffstat (limited to 'security/tomoyo/file.c')
-rw-r--r-- | security/tomoyo/file.c | 315 |
1 files changed, 134 insertions, 181 deletions
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 | */ | ||
101 | static 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 | |||
112 | static 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 | */ | ||
120 | static 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 | */ |
666 | static int tomoyo_path_acl2(const struct tomoyo_domain_info *domain, | 721 | static 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 | */ | ||
705 | static 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 | */ |
739 | static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain, | 761 | static 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 | */ | ||
979 | static 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 | */ |
999 | static int tomoyo_path2_acl(const struct tomoyo_domain_info *domain, | 1003 | static 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 | */ |
1039 | static int tomoyo_path_permission2(struct tomoyo_domain_info *const domain, | 1040 | static 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, | |||
1089 | int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain, | 1081 | int 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 | */ | ||
1209 | int 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 | } |