diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2010-06-23 22:28:14 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-08-02 01:34:44 -0400 |
commit | 475e6fa3d340e75a454ea09191a29e52e2ee6e71 (patch) | |
tree | 44e8222ec250f8573199fc3132eaeb2f8922f85e /security | |
parent | 5448ec4f5062ef75ce74f8d7784d4cea9c46ad00 (diff) |
TOMOYO: Change list iterator.
Change list_for_each_cookie to
(1) start from current position rather than next position
(2) remove temporary cursor
(3) check that srcu_read_lock() is held
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security')
-rw-r--r-- | security/tomoyo/common.c | 75 | ||||
-rw-r--r-- | security/tomoyo/common.h | 16 |
2 files changed, 34 insertions, 57 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 6568ef18112b..2a5330ec06c9 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -507,16 +507,14 @@ static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head) | |||
507 | */ | 507 | */ |
508 | static void tomoyo_read_manager_policy(struct tomoyo_io_buffer *head) | 508 | static void tomoyo_read_manager_policy(struct tomoyo_io_buffer *head) |
509 | { | 509 | { |
510 | struct list_head *pos; | ||
511 | bool done = true; | 510 | bool done = true; |
512 | 511 | ||
513 | if (head->read_eof) | 512 | if (head->read_eof) |
514 | return; | 513 | return; |
515 | list_for_each_cookie(pos, head->read_var2, | 514 | list_for_each_cookie(head->read_var2, |
516 | &tomoyo_policy_list[TOMOYO_ID_MANAGER]) { | 515 | &tomoyo_policy_list[TOMOYO_ID_MANAGER]) { |
517 | struct tomoyo_policy_manager_entry *ptr; | 516 | struct tomoyo_policy_manager_entry *ptr = |
518 | ptr = list_entry(pos, struct tomoyo_policy_manager_entry, | 517 | list_entry(head->read_var2, typeof(*ptr), head.list); |
519 | head.list); | ||
520 | if (ptr->head.is_deleted) | 518 | if (ptr->head.is_deleted) |
521 | continue; | 519 | continue; |
522 | done = tomoyo_io_printf(head, "%s\n", ptr->manager->name); | 520 | done = tomoyo_io_printf(head, "%s\n", ptr->manager->name); |
@@ -590,8 +588,7 @@ static bool tomoyo_policy_manager(void) | |||
590 | * | 588 | * |
591 | * Caller holds tomoyo_read_lock(). | 589 | * Caller holds tomoyo_read_lock(). |
592 | */ | 590 | */ |
593 | static bool tomoyo_select_one(struct tomoyo_io_buffer *head, | 591 | static bool tomoyo_select_one(struct tomoyo_io_buffer *head, const char *data) |
594 | const char *data) | ||
595 | { | 592 | { |
596 | unsigned int pid; | 593 | unsigned int pid; |
597 | struct tomoyo_domain_info *domain = NULL; | 594 | struct tomoyo_domain_info *domain = NULL; |
@@ -623,20 +620,12 @@ static bool tomoyo_select_one(struct tomoyo_io_buffer *head, | |||
623 | tomoyo_io_printf(head, "# select %s\n", data); | 620 | tomoyo_io_printf(head, "# select %s\n", data); |
624 | head->read_single_domain = true; | 621 | head->read_single_domain = true; |
625 | head->read_eof = !domain; | 622 | head->read_eof = !domain; |
626 | if (domain) { | 623 | head->read_var1 = &domain->list; |
627 | struct tomoyo_domain_info *d; | 624 | head->read_var2 = NULL; |
628 | head->read_var1 = NULL; | 625 | head->read_bit = 0; |
629 | list_for_each_entry_rcu(d, &tomoyo_domain_list, list) { | 626 | head->read_step = 0; |
630 | if (d == domain) | 627 | if (domain && domain->is_deleted) |
631 | break; | 628 | tomoyo_io_printf(head, "# This is a deleted domain.\n"); |
632 | head->read_var1 = &d->list; | ||
633 | } | ||
634 | head->read_var2 = NULL; | ||
635 | head->read_bit = 0; | ||
636 | head->read_step = 0; | ||
637 | if (domain->is_deleted) | ||
638 | tomoyo_io_printf(head, "# This is a deleted domain.\n"); | ||
639 | } | ||
640 | return true; | 629 | return true; |
641 | } | 630 | } |
642 | 631 | ||
@@ -972,20 +961,18 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, | |||
972 | */ | 961 | */ |
973 | static void tomoyo_read_domain_policy(struct tomoyo_io_buffer *head) | 962 | static void tomoyo_read_domain_policy(struct tomoyo_io_buffer *head) |
974 | { | 963 | { |
975 | struct list_head *dpos; | ||
976 | struct list_head *apos; | ||
977 | bool done = true; | 964 | bool done = true; |
978 | 965 | ||
979 | if (head->read_eof) | 966 | if (head->read_eof) |
980 | return; | 967 | return; |
981 | if (head->read_step == 0) | 968 | if (head->read_step == 0) |
982 | head->read_step = 1; | 969 | head->read_step = 1; |
983 | list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) { | 970 | list_for_each_cookie(head->read_var1, &tomoyo_domain_list) { |
984 | struct tomoyo_domain_info *domain; | 971 | struct tomoyo_domain_info *domain = |
972 | list_entry(head->read_var1, typeof(*domain), list); | ||
985 | const char *quota_exceeded = ""; | 973 | const char *quota_exceeded = ""; |
986 | const char *transition_failed = ""; | 974 | const char *transition_failed = ""; |
987 | const char *ignore_global_allow_read = ""; | 975 | const char *ignore_global_allow_read = ""; |
988 | domain = list_entry(dpos, struct tomoyo_domain_info, list); | ||
989 | if (head->read_step != 1) | 976 | if (head->read_step != 1) |
990 | goto acl_loop; | 977 | goto acl_loop; |
991 | if (domain->is_deleted && !head->read_single_domain) | 978 | if (domain->is_deleted && !head->read_single_domain) |
@@ -1011,17 +998,17 @@ acl_loop: | |||
1011 | if (head->read_step == 3) | 998 | if (head->read_step == 3) |
1012 | goto tail_mark; | 999 | goto tail_mark; |
1013 | /* Print ACL entries in the domain. */ | 1000 | /* Print ACL entries in the domain. */ |
1014 | list_for_each_cookie(apos, head->read_var2, | 1001 | list_for_each_cookie(head->read_var2, |
1015 | &domain->acl_info_list) { | 1002 | &domain->acl_info_list) { |
1016 | struct tomoyo_acl_info *ptr | 1003 | struct tomoyo_acl_info *ptr = |
1017 | = list_entry(apos, struct tomoyo_acl_info, | 1004 | list_entry(head->read_var2, typeof(*ptr), list); |
1018 | list); | ||
1019 | done = tomoyo_print_entry(head, ptr); | 1005 | done = tomoyo_print_entry(head, ptr); |
1020 | if (!done) | 1006 | if (!done) |
1021 | break; | 1007 | break; |
1022 | } | 1008 | } |
1023 | if (!done) | 1009 | if (!done) |
1024 | break; | 1010 | break; |
1011 | head->read_var2 = NULL; | ||
1025 | head->read_step = 3; | 1012 | head->read_step = 3; |
1026 | tail_mark: | 1013 | tail_mark: |
1027 | done = tomoyo_io_printf(head, "\n"); | 1014 | done = tomoyo_io_printf(head, "\n"); |
@@ -1085,14 +1072,13 @@ static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head) | |||
1085 | */ | 1072 | */ |
1086 | static void tomoyo_read_domain_profile(struct tomoyo_io_buffer *head) | 1073 | static void tomoyo_read_domain_profile(struct tomoyo_io_buffer *head) |
1087 | { | 1074 | { |
1088 | struct list_head *pos; | ||
1089 | bool done = true; | 1075 | bool done = true; |
1090 | 1076 | ||
1091 | if (head->read_eof) | 1077 | if (head->read_eof) |
1092 | return; | 1078 | return; |
1093 | list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) { | 1079 | list_for_each_cookie(head->read_var1, &tomoyo_domain_list) { |
1094 | struct tomoyo_domain_info *domain; | 1080 | struct tomoyo_domain_info *domain = |
1095 | domain = list_entry(pos, struct tomoyo_domain_info, list); | 1081 | list_entry(head->read_var1, typeof(*domain), list); |
1096 | if (domain->is_deleted) | 1082 | if (domain->is_deleted) |
1097 | continue; | 1083 | continue; |
1098 | done = tomoyo_io_printf(head, "%u %s\n", domain->profile, | 1084 | done = tomoyo_io_printf(head, "%u %s\n", domain->profile, |
@@ -1245,19 +1231,16 @@ static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = { | |||
1245 | */ | 1231 | */ |
1246 | static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) | 1232 | static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) |
1247 | { | 1233 | { |
1248 | struct list_head *gpos; | ||
1249 | struct list_head *mpos; | ||
1250 | const char *w[3] = { "", "", "" }; | 1234 | const char *w[3] = { "", "", "" }; |
1251 | w[0] = tomoyo_group_name[idx]; | 1235 | w[0] = tomoyo_group_name[idx]; |
1252 | list_for_each_cookie(gpos, head->read_var1, &tomoyo_group_list[idx]) { | 1236 | list_for_each_cookie(head->read_var1, &tomoyo_group_list[idx]) { |
1253 | struct tomoyo_group *group = | 1237 | struct tomoyo_group *group = |
1254 | list_entry(gpos, struct tomoyo_group, list); | 1238 | list_entry(head->read_var1, typeof(*group), list); |
1255 | w[1] = group->group_name->name; | 1239 | w[1] = group->group_name->name; |
1256 | list_for_each_cookie(mpos, head->read_var2, | 1240 | list_for_each_cookie(head->read_var2, &group->member_list) { |
1257 | &group->member_list) { | ||
1258 | char buffer[128]; | 1241 | char buffer[128]; |
1259 | struct tomoyo_acl_head *ptr = | 1242 | struct tomoyo_acl_head *ptr = |
1260 | list_entry(mpos, struct tomoyo_acl_head, list); | 1243 | list_entry(head->read_var2, typeof(*ptr), list); |
1261 | if (ptr->is_deleted) | 1244 | if (ptr->is_deleted) |
1262 | continue; | 1245 | continue; |
1263 | if (idx == TOMOYO_PATH_GROUP) { | 1246 | if (idx == TOMOYO_PATH_GROUP) { |
@@ -1276,7 +1259,9 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) | |||
1276 | w[2])) | 1259 | w[2])) |
1277 | return false; | 1260 | return false; |
1278 | } | 1261 | } |
1262 | head->read_var2 = NULL; | ||
1279 | } | 1263 | } |
1264 | head->read_var1 = NULL; | ||
1280 | return true; | 1265 | return true; |
1281 | } | 1266 | } |
1282 | 1267 | ||
@@ -1292,11 +1277,10 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) | |||
1292 | */ | 1277 | */ |
1293 | static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) | 1278 | static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) |
1294 | { | 1279 | { |
1295 | struct list_head *pos; | 1280 | list_for_each_cookie(head->read_var2, &tomoyo_policy_list[idx]) { |
1296 | list_for_each_cookie(pos, head->read_var2, &tomoyo_policy_list[idx]) { | ||
1297 | const char *w[4] = { "", "", "", "" }; | 1281 | const char *w[4] = { "", "", "", "" }; |
1298 | struct tomoyo_acl_head *acl = container_of(pos, typeof(*acl), | 1282 | struct tomoyo_acl_head *acl = |
1299 | list); | 1283 | container_of(head->read_var2, typeof(*acl), list); |
1300 | if (acl->is_deleted) | 1284 | if (acl->is_deleted) |
1301 | continue; | 1285 | continue; |
1302 | switch (idx) { | 1286 | switch (idx) { |
@@ -1354,6 +1338,7 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) | |||
1354 | w[3])) | 1338 | w[3])) |
1355 | return false; | 1339 | return false; |
1356 | } | 1340 | } |
1341 | head->read_var2 = NULL; | ||
1357 | return true; | 1342 | return true; |
1358 | } | 1343 | } |
1359 | 1344 | ||
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 1277724edae4..cdc9ef56fd86 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h | |||
@@ -1023,19 +1023,11 @@ static inline bool tomoyo_same_number_union | |||
1023 | /** | 1023 | /** |
1024 | * list_for_each_cookie - iterate over a list with cookie. | 1024 | * list_for_each_cookie - iterate over a list with cookie. |
1025 | * @pos: the &struct list_head to use as a loop cursor. | 1025 | * @pos: the &struct list_head to use as a loop cursor. |
1026 | * @cookie: the &struct list_head to use as a cookie. | ||
1027 | * @head: the head for your list. | 1026 | * @head: the head for your list. |
1028 | * | ||
1029 | * Same with list_for_each_rcu() except that this primitive uses @cookie | ||
1030 | * so that we can continue iteration. | ||
1031 | * @cookie must be NULL when iteration starts, and @cookie will become | ||
1032 | * NULL when iteration finishes. | ||
1033 | */ | 1027 | */ |
1034 | #define list_for_each_cookie(pos, cookie, head) \ | 1028 | #define list_for_each_cookie(pos, head) \ |
1035 | for (({ if (!cookie) \ | 1029 | if (!pos) \ |
1036 | cookie = head; }), \ | 1030 | pos = srcu_dereference((head)->next, &tomoyo_ss); \ |
1037 | pos = rcu_dereference((cookie)->next); \ | 1031 | for ( ; pos != (head); pos = srcu_dereference(pos->next, &tomoyo_ss)) |
1038 | prefetch(pos->next), pos != (head) || ((cookie) = NULL); \ | ||
1039 | (cookie) = pos, pos = rcu_dereference(pos->next)) | ||
1040 | 1032 | ||
1041 | #endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */ | 1033 | #endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */ |