Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+30 −45
Original line number Diff line number Diff line
@@ -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)
{
	struct list_head *pos;
	bool done = true;

	if (head->read_eof)
		return;
	list_for_each_cookie(pos, head->read_var2,
	list_for_each_cookie(head->read_var2,
			     &tomoyo_policy_list[TOMOYO_ID_MANAGER]) {
		struct tomoyo_policy_manager_entry *ptr;
		ptr = list_entry(pos, struct tomoyo_policy_manager_entry,
				 head.list);
		struct tomoyo_policy_manager_entry *ptr =
			list_entry(head->read_var2, typeof(*ptr), head.list);
		if (ptr->head.is_deleted)
			continue;
		done = tomoyo_io_printf(head, "%s\n", ptr->manager->name);
@@ -590,8 +588,7 @@ static bool tomoyo_policy_manager(void)
 *
 * Caller holds tomoyo_read_lock().
 */
static bool tomoyo_select_one(struct tomoyo_io_buffer *head,
				 const char *data)
static bool tomoyo_select_one(struct tomoyo_io_buffer *head, const char *data)
{
	unsigned int pid;
	struct tomoyo_domain_info *domain = NULL;
@@ -623,20 +620,12 @@ static bool tomoyo_select_one(struct tomoyo_io_buffer *head,
	tomoyo_io_printf(head, "# select %s\n", data);
	head->read_single_domain = true;
	head->read_eof = !domain;
	if (domain) {
		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_var1 = &domain->list;
	head->read_var2 = NULL;
	head->read_bit = 0;
	head->read_step = 0;
		if (domain->is_deleted)
	if (domain && domain->is_deleted)
		tomoyo_io_printf(head, "# This is a deleted domain.\n");
	}
	return true;
}

@@ -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)
{
	struct list_head *dpos;
	struct list_head *apos;
	bool done = true;

	if (head->read_eof)
		return;
	if (head->read_step == 0)
		head->read_step = 1;
	list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) {
		struct tomoyo_domain_info *domain;
	list_for_each_cookie(head->read_var1, &tomoyo_domain_list) {
		struct tomoyo_domain_info *domain =
			list_entry(head->read_var1, typeof(*domain), list);
		const char *quota_exceeded = "";
		const char *transition_failed = "";
		const char *ignore_global_allow_read = "";
		domain = list_entry(dpos, struct tomoyo_domain_info, list);
		if (head->read_step != 1)
			goto acl_loop;
		if (domain->is_deleted && !head->read_single_domain)
@@ -1011,17 +998,17 @@ static void tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
		if (head->read_step == 3)
			goto tail_mark;
		/* 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) {
			struct tomoyo_acl_info *ptr
				= list_entry(apos, struct tomoyo_acl_info,
					     list);
			struct tomoyo_acl_info *ptr =
				list_entry(head->read_var2, typeof(*ptr), list);
			done = tomoyo_print_entry(head, ptr);
			if (!done)
				break;
		}
		if (!done)
			break;
		head->read_var2 = NULL;
		head->read_step = 3;
tail_mark:
		done = tomoyo_io_printf(head, "\n");
@@ -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)
{
	struct list_head *pos;
	bool done = true;

	if (head->read_eof)
		return;
	list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) {
		struct tomoyo_domain_info *domain;
		domain = list_entry(pos, struct tomoyo_domain_info, list);
	list_for_each_cookie(head->read_var1, &tomoyo_domain_list) {
		struct tomoyo_domain_info *domain =
			list_entry(head->read_var1, typeof(*domain), list);
		if (domain->is_deleted)
			continue;
		done = tomoyo_io_printf(head, "%u %s\n", domain->profile,
@@ -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)
{
	struct list_head *gpos;
	struct list_head *mpos;
	const char *w[3] = { "", "", "" };
	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 =
			list_entry(gpos, struct tomoyo_group, list);
			list_entry(head->read_var1, typeof(*group), list);
		w[1] = group->group_name->name;
		list_for_each_cookie(mpos, head->read_var2,
				     &group->member_list) {
		list_for_each_cookie(head->read_var2, &group->member_list) {
			char buffer[128];
			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)
				continue;
			if (idx == TOMOYO_PATH_GROUP) {
@@ -1276,7 +1259,9 @@ static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx)
					      w[2]))
				return false;
		}
		head->read_var2 = NULL;
	}
	head->read_var1 = NULL;
	return true;
}

@@ -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)
{
	struct list_head *pos;
	list_for_each_cookie(pos, head->read_var2, &tomoyo_policy_list[idx]) {
	list_for_each_cookie(head->read_var2, &tomoyo_policy_list[idx]) {
		const char *w[4] = { "", "", "", "" };
		struct tomoyo_acl_head *acl = container_of(pos, typeof(*acl),
							   list);
		struct tomoyo_acl_head *acl =
			container_of(head->read_var2, typeof(*acl), list);
		if (acl->is_deleted)
			continue;
		switch (idx) {
@@ -1354,6 +1338,7 @@ static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx)
				      w[3]))
			return false;
	}
	head->read_var2 = NULL;
	return true;
}

+4 −12
Original line number Diff line number Diff line
@@ -1023,19 +1023,11 @@ static inline bool tomoyo_same_number_union
/**
 * list_for_each_cookie - iterate over a list with cookie.
 * @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.
 *
 * 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)				\
	for (({ if (!cookie)						\
				     cookie = head; }),			\
		     pos = rcu_dereference((cookie)->next);		\
	     prefetch(pos->next), pos != (head) || ((cookie) = NULL);	\
	     (cookie) = pos, pos = rcu_dereference(pos->next))
#define list_for_each_cookie(pos, head)					\
	if (!pos)							\
		pos =  srcu_dereference((head)->next, &tomoyo_ss);	\
	for ( ; pos != (head); pos = srcu_dereference(pos->next, &tomoyo_ss))

#endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */