diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c index d129317ca481..a54bd823fcd5 100644 --- a/security/tomoyo/gc.c +++ b/security/tomoyo/gc.c @@ -33,13 +33,13 @@ enum tomoyo_policy_id { struct tomoyo_gc_entry { struct list_head list; int type; - void *element; + struct list_head *element; }; static LIST_HEAD(tomoyo_gc_queue); static DEFINE_MUTEX(tomoyo_gc_mutex); /* Caller holds tomoyo_policy_lock mutex. */ -static bool tomoyo_add_to_gc(const int type, void *element) +static bool tomoyo_add_to_gc(const int type, struct list_head *element) { struct tomoyo_gc_entry *entry = kzalloc(sizeof(*entry), GFP_ATOMIC); if (!entry) @@ -47,57 +47,74 @@ static bool tomoyo_add_to_gc(const int type, void *element) entry->type = type; entry->element = element; list_add(&entry->list, &tomoyo_gc_queue); + list_del_rcu(element); return true; } -static void tomoyo_del_allow_read -(struct tomoyo_globally_readable_file_entry *ptr) +static void tomoyo_del_allow_read(struct list_head *element) { + struct tomoyo_globally_readable_file_entry *ptr = + container_of(element, typeof(*ptr), head.list); tomoyo_put_name(ptr->filename); } -static void tomoyo_del_file_pattern(struct tomoyo_pattern_entry *ptr) +static void tomoyo_del_file_pattern(struct list_head *element) { + struct tomoyo_pattern_entry *ptr = + container_of(element, typeof(*ptr), head.list); tomoyo_put_name(ptr->pattern); } -static void tomoyo_del_no_rewrite(struct tomoyo_no_rewrite_entry *ptr) +static void tomoyo_del_no_rewrite(struct list_head *element) { + struct tomoyo_no_rewrite_entry *ptr = + container_of(element, typeof(*ptr), head.list); tomoyo_put_name(ptr->pattern); } -static void tomoyo_del_domain_initializer -(struct tomoyo_domain_initializer_entry *ptr) +static void tomoyo_del_domain_initializer(struct list_head *element) { + struct tomoyo_domain_initializer_entry *ptr = + container_of(element, typeof(*ptr), head.list); tomoyo_put_name(ptr->domainname); tomoyo_put_name(ptr->program); } -static void tomoyo_del_domain_keeper(struct tomoyo_domain_keeper_entry *ptr) +static void tomoyo_del_domain_keeper(struct list_head *element) { + struct tomoyo_domain_keeper_entry *ptr = + container_of(element, typeof(*ptr), head.list); tomoyo_put_name(ptr->domainname); tomoyo_put_name(ptr->program); } -static void tomoyo_del_aggregator(struct tomoyo_aggregator_entry *ptr) +static void tomoyo_del_aggregator(struct list_head *element) { + struct tomoyo_aggregator_entry *ptr = + container_of(element, typeof(*ptr), head.list); tomoyo_put_name(ptr->original_name); tomoyo_put_name(ptr->aggregated_name); } -static void tomoyo_del_alias(struct tomoyo_alias_entry *ptr) +static void tomoyo_del_alias(struct list_head *element) { + struct tomoyo_alias_entry *ptr = + container_of(element, typeof(*ptr), head.list); tomoyo_put_name(ptr->original_name); tomoyo_put_name(ptr->aliased_name); } -static void tomoyo_del_manager(struct tomoyo_policy_manager_entry *ptr) +static void tomoyo_del_manager(struct list_head *element) { + struct tomoyo_policy_manager_entry *ptr = + container_of(element, typeof(*ptr), head.list); tomoyo_put_name(ptr->manager); } -static void tomoyo_del_acl(struct tomoyo_acl_info *acl) +static void tomoyo_del_acl(struct list_head *element) { + struct tomoyo_acl_info *acl = + container_of(element, typeof(*acl), list); switch (acl->type) { case TOMOYO_TYPE_PATH_ACL: { @@ -142,14 +159,13 @@ static void tomoyo_del_acl(struct tomoyo_acl_info *acl) tomoyo_put_number_union(&entry->flags); } break; - default: - printk(KERN_WARNING "Unknown type\n"); - break; } } -static bool tomoyo_del_domain(struct tomoyo_domain_info *domain) +static bool tomoyo_del_domain(struct list_head *element) { + struct tomoyo_domain_info *domain = + container_of(element, typeof(*domain), list); struct tomoyo_acl_info *acl; struct tomoyo_acl_info *tmp; /* @@ -177,7 +193,7 @@ static bool tomoyo_del_domain(struct tomoyo_domain_info *domain) if (atomic_read(&domain->users)) return false; list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) { - tomoyo_del_acl(acl); + tomoyo_del_acl(&acl->list); tomoyo_memory_free(acl); } tomoyo_put_name(domain->domainname); @@ -185,28 +201,36 @@ static bool tomoyo_del_domain(struct tomoyo_domain_info *domain) } -static void tomoyo_del_name(const struct tomoyo_name_entry *ptr) +static void tomoyo_del_name(struct list_head *element) { + const struct tomoyo_name_entry *ptr = + container_of(element, typeof(*ptr), list); } -static void tomoyo_del_path_group_member(struct tomoyo_path_group_member - *member) +static void tomoyo_del_path_group_member(struct list_head *element) { + struct tomoyo_path_group_member *member = + container_of(element, typeof(*member), head.list); tomoyo_put_name(member->member_name); } -static void tomoyo_del_path_group(struct tomoyo_path_group *group) +static void tomoyo_del_path_group(struct list_head *element) { + struct tomoyo_path_group *group = + container_of(element, typeof(*group), list); tomoyo_put_name(group->group_name); } -static void tomoyo_del_number_group_member(struct tomoyo_number_group_member - *member) +static void tomoyo_del_number_group_member(struct list_head *element) { + struct tomoyo_number_group_member *member = + container_of(element, typeof(*member), head.list); } -static void tomoyo_del_number_group(struct tomoyo_number_group *group) +static void tomoyo_del_number_group(struct list_head *element) { + struct tomoyo_number_group *group = + container_of(element, typeof(*group), list); tomoyo_put_name(group->group_name); } @@ -229,7 +253,6 @@ static bool tomoyo_collect_member(struct list_head *member_list, int id) continue; if (!tomoyo_add_to_gc(id, &member->list)) return false; - list_del_rcu(&member->list); } return true; } @@ -242,7 +265,6 @@ static bool tomoyo_collect_acl(struct tomoyo_domain_info *domain) continue; if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list)) return false; - list_del_rcu(&acl->list); } return true; } @@ -269,9 +291,7 @@ static void tomoyo_collect_entry(void) * refer this domain after successful execve(). * We recheck domain->users after SRCU synchronization. */ - if (tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, domain)) - list_del_rcu(&domain->list); - else + if (!tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, &domain->list)) goto unlock; } } @@ -280,9 +300,7 @@ static void tomoyo_collect_entry(void) list_for_each_entry_rcu(ptr, &tomoyo_name_list[i], list) { if (atomic_read(&ptr->users)) continue; - if (tomoyo_add_to_gc(TOMOYO_ID_NAME, ptr)) - list_del_rcu(&ptr->list); - else + if (!tomoyo_add_to_gc(TOMOYO_ID_NAME, &ptr->list)) goto unlock; } } @@ -294,9 +312,8 @@ static void tomoyo_collect_entry(void) if (!list_empty(&group->member_list) || atomic_read(&group->users)) continue; - if (tomoyo_add_to_gc(TOMOYO_ID_PATH_GROUP, group)) - list_del_rcu(&group->list); - else + if (!tomoyo_add_to_gc(TOMOYO_ID_PATH_GROUP, + &group->list)) goto unlock; } } @@ -309,9 +326,8 @@ static void tomoyo_collect_entry(void) if (!list_empty(&group->member_list) || atomic_read(&group->users)) continue; - if (tomoyo_add_to_gc(TOMOYO_ID_NUMBER_GROUP, group)) - list_del_rcu(&group->list); - else + if (!tomoyo_add_to_gc(TOMOYO_ID_NUMBER_GROUP, + &group->list)) goto unlock; } } @@ -325,58 +341,56 @@ static void tomoyo_kfree_entry(void) struct tomoyo_gc_entry *tmp; list_for_each_entry_safe(p, tmp, &tomoyo_gc_queue, list) { + struct list_head *element = p->element; switch (p->type) { case TOMOYO_ID_DOMAIN_INITIALIZER: - tomoyo_del_domain_initializer(p->element); + tomoyo_del_domain_initializer(element); break; case TOMOYO_ID_DOMAIN_KEEPER: - tomoyo_del_domain_keeper(p->element); + tomoyo_del_domain_keeper(element); break; case TOMOYO_ID_AGGREGATOR: - tomoyo_del_aggregator(p->element); + tomoyo_del_aggregator(element); break; case TOMOYO_ID_ALIAS: - tomoyo_del_alias(p->element); + tomoyo_del_alias(element); break; case TOMOYO_ID_GLOBALLY_READABLE: - tomoyo_del_allow_read(p->element); + tomoyo_del_allow_read(element); break; case TOMOYO_ID_PATTERN: - tomoyo_del_file_pattern(p->element); + tomoyo_del_file_pattern(element); break; case TOMOYO_ID_NO_REWRITE: - tomoyo_del_no_rewrite(p->element); + tomoyo_del_no_rewrite(element); break; case TOMOYO_ID_MANAGER: - tomoyo_del_manager(p->element); + tomoyo_del_manager(element); break; case TOMOYO_ID_NAME: - tomoyo_del_name(p->element); + tomoyo_del_name(element); break; case TOMOYO_ID_ACL: - tomoyo_del_acl(p->element); + tomoyo_del_acl(element); break; case TOMOYO_ID_DOMAIN: - if (!tomoyo_del_domain(p->element)) + if (!tomoyo_del_domain(element)) continue; break; case TOMOYO_ID_PATH_GROUP_MEMBER: - tomoyo_del_path_group_member(p->element); + tomoyo_del_path_group_member(element); break; case TOMOYO_ID_PATH_GROUP: - tomoyo_del_path_group(p->element); + tomoyo_del_path_group(element); break; case TOMOYO_ID_NUMBER_GROUP_MEMBER: - tomoyo_del_number_group_member(p->element); + tomoyo_del_number_group_member(element); break; case TOMOYO_ID_NUMBER_GROUP: - tomoyo_del_number_group(p->element); - break; - default: - printk(KERN_WARNING "Unknown type\n"); + tomoyo_del_number_group(element); break; } - tomoyo_memory_free(p->element); + tomoyo_memory_free(element); list_del(&p->list); kfree(p); }