summaryrefslogtreecommitdiffstats
path: root/security/tomoyo/gc.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/gc.c')
-rw-r--r--security/tomoyo/gc.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c
index e22bea811c57..9537832fca18 100644
--- a/security/tomoyo/gc.c
+++ b/security/tomoyo/gc.c
@@ -77,11 +77,13 @@ static bool tomoyo_name_used_by_io_buffer(const char *string)
spin_lock(&tomoyo_io_buffer_list_lock);
list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
int i;
+
head->users++;
spin_unlock(&tomoyo_io_buffer_list_lock);
mutex_lock(&head->io_sem);
for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) {
const char *w = head->r.w[i];
+
if (w < string || w > string + size)
continue;
in_use = true;
@@ -108,6 +110,7 @@ static inline void tomoyo_del_transition_control(struct list_head *element)
{
struct tomoyo_transition_control *ptr =
container_of(element, typeof(*ptr), head.list);
+
tomoyo_put_name(ptr->domainname);
tomoyo_put_name(ptr->program);
}
@@ -123,6 +126,7 @@ static inline void tomoyo_del_aggregator(struct list_head *element)
{
struct tomoyo_aggregator *ptr =
container_of(element, typeof(*ptr), head.list);
+
tomoyo_put_name(ptr->original_name);
tomoyo_put_name(ptr->aggregated_name);
}
@@ -138,6 +142,7 @@ static inline void tomoyo_del_manager(struct list_head *element)
{
struct tomoyo_manager *ptr =
container_of(element, typeof(*ptr), head.list);
+
tomoyo_put_name(ptr->manager);
}
@@ -152,6 +157,7 @@ static void tomoyo_del_acl(struct list_head *element)
{
struct tomoyo_acl_info *acl =
container_of(element, typeof(*acl), list);
+
tomoyo_put_condition(acl->cond);
switch (acl->type) {
case TOMOYO_TYPE_PATH_ACL:
@@ -226,6 +232,7 @@ static void tomoyo_del_acl(struct list_head *element)
{
struct tomoyo_task_acl *entry =
container_of(acl, typeof(*entry), head);
+
tomoyo_put_name(entry->domainname);
}
break;
@@ -247,6 +254,7 @@ static inline void tomoyo_del_domain(struct list_head *element)
container_of(element, typeof(*domain), list);
struct tomoyo_acl_info *acl;
struct tomoyo_acl_info *tmp;
+
/*
* Since this domain is referenced from neither
* "struct tomoyo_io_buffer" nor "struct cred"->security, we can delete
@@ -286,6 +294,7 @@ void tomoyo_del_condition(struct list_head *element)
= (const struct tomoyo_argv *) (names_p + names_count);
const struct tomoyo_envp *envp
= (const struct tomoyo_envp *) (argv + argc);
+
for (i = 0; i < numbers_count; i++)
tomoyo_put_number_union(numbers_p++);
for (i = 0; i < names_count; i++)
@@ -321,6 +330,7 @@ static inline void tomoyo_del_path_group(struct list_head *element)
{
struct tomoyo_path_group *member =
container_of(element, typeof(*member), head.list);
+
tomoyo_put_name(member->member_name);
}
@@ -335,6 +345,7 @@ static inline void tomoyo_del_group(struct list_head *element)
{
struct tomoyo_group *group =
container_of(element, typeof(*group), head.list);
+
tomoyo_put_name(group->group_name);
}
@@ -476,6 +487,7 @@ static void tomoyo_collect_member(const enum tomoyo_policy_id id,
{
struct tomoyo_acl_head *member;
struct tomoyo_acl_head *tmp;
+
list_for_each_entry_safe(member, tmp, member_list, list) {
if (!member->is_deleted)
continue;
@@ -495,6 +507,7 @@ static void tomoyo_collect_acl(struct list_head *list)
{
struct tomoyo_acl_info *acl;
struct tomoyo_acl_info *tmp;
+
list_for_each_entry_safe(acl, tmp, list, list) {
if (!acl->is_deleted)
continue;
@@ -513,10 +526,12 @@ static void tomoyo_collect_entry(void)
int i;
enum tomoyo_policy_id id;
struct tomoyo_policy_namespace *ns;
+
mutex_lock(&tomoyo_policy_lock);
{
struct tomoyo_domain_info *domain;
struct tomoyo_domain_info *tmp;
+
list_for_each_entry_safe(domain, tmp, &tomoyo_domain_list,
list) {
tomoyo_collect_acl(&domain->acl_info_list);
@@ -534,6 +549,7 @@ static void tomoyo_collect_entry(void)
{
struct tomoyo_shared_acl_head *ptr;
struct tomoyo_shared_acl_head *tmp;
+
list_for_each_entry_safe(ptr, tmp, &tomoyo_condition_list,
list) {
if (atomic_read(&ptr->users) > 0)
@@ -547,6 +563,7 @@ static void tomoyo_collect_entry(void)
struct list_head *list = &ns->group_list[i];
struct tomoyo_group *group;
struct tomoyo_group *tmp;
+
switch (i) {
case 0:
id = TOMOYO_ID_PATH_GROUP;
@@ -574,6 +591,7 @@ static void tomoyo_collect_entry(void)
struct list_head *list = &tomoyo_name_list[i];
struct tomoyo_shared_acl_head *ptr;
struct tomoyo_shared_acl_head *tmp;
+
list_for_each_entry_safe(ptr, tmp, list, list) {
if (atomic_read(&ptr->users) > 0)
continue;
@@ -595,6 +613,7 @@ static int tomoyo_gc_thread(void *unused)
{
/* Garbage collector thread is exclusive. */
static DEFINE_MUTEX(tomoyo_gc_mutex);
+
if (!mutex_trylock(&tomoyo_gc_mutex))
goto out;
tomoyo_collect_entry();