Commit 475e6fa3 authored by Tetsuo Handa's avatar Tetsuo Handa Committed by James Morris

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: default avatarTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent 5448ec4f
...@@ -507,16 +507,14 @@ static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head) ...@@ -507,16 +507,14 @@ static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head)
*/ */
static void tomoyo_read_manager_policy(struct tomoyo_io_buffer *head) static void tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
{ {
struct list_head *pos;
bool done = true; bool done = true;
if (head->read_eof) if (head->read_eof)
return; return;
list_for_each_cookie(pos, head->read_var2, list_for_each_cookie(head->read_var2,
&tomoyo_policy_list[TOMOYO_ID_MANAGER]) { &tomoyo_policy_list[TOMOYO_ID_MANAGER]) {
struct tomoyo_policy_manager_entry *ptr; struct tomoyo_policy_manager_entry *ptr =
ptr = list_entry(pos, struct tomoyo_policy_manager_entry, list_entry(head->read_var2, typeof(*ptr), head.list);
head.list);
if (ptr->head.is_deleted) if (ptr->head.is_deleted)
continue; continue;
done = tomoyo_io_printf(head, "%s\n", ptr->manager->name); done = tomoyo_io_printf(head, "%s\n", ptr->manager->name);
...@@ -590,8 +588,7 @@ static bool tomoyo_policy_manager(void) ...@@ -590,8 +588,7 @@ static bool tomoyo_policy_manager(void)
* *
* Caller holds tomoyo_read_lock(). * Caller holds tomoyo_read_lock().
*/ */
static bool tomoyo_select_one(struct tomoyo_io_buffer *head, static bool tomoyo_select_one(struct tomoyo_io_buffer *head, const char *data)
const char *data)
{ {
unsigned int pid; unsigned int pid;
struct tomoyo_domain_info *domain = NULL; struct tomoyo_domain_info *domain = NULL;
...@@ -623,20 +620,12 @@ static bool tomoyo_select_one(struct tomoyo_io_buffer *head, ...@@ -623,20 +620,12 @@ static bool tomoyo_select_one(struct tomoyo_io_buffer *head,
tomoyo_io_printf(head, "# select %s\n", data); tomoyo_io_printf(head, "# select %s\n", data);
head->read_single_domain = true; head->read_single_domain = true;
head->read_eof = !domain; head->read_eof = !domain;
if (domain) { head->read_var1 = &domain->list;
struct tomoyo_domain_info *d;
head->read_var1 = NULL;
list_for_each_entry_rcu(d, &tomoyo_domain_list, list) {
if (d == domain)
break;
head->read_var1 = &d->list;
}
head->read_var2 = NULL; head->read_var2 = NULL;
head->read_bit = 0; head->read_bit = 0;
head->read_step = 0; head->read_step = 0;
if (domain->is_deleted) if (domain && domain->is_deleted)
tomoyo_io_printf(head, "# This is a deleted domain.\n"); tomoyo_io_printf(head, "# This is a deleted domain.\n");
}
return true; return true;
} }
...@@ -972,20 +961,18 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head, ...@@ -972,20 +961,18 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
*/ */
static void tomoyo_read_domain_policy(struct tomoyo_io_buffer *head) static void tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
{ {
struct list_head *dpos;
struct list_head *apos;
bool done = true; bool done = true;
if (head->read_eof) if (head->read_eof)
return; return;
if (head->read_step == 0) if (head->read_step == 0)
head->read_step = 1; head->read_step = 1;
list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) { list_for_each_cookie(head->read_var1, &tomoyo_domain_list) {
struct tomoyo_domain_info *domain; struct tomoyo_domain_info *domain =
list_entry(head->read_var1, typeof(*domain), list);
const char *quota_exceeded = ""; const char *quota_exceeded = "";
const char *transition_failed = ""; const char *transition_failed = "";
const char *ignore_global_allow_read = ""; const char *ignore_global_allow_read = "";
domain = list_entry(dpos, struct tomoyo_domain_info, list);
if (head->read_step != 1) if (head->read_step != 1)
goto acl_loop; goto acl_loop;
if (domain->is_deleted && !head->read_single_domain) if (domain->is_deleted && !head->read_single_domain)
...@@ -1011,17 +998,17 @@ static void tomoyo_read_domain_policy(struct tomoyo_io_buffer *head) ...@@ -1011,17 +998,17 @@ static void tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
if (head->read_step == 3) if (head->read_step == 3)
goto tail_mark; goto tail_mark;
/* Print ACL entries in the domain. */ /* Print ACL entries in the domain. */
list_for_each_cookie(apos, head->read_var2, list_for_each_cookie(head->read_var2,
&domain->acl_info_list) { &domain->acl_info_list) {
struct tomoyo_acl_info *ptr struct tomoyo_acl_info *ptr =
= list_entry(apos, struct tomoyo_acl_info, list_entry(head->read_var2, typeof(*ptr), list);
list);
done = tomoyo_print_entry(head, ptr); done = tomoyo_print_entry(head, ptr);
if (!done) if (!done)
break; break;
} }
if (!done) if (!done)
break; break;
head->read_var2 = NULL;
head->read_step = 3; head->read_step = 3;
tail_mark: tail_mark:
done = tomoyo_io_printf(head, "\n"); done = tomoyo_io_printf(head, "\n");
...@@ -1085,14 +1072,13 @@ static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head) ...@@ -1085,14 +1072,13 @@ static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
*/ */
static void tomoyo_read_domain_profile(struct tomoyo_io_buffer *head) static void tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
{ {
struct list_head *pos;
bool done = true; bool done = true;
if (head->read_eof) if (head->read_eof)
return; return;
list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) { list_for_each_cookie(head->read_var1, &tomoyo_domain_list) {
struct tomoyo_domain_info *domain; struct tomoyo_domain_info *domain =
domain = list_entry(pos, struct tomoyo_domain_info, list); list_entry(head->read_var1, typeof(*domain), list);
if (domain->is_deleted) if (domain->is_deleted)
continue; continue;
done = tomoyo_io_printf(head, "%u %s\n", domain->profile, done = tomoyo_io_printf(head, "%u %s\n", domain->profile,
...@@ -1245,19 +1231,16 @@ static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = { ...@@ -1245,19 +1231,16 @@ static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = {
*/ */
static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
{ {
struct list_head *gpos;
struct list_head *mpos;
const char *w[3] = { "", "", "" }; const char *w[3] = { "", "", "" };
w[0] = tomoyo_group_name[idx]; w[0] = tomoyo_group_name[idx];
list_for_each_cookie(gpos, head->read_var1, &tomoyo_group_list[idx]) { list_for_each_cookie(head->read_var1, &tomoyo_group_list[idx]) {
struct tomoyo_group *group = struct tomoyo_group *group =
list_entry(gpos, struct tomoyo_group, list); list_entry(head->read_var1, typeof(*group), list);
w[1] = group->group_name->name; w[1] = group->group_name->name;
list_for_each_cookie(mpos, head->read_var2, list_for_each_cookie(head->read_var2, &group->member_list) {
&group->member_list) {
char buffer[128]; char buffer[128];
struct tomoyo_acl_head *ptr = struct tomoyo_acl_head *ptr =
list_entry(mpos, struct tomoyo_acl_head, list); list_entry(head->read_var2, typeof(*ptr), list);
if (ptr->is_deleted) if (ptr->is_deleted)
continue; continue;
if (idx == TOMOYO_PATH_GROUP) { if (idx == TOMOYO_PATH_GROUP) {
...@@ -1276,7 +1259,9 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) ...@@ -1276,7 +1259,9 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
w[2])) w[2]))
return false; return false;
} }
head->read_var2 = NULL;
} }
head->read_var1 = NULL;
return true; return true;
} }
...@@ -1292,11 +1277,10 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) ...@@ -1292,11 +1277,10 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
*/ */
static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
{ {
struct list_head *pos; list_for_each_cookie(head->read_var2, &tomoyo_policy_list[idx]) {
list_for_each_cookie(pos, head->read_var2, &tomoyo_policy_list[idx]) {
const char *w[4] = { "", "", "", "" }; const char *w[4] = { "", "", "", "" };
struct tomoyo_acl_head *acl = container_of(pos, typeof(*acl), struct tomoyo_acl_head *acl =
list); container_of(head->read_var2, typeof(*acl), list);
if (acl->is_deleted) if (acl->is_deleted)
continue; continue;
switch (idx) { switch (idx) {
...@@ -1354,6 +1338,7 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) ...@@ -1354,6 +1338,7 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
w[3])) w[3]))
return false; return false;
} }
head->read_var2 = NULL;
return true; return true;
} }
......
...@@ -1023,19 +1023,11 @@ static inline bool tomoyo_same_number_union ...@@ -1023,19 +1023,11 @@ static inline bool tomoyo_same_number_union
/** /**
* list_for_each_cookie - iterate over a list with cookie. * list_for_each_cookie - iterate over a list with cookie.
* @pos: the &struct list_head to use as a loop cursor. * @pos: the &struct list_head to use as a loop cursor.
* @cookie: the &struct list_head to use as a cookie.
* @head: the head for your list. * @head: the head for your list.
*
* Same with list_for_each_rcu() except that this primitive uses @cookie
* so that we can continue iteration.
* @cookie must be NULL when iteration starts, and @cookie will become
* NULL when iteration finishes.
*/ */
#define list_for_each_cookie(pos, cookie, head) \ #define list_for_each_cookie(pos, head) \
for (({ if (!cookie) \ if (!pos) \
cookie = head; }), \ pos = srcu_dereference((head)->next, &tomoyo_ss); \
pos = rcu_dereference((cookie)->next); \ for ( ; pos != (head); pos = srcu_dereference(pos->next, &tomoyo_ss))
prefetch(pos->next), pos != (head) || ((cookie) = NULL); \
(cookie) = pos, pos = rcu_dereference(pos->next))
#endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */ #endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment