Skip to content

Commit

Permalink
TOMOYO: Remove memory pool for list elements.
Browse files Browse the repository at this point in the history
Currently, TOMOYO allocates memory for list elements from memory pool allocated
by kmalloc(PAGE_SIZE). But that makes it difficult to kfree() when garbage
collector is added. Thus, remove memory pool and use kmalloc(sizeof()).

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
  • Loading branch information
Tetsuo Handa authored and James Morris committed Jan 10, 2010
1 parent e41035a commit cd7bec6
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 134 deletions.
41 changes: 8 additions & 33 deletions security/tomoyo/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -900,9 +900,11 @@ static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned
ptr = tomoyo_profile_ptr[profile];
if (ptr)
goto ok;
ptr = tomoyo_alloc_element(sizeof(*ptr));
if (!ptr)
ptr = kmalloc(sizeof(*ptr), GFP_KERNEL);
if (!tomoyo_memory_ok(ptr)) {
kfree(ptr);
goto ok;
}
for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++)
ptr->value[i] = tomoyo_control_array[i].current_value;
mb(); /* Avoid out-of-order execution. */
Expand Down Expand Up @@ -1120,6 +1122,7 @@ static int tomoyo_update_manager_entry(const char *manager,
saved_manager = tomoyo_save_name(manager);
if (!saved_manager)
return -ENOMEM;
new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
if (ptr->manager != saved_manager)
Expand All @@ -1132,15 +1135,16 @@ static int tomoyo_update_manager_entry(const char *manager,
error = -ENOENT;
goto out;
}
new_entry = tomoyo_alloc_element(sizeof(*new_entry));
if (!new_entry)
if (!tomoyo_memory_ok(new_entry))
goto out;
new_entry->manager = saved_manager;
new_entry->is_domain = is_domain;
list_add_tail_rcu(&new_entry->list, &tomoyo_policy_manager_list);
new_entry = NULL;
error = 0;
out:
mutex_unlock(&tomoyo_policy_lock);
kfree(new_entry);
return error;
}

Expand Down Expand Up @@ -2147,35 +2151,6 @@ static int tomoyo_close_control(struct file *file)
return 0;
}

/**
* tomoyo_alloc_acl_element - Allocate permanent memory for ACL entry.
*
* @acl_type: Type of ACL entry.
*
* Returns pointer to the ACL entry on success, NULL otherwise.
*/
void *tomoyo_alloc_acl_element(const u8 acl_type)
{
int len;
struct tomoyo_acl_info *ptr;

switch (acl_type) {
case TOMOYO_TYPE_SINGLE_PATH_ACL:
len = sizeof(struct tomoyo_single_path_acl_record);
break;
case TOMOYO_TYPE_DOUBLE_PATH_ACL:
len = sizeof(struct tomoyo_double_path_acl_record);
break;
default:
return NULL;
}
ptr = tomoyo_alloc_element(len);
if (!ptr)
return NULL;
ptr->type = acl_type;
return ptr;
}

/**
* tomoyo_open - open() for /sys/kernel/security/tomoyo/ interface.
*
Expand Down
2 changes: 0 additions & 2 deletions security/tomoyo/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,6 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
/* Check mode for specified functionality. */
unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
const u8 index);
/* Allocate memory for structures. */
void *tomoyo_alloc_acl_element(const u8 acl_type);
/* Fill in "struct tomoyo_path_info" members. */
void tomoyo_fill_path_info(struct tomoyo_path_info *ptr);
/* Run policy loader when /sbin/init starts. */
Expand Down
58 changes: 19 additions & 39 deletions security/tomoyo/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
saved_program = tomoyo_save_name(program);
if (!saved_program)
return -ENOMEM;
new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) {
if (ptr->is_not != is_not ||
Expand All @@ -259,17 +260,18 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
error = -ENOENT;
goto out;
}
new_entry = tomoyo_alloc_element(sizeof(*new_entry));
if (!new_entry)
if (!tomoyo_memory_ok(new_entry))
goto out;
new_entry->domainname = saved_domainname;
new_entry->program = saved_program;
new_entry->is_not = is_not;
new_entry->is_last_name = is_last_name;
list_add_tail_rcu(&new_entry->list, &tomoyo_domain_initializer_list);
new_entry = NULL;
error = 0;
out:
mutex_unlock(&tomoyo_policy_lock);
kfree(new_entry);
return error;
}

Expand Down Expand Up @@ -461,6 +463,7 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
saved_domainname = tomoyo_save_name(domainname);
if (!saved_domainname)
return -ENOMEM;
new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
if (ptr->is_not != is_not ||
Expand All @@ -475,17 +478,18 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
error = -ENOENT;
goto out;
}
new_entry = tomoyo_alloc_element(sizeof(*new_entry));
if (!new_entry)
if (!tomoyo_memory_ok(new_entry))
goto out;
new_entry->domainname = saved_domainname;
new_entry->program = saved_program;
new_entry->is_not = is_not;
new_entry->is_last_name = is_last_name;
list_add_tail_rcu(&new_entry->list, &tomoyo_domain_keeper_list);
new_entry = NULL;
error = 0;
out:
mutex_unlock(&tomoyo_policy_lock);
kfree(new_entry);
return error;
}

Expand Down Expand Up @@ -650,6 +654,7 @@ static int tomoyo_update_alias_entry(const char *original_name,
saved_aliased_name = tomoyo_save_name(aliased_name);
if (!saved_original_name || !saved_aliased_name)
return -ENOMEM;
new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
if (ptr->original_name != saved_original_name ||
Expand All @@ -663,15 +668,16 @@ static int tomoyo_update_alias_entry(const char *original_name,
error = -ENOENT;
goto out;
}
new_entry = tomoyo_alloc_element(sizeof(*new_entry));
if (!new_entry)
if (!tomoyo_memory_ok(new_entry))
goto out;
new_entry->original_name = saved_original_name;
new_entry->aliased_name = saved_aliased_name;
list_add_tail_rcu(&new_entry->list, &tomoyo_alias_list);
new_entry = NULL;
error = 0;
out:
mutex_unlock(&tomoyo_policy_lock);
kfree(new_entry);
return error;
}

Expand Down Expand Up @@ -738,7 +744,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
domainname,
const u8 profile)
{
struct tomoyo_domain_info *domain = NULL;
struct tomoyo_domain_info *domain;
const struct tomoyo_path_info *saved_domainname;

mutex_lock(&tomoyo_policy_lock);
Expand All @@ -750,43 +756,17 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
saved_domainname = tomoyo_save_name(domainname);
if (!saved_domainname)
goto out;
/* Can I reuse memory of deleted domain? */
list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
struct task_struct *p;
struct tomoyo_acl_info *ptr;
bool flag;
if (!domain->is_deleted ||
domain->domainname != saved_domainname)
continue;
flag = false;
read_lock(&tasklist_lock);
for_each_process(p) {
if (tomoyo_real_domain(p) != domain)
continue;
flag = true;
break;
}
read_unlock(&tasklist_lock);
if (flag)
continue;
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
ptr->type |= TOMOYO_ACL_DELETED;
}
tomoyo_set_domain_flag(domain, true, domain->flags);
domain->profile = profile;
domain->quota_warned = false;
mb(); /* Avoid out-of-order execution. */
domain->is_deleted = false;
goto out;
}
/* No memory reusable. Create using new memory. */
domain = tomoyo_alloc_element(sizeof(*domain));
if (domain) {
domain = kmalloc(sizeof(*domain), GFP_KERNEL);
if (tomoyo_memory_ok(domain)) {
INIT_LIST_HEAD(&domain->acl_info_list);
domain->domainname = saved_domainname;
domain->profile = profile;
list_add_tail_rcu(&domain->list, &tomoyo_domain_list);
} else {
kfree(domain);
domain = NULL;
}

out:
mutex_unlock(&tomoyo_policy_lock);
return domain;
Expand Down
34 changes: 24 additions & 10 deletions security/tomoyo/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
saved_filename = tomoyo_save_name(filename);
if (!saved_filename)
return -ENOMEM;
new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
if (ptr->filename != saved_filename)
Expand All @@ -237,14 +238,15 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
error = -ENOENT;
goto out;
}
new_entry = tomoyo_alloc_element(sizeof(*new_entry));
if (!new_entry)
if (!tomoyo_memory_ok(new_entry))
goto out;
new_entry->filename = saved_filename;
list_add_tail_rcu(&new_entry->list, &tomoyo_globally_readable_list);
new_entry = NULL;
error = 0;
out:
mutex_unlock(&tomoyo_policy_lock);
kfree(new_entry);
return error;
}

Expand Down Expand Up @@ -372,6 +374,7 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
saved_pattern = tomoyo_save_name(pattern);
if (!saved_pattern)
return -ENOMEM;
new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
if (saved_pattern != ptr->pattern)
Expand All @@ -384,14 +387,15 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
error = -ENOENT;
goto out;
}
new_entry = tomoyo_alloc_element(sizeof(*new_entry));
if (!new_entry)
if (!tomoyo_memory_ok(new_entry))
goto out;
new_entry->pattern = saved_pattern;
list_add_tail_rcu(&new_entry->list, &tomoyo_pattern_list);
new_entry = NULL;
error = 0;
out:
mutex_unlock(&tomoyo_policy_lock);
kfree(new_entry);
return error;
}

Expand Down Expand Up @@ -523,6 +527,7 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
saved_pattern = tomoyo_save_name(pattern);
if (!saved_pattern)
return -ENOMEM;
new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
if (ptr->pattern != saved_pattern)
Expand All @@ -535,14 +540,15 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
error = -ENOENT;
goto out;
}
new_entry = tomoyo_alloc_element(sizeof(*new_entry));
if (!new_entry)
if (!tomoyo_memory_ok(new_entry))
goto out;
new_entry->pattern = saved_pattern;
list_add_tail_rcu(&new_entry->list, &tomoyo_no_rewrite_list);
new_entry = NULL;
error = 0;
out:
mutex_unlock(&tomoyo_policy_lock);
kfree(new_entry);
return error;
}

Expand Down Expand Up @@ -901,9 +907,13 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
goto out;
}
/* Not found. Append it to the tail. */
acl = tomoyo_alloc_acl_element(TOMOYO_TYPE_SINGLE_PATH_ACL);
if (!acl)
acl = kmalloc(sizeof(*acl), GFP_KERNEL);
if (!tomoyo_memory_ok(acl)) {
kfree(acl);
acl = NULL;
goto out;
}
acl->head.type = TOMOYO_TYPE_SINGLE_PATH_ACL;
if (perm <= 0xFFFF)
acl->perm = perm;
else
Expand Down Expand Up @@ -995,9 +1005,13 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
goto out;
}
/* Not found. Append it to the tail. */
acl = tomoyo_alloc_acl_element(TOMOYO_TYPE_DOUBLE_PATH_ACL);
if (!acl)
acl = kmalloc(sizeof(*acl), GFP_KERNEL);
if (!tomoyo_memory_ok(acl)) {
kfree(acl);
acl = NULL;
goto out;
}
acl->head.type = TOMOYO_TYPE_DOUBLE_PATH_ACL;
acl->perm = perm;
acl->filename1 = saved_filename1;
acl->filename2 = saved_filename2;
Expand Down
Loading

0 comments on commit cd7bec6

Please sign in to comment.