aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>2010-06-16 03:22:51 -0400
committerJames Morris <jmorris@namei.org>2010-08-02 01:34:32 -0400
commit99a852596beb26cc449ca1a79834c107ef4080e1 (patch)
tree8d593b0af85f6cbbfe73b916f7449148ccf93133
parentcf6e9a6468ec82a94cbc707b607452ec4454182c (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.h3
-rw-r--r--security/tomoyo/domain.c18
-rw-r--r--security/tomoyo/file.c394
-rw-r--r--security/tomoyo/mount.c73
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 *));
955void 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
112void 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 */
228static 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 */
246static 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 */
267static 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 */
292static 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
221static int tomoyo_update_path2_acl(const u8 type, const char *filename1, 323static 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/** 742static 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 */
651static 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) { 751static 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
763static 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
774static 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
673static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a, 790static 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 */
886static 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 */
928static 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,
965int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation, 1000int 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 */
1022static 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
1046static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a, 1039static 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 */
1326static 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 */
34static 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
63static 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);