diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2010-06-16 03:22:51 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-08-02 01:34:32 -0400 |
commit | 99a852596beb26cc449ca1a79834c107ef4080e1 (patch) | |
tree | 8d593b0af85f6cbbfe73b916f7449148ccf93133 | |
parent | cf6e9a6468ec82a94cbc707b607452ec4454182c (diff) |
TOMOYO: Use callback for permission check.
We can use callback function since parameters are passed via
"const struct tomoyo_request_info".
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r-- | security/tomoyo/common.h | 3 | ||||
-rw-r--r-- | security/tomoyo/domain.c | 18 | ||||
-rw-r--r-- | security/tomoyo/file.c | 394 | ||||
-rw-r--r-- | security/tomoyo/mount.c | 73 |
4 files changed, 230 insertions, 258 deletions
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index f055e273ec02..36b027460ea6 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h | |||
@@ -952,6 +952,9 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size, | |||
952 | *, | 952 | *, |
953 | const struct tomoyo_acl_head | 953 | const struct tomoyo_acl_head |
954 | *)); | 954 | *)); |
955 | void tomoyo_check_acl(struct tomoyo_request_info *r, | ||
956 | bool (*check_entry) (const struct tomoyo_request_info *, | ||
957 | const struct tomoyo_acl_info *)); | ||
955 | 958 | ||
956 | /********** External variable definitions. **********/ | 959 | /********** External variable definitions. **********/ |
957 | 960 | ||
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index 35317e783f34..13f4f39baf8f 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c | |||
@@ -109,6 +109,24 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size, | |||
109 | return error; | 109 | return error; |
110 | } | 110 | } |
111 | 111 | ||
112 | void tomoyo_check_acl(struct tomoyo_request_info *r, | ||
113 | bool (*check_entry) (const struct tomoyo_request_info *, | ||
114 | const struct tomoyo_acl_info *)) | ||
115 | { | ||
116 | const struct tomoyo_domain_info *domain = r->domain; | ||
117 | struct tomoyo_acl_info *ptr; | ||
118 | |||
119 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { | ||
120 | if (ptr->is_deleted || ptr->type != r->param_type) | ||
121 | continue; | ||
122 | if (check_entry(r, ptr)) { | ||
123 | r->granted = true; | ||
124 | return; | ||
125 | } | ||
126 | } | ||
127 | r->granted = false; | ||
128 | } | ||
129 | |||
112 | /* | 130 | /* |
113 | * tomoyo_domain_list is used for holding list of domains. | 131 | * tomoyo_domain_list is used for holding list of domains. |
114 | * The ->acl_info_list of "struct tomoyo_domain_info" is used for holding | 132 | * The ->acl_info_list of "struct tomoyo_domain_info" is used for holding |
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index 32661df10e85..18969e77f5e8 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c | |||
@@ -218,6 +218,108 @@ static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, struct path *path) | |||
218 | return false; | 218 | return false; |
219 | } | 219 | } |
220 | 220 | ||
221 | /** | ||
222 | * tomoyo_audit_path_log - Audit path request log. | ||
223 | * | ||
224 | * @r: Pointer to "struct tomoyo_request_info". | ||
225 | * | ||
226 | * Returns 0 on success, negative value otherwise. | ||
227 | */ | ||
228 | static int tomoyo_audit_path_log(struct tomoyo_request_info *r) | ||
229 | { | ||
230 | const char *operation = tomoyo_path_keyword[r->param.path.operation]; | ||
231 | const struct tomoyo_path_info *filename = r->param.path.filename; | ||
232 | if (r->granted) | ||
233 | return 0; | ||
234 | tomoyo_warn_log(r, "%s %s", operation, filename->name); | ||
235 | return tomoyo_supervisor(r, "allow_%s %s\n", operation, | ||
236 | tomoyo_file_pattern(filename)); | ||
237 | } | ||
238 | |||
239 | /** | ||
240 | * tomoyo_audit_path2_log - Audit path/path request log. | ||
241 | * | ||
242 | * @r: Pointer to "struct tomoyo_request_info". | ||
243 | * | ||
244 | * Returns 0 on success, negative value otherwise. | ||
245 | */ | ||
246 | static int tomoyo_audit_path2_log(struct tomoyo_request_info *r) | ||
247 | { | ||
248 | const char *operation = tomoyo_path2_keyword[r->param.path2.operation]; | ||
249 | const struct tomoyo_path_info *filename1 = r->param.path2.filename1; | ||
250 | const struct tomoyo_path_info *filename2 = r->param.path2.filename2; | ||
251 | if (r->granted) | ||
252 | return 0; | ||
253 | tomoyo_warn_log(r, "%s %s %s", operation, filename1->name, | ||
254 | filename2->name); | ||
255 | return tomoyo_supervisor(r, "allow_%s %s %s\n", operation, | ||
256 | tomoyo_file_pattern(filename1), | ||
257 | tomoyo_file_pattern(filename2)); | ||
258 | } | ||
259 | |||
260 | /** | ||
261 | * tomoyo_audit_mkdev_log - Audit path/number/number/number request log. | ||
262 | * | ||
263 | * @r: Pointer to "struct tomoyo_request_info". | ||
264 | * | ||
265 | * Returns 0 on success, negative value otherwise. | ||
266 | */ | ||
267 | static int tomoyo_audit_mkdev_log(struct tomoyo_request_info *r) | ||
268 | { | ||
269 | const char *operation = tomoyo_path_number32keyword(r->param.mkdev. | ||
270 | operation); | ||
271 | const struct tomoyo_path_info *filename = r->param.mkdev.filename; | ||
272 | const unsigned int major = r->param.mkdev.major; | ||
273 | const unsigned int minor = r->param.mkdev.minor; | ||
274 | const unsigned int mode = r->param.mkdev.mode; | ||
275 | if (r->granted) | ||
276 | return 0; | ||
277 | tomoyo_warn_log(r, "%s %s 0%o %u %u", operation, filename->name, mode, | ||
278 | major, minor); | ||
279 | return tomoyo_supervisor(r, "allow_%s %s 0%o %u %u\n", operation, | ||
280 | tomoyo_file_pattern(filename), mode, major, | ||
281 | minor); | ||
282 | } | ||
283 | |||
284 | /** | ||
285 | * tomoyo_audit_path_number_log - Audit path/number request log. | ||
286 | * | ||
287 | * @r: Pointer to "struct tomoyo_request_info". | ||
288 | * @error: Error code. | ||
289 | * | ||
290 | * Returns 0 on success, negative value otherwise. | ||
291 | */ | ||
292 | static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r) | ||
293 | { | ||
294 | const u8 type = r->param.path_number.operation; | ||
295 | u8 radix; | ||
296 | const struct tomoyo_path_info *filename = r->param.path_number.filename; | ||
297 | const char *operation = tomoyo_path_number_keyword[type]; | ||
298 | char buffer[64]; | ||
299 | if (r->granted) | ||
300 | return 0; | ||
301 | switch (type) { | ||
302 | case TOMOYO_TYPE_CREATE: | ||
303 | case TOMOYO_TYPE_MKDIR: | ||
304 | case TOMOYO_TYPE_MKFIFO: | ||
305 | case TOMOYO_TYPE_MKSOCK: | ||
306 | case TOMOYO_TYPE_CHMOD: | ||
307 | radix = TOMOYO_VALUE_TYPE_OCTAL; | ||
308 | break; | ||
309 | case TOMOYO_TYPE_IOCTL: | ||
310 | radix = TOMOYO_VALUE_TYPE_HEXADECIMAL; | ||
311 | break; | ||
312 | default: | ||
313 | radix = TOMOYO_VALUE_TYPE_DECIMAL; | ||
314 | break; | ||
315 | } | ||
316 | tomoyo_print_ulong(buffer, sizeof(buffer), r->param.path_number.number, | ||
317 | radix); | ||
318 | tomoyo_warn_log(r, "%s %s %s", operation, filename->name, buffer); | ||
319 | return tomoyo_supervisor(r, "allow_%s %s %s\n", operation, | ||
320 | tomoyo_file_pattern(filename), buffer); | ||
321 | } | ||
322 | |||
221 | static int tomoyo_update_path2_acl(const u8 type, const char *filename1, | 323 | static int tomoyo_update_path2_acl(const u8 type, const char *filename1, |
222 | const char *filename2, | 324 | const char *filename2, |
223 | struct tomoyo_domain_info *const domain, | 325 | struct tomoyo_domain_info *const domain, |
@@ -637,37 +739,52 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head) | |||
637 | return done; | 739 | return done; |
638 | } | 740 | } |
639 | 741 | ||
640 | /** | 742 | static bool tomoyo_check_path_acl(const struct tomoyo_request_info *r, |
641 | * tomoyo_path_acl - Check permission for single path operation. | 743 | const struct tomoyo_acl_info *ptr) |
642 | * | ||
643 | * @r: Pointer to "struct tomoyo_request_info". | ||
644 | * @filename: Filename to check. | ||
645 | * @perm: Permission. | ||
646 | * | ||
647 | * Returns 0 on success, -EPERM otherwise. | ||
648 | * | ||
649 | * Caller holds tomoyo_read_lock(). | ||
650 | */ | ||
651 | static int tomoyo_path_acl(const struct tomoyo_request_info *r, | ||
652 | const struct tomoyo_path_info *filename, | ||
653 | const u32 perm) | ||
654 | { | 744 | { |
655 | struct tomoyo_domain_info *domain = r->domain; | 745 | const struct tomoyo_path_acl *acl = container_of(ptr, typeof(*acl), |
656 | struct tomoyo_acl_info *ptr; | 746 | head); |
657 | int error = -EPERM; | 747 | return (acl->perm & (1 << r->param.path.operation)) && |
748 | tomoyo_compare_name_union(r->param.path.filename, &acl->name); | ||
749 | } | ||
658 | 750 | ||
659 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { | 751 | static bool tomoyo_check_path_number_acl(const struct tomoyo_request_info *r, |
660 | struct tomoyo_path_acl *acl; | 752 | const struct tomoyo_acl_info *ptr) |
661 | if (ptr->type != TOMOYO_TYPE_PATH_ACL) | 753 | { |
662 | continue; | 754 | const struct tomoyo_path_number_acl *acl = |
663 | acl = container_of(ptr, struct tomoyo_path_acl, head); | 755 | container_of(ptr, typeof(*acl), head); |
664 | if (!(acl->perm & perm) || | 756 | return (acl->perm & (1 << r->param.path_number.operation)) && |
665 | !tomoyo_compare_name_union(filename, &acl->name)) | 757 | tomoyo_compare_number_union(r->param.path_number.number, |
666 | continue; | 758 | &acl->number) && |
667 | error = 0; | 759 | tomoyo_compare_name_union(r->param.path_number.filename, |
668 | break; | 760 | &acl->name); |
669 | } | 761 | } |
670 | return error; | 762 | |
763 | static bool tomoyo_check_path2_acl(const struct tomoyo_request_info *r, | ||
764 | const struct tomoyo_acl_info *ptr) | ||
765 | { | ||
766 | const struct tomoyo_path2_acl *acl = | ||
767 | container_of(ptr, typeof(*acl), head); | ||
768 | return (acl->perm & (1 << r->param.path2.operation)) && | ||
769 | tomoyo_compare_name_union(r->param.path2.filename1, &acl->name1) | ||
770 | && tomoyo_compare_name_union(r->param.path2.filename2, | ||
771 | &acl->name2); | ||
772 | } | ||
773 | |||
774 | static bool tomoyo_check_mkdev_acl(const struct tomoyo_request_info *r, | ||
775 | const struct tomoyo_acl_info *ptr) | ||
776 | { | ||
777 | const struct tomoyo_path_number3_acl *acl = | ||
778 | container_of(ptr, typeof(*acl), head); | ||
779 | return (acl->perm & (1 << r->param.mkdev.operation)) && | ||
780 | tomoyo_compare_number_union(r->param.mkdev.mode, | ||
781 | &acl->mode) && | ||
782 | tomoyo_compare_number_union(r->param.mkdev.major, | ||
783 | &acl->major) && | ||
784 | tomoyo_compare_number_union(r->param.mkdev.minor, | ||
785 | &acl->minor) && | ||
786 | tomoyo_compare_name_union(r->param.mkdev.filename, | ||
787 | &acl->name); | ||
671 | } | 788 | } |
672 | 789 | ||
673 | static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a, | 790 | static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a, |
@@ -870,88 +987,6 @@ static int tomoyo_update_path2_acl(const u8 type, const char *filename1, | |||
870 | } | 987 | } |
871 | 988 | ||
872 | /** | 989 | /** |
873 | * tomoyo_path_number3_acl - Check permission for path/number/number/number operation. | ||
874 | * | ||
875 | * @r: Pointer to "struct tomoyo_request_info". | ||
876 | * @filename: Filename to check. | ||
877 | * @perm: Permission. | ||
878 | * @mode: Create mode. | ||
879 | * @major: Device major number. | ||
880 | * @minor: Device minor number. | ||
881 | * | ||
882 | * Returns 0 on success, -EPERM otherwise. | ||
883 | * | ||
884 | * Caller holds tomoyo_read_lock(). | ||
885 | */ | ||
886 | static int tomoyo_path_number3_acl(struct tomoyo_request_info *r, | ||
887 | const struct tomoyo_path_info *filename, | ||
888 | const u16 perm, const unsigned int mode, | ||
889 | const unsigned int major, | ||
890 | const unsigned int minor) | ||
891 | { | ||
892 | struct tomoyo_domain_info *domain = r->domain; | ||
893 | struct tomoyo_acl_info *ptr; | ||
894 | int error = -EPERM; | ||
895 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { | ||
896 | struct tomoyo_path_number3_acl *acl; | ||
897 | if (ptr->type != TOMOYO_TYPE_PATH_NUMBER3_ACL) | ||
898 | continue; | ||
899 | acl = container_of(ptr, struct tomoyo_path_number3_acl, head); | ||
900 | if (!tomoyo_compare_number_union(mode, &acl->mode)) | ||
901 | continue; | ||
902 | if (!tomoyo_compare_number_union(major, &acl->major)) | ||
903 | continue; | ||
904 | if (!tomoyo_compare_number_union(minor, &acl->minor)) | ||
905 | continue; | ||
906 | if (!(acl->perm & perm)) | ||
907 | continue; | ||
908 | if (!tomoyo_compare_name_union(filename, &acl->name)) | ||
909 | continue; | ||
910 | error = 0; | ||
911 | break; | ||
912 | } | ||
913 | return error; | ||
914 | } | ||
915 | |||
916 | /** | ||
917 | * tomoyo_path2_acl - Check permission for double path operation. | ||
918 | * | ||
919 | * @r: Pointer to "struct tomoyo_request_info". | ||
920 | * @type: Type of operation. | ||
921 | * @filename1: First filename to check. | ||
922 | * @filename2: Second filename to check. | ||
923 | * | ||
924 | * Returns 0 on success, -EPERM otherwise. | ||
925 | * | ||
926 | * Caller holds tomoyo_read_lock(). | ||
927 | */ | ||
928 | static int tomoyo_path2_acl(const struct tomoyo_request_info *r, const u8 type, | ||
929 | const struct tomoyo_path_info *filename1, | ||
930 | const struct tomoyo_path_info *filename2) | ||
931 | { | ||
932 | const struct tomoyo_domain_info *domain = r->domain; | ||
933 | struct tomoyo_acl_info *ptr; | ||
934 | const u8 perm = 1 << type; | ||
935 | int error = -EPERM; | ||
936 | |||
937 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { | ||
938 | struct tomoyo_path2_acl *acl; | ||
939 | if (ptr->type != TOMOYO_TYPE_PATH2_ACL) | ||
940 | continue; | ||
941 | acl = container_of(ptr, struct tomoyo_path2_acl, head); | ||
942 | if (!(acl->perm & perm)) | ||
943 | continue; | ||
944 | if (!tomoyo_compare_name_union(filename1, &acl->name1)) | ||
945 | continue; | ||
946 | if (!tomoyo_compare_name_union(filename2, &acl->name2)) | ||
947 | continue; | ||
948 | error = 0; | ||
949 | break; | ||
950 | } | ||
951 | return error; | ||
952 | } | ||
953 | |||
954 | /** | ||
955 | * tomoyo_path_permission - Check permission for single path operation. | 990 | * tomoyo_path_permission - Check permission for single path operation. |
956 | * | 991 | * |
957 | * @r: Pointer to "struct tomoyo_request_info". | 992 | * @r: Pointer to "struct tomoyo_request_info". |
@@ -965,7 +1000,6 @@ static int tomoyo_path2_acl(const struct tomoyo_request_info *r, const u8 type, | |||
965 | int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation, | 1000 | int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation, |
966 | const struct tomoyo_path_info *filename) | 1001 | const struct tomoyo_path_info *filename) |
967 | { | 1002 | { |
968 | const char *msg; | ||
969 | int error; | 1003 | int error; |
970 | 1004 | ||
971 | next: | 1005 | next: |
@@ -977,17 +1011,12 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation, | |||
977 | r->param.path.filename = filename; | 1011 | r->param.path.filename = filename; |
978 | r->param.path.operation = operation; | 1012 | r->param.path.operation = operation; |
979 | do { | 1013 | do { |
980 | error = tomoyo_path_acl(r, filename, 1 << operation); | 1014 | tomoyo_check_acl(r, tomoyo_check_path_acl); |
981 | if (error && operation == TOMOYO_TYPE_READ && | 1015 | if (!r->granted && operation == TOMOYO_TYPE_READ && |
982 | !r->domain->ignore_global_allow_read && | 1016 | !r->domain->ignore_global_allow_read && |
983 | tomoyo_is_globally_readable_file(filename)) | 1017 | tomoyo_is_globally_readable_file(filename)) |
984 | error = 0; | 1018 | r->granted = true; |
985 | if (!error) | 1019 | error = tomoyo_audit_path_log(r); |
986 | break; | ||
987 | msg = tomoyo_path2keyword(operation); | ||
988 | tomoyo_warn_log(r, "%s %s", msg, filename->name); | ||
989 | error = tomoyo_supervisor(r, "allow_%s %s\n", msg, | ||
990 | tomoyo_file_pattern(filename)); | ||
991 | /* | 1020 | /* |
992 | * Do not retry for execute request, for alias may have | 1021 | * Do not retry for execute request, for alias may have |
993 | * changed. | 1022 | * changed. |
@@ -1007,42 +1036,6 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation, | |||
1007 | return error; | 1036 | return error; |
1008 | } | 1037 | } |
1009 | 1038 | ||
1010 | /** | ||
1011 | * tomoyo_path_number_acl - Check permission for ioctl/chmod/chown/chgrp operation. | ||
1012 | * | ||
1013 | * @r: Pointer to "struct tomoyo_request_info". | ||
1014 | * @type: Operation. | ||
1015 | * @filename: Filename to check. | ||
1016 | * @number: Number. | ||
1017 | * | ||
1018 | * Returns 0 on success, -EPERM otherwise. | ||
1019 | * | ||
1020 | * Caller holds tomoyo_read_lock(). | ||
1021 | */ | ||
1022 | static int tomoyo_path_number_acl(struct tomoyo_request_info *r, const u8 type, | ||
1023 | const struct tomoyo_path_info *filename, | ||
1024 | const unsigned long number) | ||
1025 | { | ||
1026 | struct tomoyo_domain_info *domain = r->domain; | ||
1027 | struct tomoyo_acl_info *ptr; | ||
1028 | const u8 perm = 1 << type; | ||
1029 | int error = -EPERM; | ||
1030 | list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { | ||
1031 | struct tomoyo_path_number_acl *acl; | ||
1032 | if (ptr->type != TOMOYO_TYPE_PATH_NUMBER_ACL) | ||
1033 | continue; | ||
1034 | acl = container_of(ptr, struct tomoyo_path_number_acl, | ||
1035 | head); | ||
1036 | if (!(acl->perm & perm) || | ||
1037 | !tomoyo_compare_number_union(number, &acl->number) || | ||
1038 | !tomoyo_compare_name_union(filename, &acl->name)) | ||
1039 | continue; | ||
1040 | error = 0; | ||
1041 | break; | ||
1042 | } | ||
1043 | return error; | ||
1044 | } | ||
1045 | |||
1046 | static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a, | 1039 | static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a, |
1047 | const struct tomoyo_acl_info *b) | 1040 | const struct tomoyo_acl_info *b) |
1048 | { | 1041 | { |
@@ -1123,42 +1116,17 @@ static int tomoyo_path_number_perm2(struct tomoyo_request_info *r, | |||
1123 | const struct tomoyo_path_info *filename, | 1116 | const struct tomoyo_path_info *filename, |
1124 | const unsigned long number) | 1117 | const unsigned long number) |
1125 | { | 1118 | { |
1126 | char buffer[64]; | ||
1127 | int error; | 1119 | int error; |
1128 | u8 radix; | ||
1129 | const char *msg; | ||
1130 | 1120 | ||
1131 | if (!filename) | 1121 | if (!filename) |
1132 | return 0; | 1122 | return 0; |
1133 | switch (type) { | ||
1134 | case TOMOYO_TYPE_CREATE: | ||
1135 | case TOMOYO_TYPE_MKDIR: | ||
1136 | case TOMOYO_TYPE_MKFIFO: | ||
1137 | case TOMOYO_TYPE_MKSOCK: | ||
1138 | case TOMOYO_TYPE_CHMOD: | ||
1139 | radix = TOMOYO_VALUE_TYPE_OCTAL; | ||
1140 | break; | ||
1141 | case TOMOYO_TYPE_IOCTL: | ||
1142 | radix = TOMOYO_VALUE_TYPE_HEXADECIMAL; | ||
1143 | break; | ||
1144 | default: | ||
1145 | radix = TOMOYO_VALUE_TYPE_DECIMAL; | ||
1146 | break; | ||
1147 | } | ||
1148 | tomoyo_print_ulong(buffer, sizeof(buffer), number, radix); | ||
1149 | r->param_type = TOMOYO_TYPE_PATH_NUMBER_ACL; | 1123 | r->param_type = TOMOYO_TYPE_PATH_NUMBER_ACL; |
1150 | r->param.path_number.operation = type; | 1124 | r->param.path_number.operation = type; |
1151 | r->param.path_number.filename = filename; | 1125 | r->param.path_number.filename = filename; |
1152 | r->param.path_number.number = number; | 1126 | r->param.path_number.number = number; |
1153 | do { | 1127 | do { |
1154 | error = tomoyo_path_number_acl(r, type, filename, number); | 1128 | tomoyo_check_acl(r, tomoyo_check_path_number_acl); |
1155 | if (!error) | 1129 | error = tomoyo_audit_path_number_log(r); |
1156 | break; | ||
1157 | msg = tomoyo_path_number2keyword(type); | ||
1158 | tomoyo_warn_log(r, "%s %s %s", msg, filename->name, buffer); | ||
1159 | error = tomoyo_supervisor(r, "allow_%s %s %s\n", msg, | ||
1160 | tomoyo_file_pattern(filename), | ||
1161 | buffer); | ||
1162 | } while (error == TOMOYO_RETRY_REQUEST); | 1130 | } while (error == TOMOYO_RETRY_REQUEST); |
1163 | return error; | 1131 | return error; |
1164 | } | 1132 | } |
@@ -1311,47 +1279,6 @@ int tomoyo_path_perm(const u8 operation, struct path *path) | |||
1311 | } | 1279 | } |
1312 | 1280 | ||
1313 | /** | 1281 | /** |
1314 | * tomoyo_path_number3_perm2 - Check permission for path/number/number/number operation. | ||
1315 | * | ||
1316 | * @r: Pointer to "struct tomoyo_request_info". | ||
1317 | * @operation: Type of operation. | ||
1318 | * @filename: Filename to check. | ||
1319 | * @mode: Create mode. | ||
1320 | * @dev: Device number. | ||
1321 | * | ||
1322 | * Returns 0 on success, negative value otherwise. | ||
1323 | * | ||
1324 | * Caller holds tomoyo_read_lock(). | ||
1325 | */ | ||
1326 | static int tomoyo_path_number3_perm2(struct tomoyo_request_info *r, | ||
1327 | const u8 operation, | ||
1328 | const struct tomoyo_path_info *filename, | ||
1329 | const unsigned int mode, | ||
1330 | const unsigned int dev) | ||
1331 | { | ||
1332 | int error; | ||
1333 | const char *msg; | ||
1334 | const unsigned int major = MAJOR(dev); | ||
1335 | const unsigned int minor = MINOR(dev); | ||
1336 | |||
1337 | do { | ||
1338 | error = tomoyo_path_number3_acl(r, filename, 1 << operation, | ||
1339 | mode, major, minor); | ||
1340 | if (!error) | ||
1341 | break; | ||
1342 | msg = tomoyo_path_number32keyword(operation); | ||
1343 | tomoyo_warn_log(r, "%s %s 0%o %u %u", msg, filename->name, | ||
1344 | mode, major, minor); | ||
1345 | error = tomoyo_supervisor(r, "allow_%s %s 0%o %u %u\n", msg, | ||
1346 | tomoyo_file_pattern(filename), mode, | ||
1347 | major, minor); | ||
1348 | } while (error == TOMOYO_RETRY_REQUEST); | ||
1349 | if (r->mode != TOMOYO_CONFIG_ENFORCING) | ||
1350 | error = 0; | ||
1351 | return error; | ||
1352 | } | ||
1353 | |||
1354 | /** | ||
1355 | * tomoyo_path_number3_perm - Check permission for "mkblock" and "mkchar". | 1282 | * tomoyo_path_number3_perm - Check permission for "mkblock" and "mkchar". |
1356 | * | 1283 | * |
1357 | * @operation: Type of operation. (TOMOYO_TYPE_MKCHAR or TOMOYO_TYPE_MKBLOCK) | 1284 | * @operation: Type of operation. (TOMOYO_TYPE_MKCHAR or TOMOYO_TYPE_MKBLOCK) |
@@ -1383,8 +1310,8 @@ int tomoyo_path_number3_perm(const u8 operation, struct path *path, | |||
1383 | r.param.mkdev.mode = mode; | 1310 | r.param.mkdev.mode = mode; |
1384 | r.param.mkdev.major = MAJOR(dev); | 1311 | r.param.mkdev.major = MAJOR(dev); |
1385 | r.param.mkdev.minor = MINOR(dev); | 1312 | r.param.mkdev.minor = MINOR(dev); |
1386 | error = tomoyo_path_number3_perm2(&r, operation, &buf, mode, | 1313 | tomoyo_check_acl(&r, tomoyo_check_mkdev_acl); |
1387 | dev); | 1314 | error = tomoyo_audit_mkdev_log(&r); |
1388 | kfree(buf.name); | 1315 | kfree(buf.name); |
1389 | } | 1316 | } |
1390 | tomoyo_read_unlock(idx); | 1317 | tomoyo_read_unlock(idx); |
@@ -1406,7 +1333,6 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1, | |||
1406 | struct path *path2) | 1333 | struct path *path2) |
1407 | { | 1334 | { |
1408 | int error = -ENOMEM; | 1335 | int error = -ENOMEM; |
1409 | const char *msg; | ||
1410 | struct tomoyo_path_info buf1; | 1336 | struct tomoyo_path_info buf1; |
1411 | struct tomoyo_path_info buf2; | 1337 | struct tomoyo_path_info buf2; |
1412 | struct tomoyo_request_info r; | 1338 | struct tomoyo_request_info r; |
@@ -1440,15 +1366,9 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1, | |||
1440 | r.param.path2.filename1 = &buf1; | 1366 | r.param.path2.filename1 = &buf1; |
1441 | r.param.path2.filename2 = &buf2; | 1367 | r.param.path2.filename2 = &buf2; |
1442 | do { | 1368 | do { |
1443 | error = tomoyo_path2_acl(&r, operation, &buf1, &buf2); | 1369 | tomoyo_check_acl(&r, tomoyo_check_path2_acl); |
1444 | if (!error) | 1370 | error = tomoyo_audit_path2_log(&r); |
1445 | break; | 1371 | } while (error == TOMOYO_RETRY_REQUEST); |
1446 | msg = tomoyo_path22keyword(operation); | ||
1447 | tomoyo_warn_log(&r, "%s %s %s", msg, buf1.name, buf2.name); | ||
1448 | error = tomoyo_supervisor(&r, "allow_%s %s %s\n", msg, | ||
1449 | tomoyo_file_pattern(&buf1), | ||
1450 | tomoyo_file_pattern(&buf2)); | ||
1451 | } while (error == TOMOYO_RETRY_REQUEST); | ||
1452 | out: | 1372 | out: |
1453 | kfree(buf1.name); | 1373 | kfree(buf1.name); |
1454 | kfree(buf2.name); | 1374 | kfree(buf2.name); |
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c index 554de173152c..8f3ac251c571 100644 --- a/security/tomoyo/mount.c +++ b/security/tomoyo/mount.c | |||
@@ -25,6 +25,54 @@ | |||
25 | #define TOMOYO_MOUNT_MAKE_SHARED_KEYWORD "--make-shared" | 25 | #define TOMOYO_MOUNT_MAKE_SHARED_KEYWORD "--make-shared" |
26 | 26 | ||
27 | /** | 27 | /** |
28 | * tomoyo_audit_mount_log - Audit mount log. | ||
29 | * | ||
30 | * @r: Pointer to "struct tomoyo_request_info". | ||
31 | * | ||
32 | * Returns 0 on success, negative value otherwise. | ||
33 | */ | ||
34 | static int tomoyo_audit_mount_log(struct tomoyo_request_info *r) | ||
35 | { | ||
36 | const char *dev = r->param.mount.dev->name; | ||
37 | const char *dir = r->param.mount.dir->name; | ||
38 | const char *type = r->param.mount.type->name; | ||
39 | const unsigned long flags = r->param.mount.flags; | ||
40 | if (r->granted) | ||
41 | return 0; | ||
42 | if (!strcmp(type, TOMOYO_MOUNT_REMOUNT_KEYWORD)) | ||
43 | tomoyo_warn_log(r, "mount -o remount %s 0x%lX", dir, flags); | ||
44 | else if (!strcmp(type, TOMOYO_MOUNT_BIND_KEYWORD) | ||
45 | || !strcmp(type, TOMOYO_MOUNT_MOVE_KEYWORD)) | ||
46 | tomoyo_warn_log(r, "mount %s %s %s 0x%lX", type, dev, dir, | ||
47 | flags); | ||
48 | else if (!strcmp(type, TOMOYO_MOUNT_MAKE_UNBINDABLE_KEYWORD) || | ||
49 | !strcmp(type, TOMOYO_MOUNT_MAKE_PRIVATE_KEYWORD) || | ||
50 | !strcmp(type, TOMOYO_MOUNT_MAKE_SLAVE_KEYWORD) || | ||
51 | !strcmp(type, TOMOYO_MOUNT_MAKE_SHARED_KEYWORD)) | ||
52 | tomoyo_warn_log(r, "mount %s %s 0x%lX", type, dir, flags); | ||
53 | else | ||
54 | tomoyo_warn_log(r, "mount -t %s %s %s 0x%lX", type, dev, dir, | ||
55 | flags); | ||
56 | return tomoyo_supervisor(r, | ||
57 | TOMOYO_KEYWORD_ALLOW_MOUNT "%s %s %s 0x%lX\n", | ||
58 | tomoyo_file_pattern(r->param.mount.dev), | ||
59 | tomoyo_file_pattern(r->param.mount.dir), type, | ||
60 | flags); | ||
61 | } | ||
62 | |||
63 | static bool tomoyo_check_mount_acl(const struct tomoyo_request_info *r, | ||
64 | const struct tomoyo_acl_info *ptr) | ||
65 | { | ||
66 | const struct tomoyo_mount_acl *acl = | ||
67 | container_of(ptr, typeof(*acl), head); | ||
68 | return tomoyo_compare_number_union(r->param.mount.flags, &acl->flags) && | ||
69 | tomoyo_compare_name_union(r->param.mount.type, &acl->fs_type) && | ||
70 | tomoyo_compare_name_union(r->param.mount.dir, &acl->dir_name) && | ||
71 | (!r->param.mount.need_dev || | ||
72 | tomoyo_compare_name_union(r->param.mount.dev, &acl->dev_name)); | ||
73 | } | ||
74 | |||
75 | /** | ||
28 | * tomoyo_mount_acl2 - Check permission for mount() operation. | 76 | * tomoyo_mount_acl2 - Check permission for mount() operation. |
29 | * | 77 | * |
30 | * @r: Pointer to "struct tomoyo_request_info". | 78 | * @r: Pointer to "struct tomoyo_request_info". |
@@ -41,7 +89,6 @@ static int tomoyo_mount_acl2(struct tomoyo_request_info *r, char *dev_name, | |||
41 | struct path *dir, char *type, unsigned long flags) | 89 | struct path *dir, char *type, unsigned long flags) |
42 | { | 90 | { |
43 | struct path path; | 91 | struct path path; |
44 | struct tomoyo_acl_info *ptr; | ||
45 | struct file_system_type *fstype = NULL; | 92 | struct file_system_type *fstype = NULL; |
46 | const char *requested_type = NULL; | 93 | const char *requested_type = NULL; |
47 | const char *requested_dir_name = NULL; | 94 | const char *requested_dir_name = NULL; |
@@ -118,26 +165,10 @@ static int tomoyo_mount_acl2(struct tomoyo_request_info *r, char *dev_name, | |||
118 | r->param.mount.dir = &rdir; | 165 | r->param.mount.dir = &rdir; |
119 | r->param.mount.type = &rtype; | 166 | r->param.mount.type = &rtype; |
120 | r->param.mount.flags = flags; | 167 | r->param.mount.flags = flags; |
121 | list_for_each_entry_rcu(ptr, &r->domain->acl_info_list, list) { | 168 | do { |
122 | struct tomoyo_mount_acl *acl; | 169 | tomoyo_check_acl(r, tomoyo_check_mount_acl); |
123 | if (ptr->is_deleted || ptr->type != TOMOYO_TYPE_MOUNT_ACL) | 170 | error = tomoyo_audit_mount_log(r); |
124 | continue; | 171 | } while (error == TOMOYO_RETRY_REQUEST); |
125 | acl = container_of(ptr, struct tomoyo_mount_acl, head); | ||
126 | if (!tomoyo_compare_number_union(flags, &acl->flags) || | ||
127 | !tomoyo_compare_name_union(&rtype, &acl->fs_type) || | ||
128 | !tomoyo_compare_name_union(&rdir, &acl->dir_name) || | ||
129 | (need_dev && | ||
130 | !tomoyo_compare_name_union(&rdev, &acl->dev_name))) | ||
131 | continue; | ||
132 | error = 0; | ||
133 | break; | ||
134 | } | ||
135 | if (error) | ||
136 | error = tomoyo_supervisor(r, TOMOYO_KEYWORD_ALLOW_MOUNT | ||
137 | "%s %s %s 0x%lX\n", | ||
138 | tomoyo_file_pattern(&rdev), | ||
139 | tomoyo_file_pattern(&rdir), | ||
140 | requested_type, flags); | ||
141 | out: | 172 | out: |
142 | kfree(requested_dev_name); | 173 | kfree(requested_dev_name); |
143 | kfree(requested_dir_name); | 174 | kfree(requested_dir_name); |