summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--security/tomoyo/common.c28
-rw-r--r--security/tomoyo/domain.c147
-rw-r--r--security/tomoyo/file.c234
3 files changed, 183 insertions, 226 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index ae3ed7313ee..a53ee059da4 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -1103,10 +1103,10 @@ static LIST_HEAD(tomoyo_policy_manager_list);
static int tomoyo_update_manager_entry(const char *manager,
const bool is_delete)
{
- struct tomoyo_policy_manager_entry *new_entry;
+ struct tomoyo_policy_manager_entry *entry = NULL;
struct tomoyo_policy_manager_entry *ptr;
const struct tomoyo_path_info *saved_manager;
- int error = -ENOMEM;
+ int error = is_delete ? -ENOENT : -ENOMEM;
bool is_domain = false;
if (tomoyo_is_domain_def(manager)) {
@@ -1120,29 +1120,25 @@ 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);
+ if (!is_delete)
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
if (ptr->manager != saved_manager)
continue;
ptr->is_deleted = is_delete;
error = 0;
- goto out;
+ break;
}
- if (is_delete) {
- error = -ENOENT;
- goto out;
+ if (!is_delete && error && tomoyo_memory_ok(entry)) {
+ entry->manager = saved_manager;
+ entry->is_domain = is_domain;
+ list_add_tail_rcu(&entry->list, &tomoyo_policy_manager_list);
+ entry = NULL;
+ error = 0;
}
- 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);
+ kfree(entry);
return error;
}
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
index ec612ae87b5..229de1e71a3 100644
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
@@ -201,11 +201,11 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
const bool is_not,
const bool is_delete)
{
- struct tomoyo_domain_initializer_entry *new_entry;
+ struct tomoyo_domain_initializer_entry *entry = NULL;
struct tomoyo_domain_initializer_entry *ptr;
const struct tomoyo_path_info *saved_program;
const struct tomoyo_path_info *saved_domainname = NULL;
- int error = -ENOMEM;
+ int error = is_delete ? -ENOENT : -ENOMEM;
bool is_last_name = false;
if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__))
@@ -218,12 +218,13 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
return -EINVAL;
saved_domainname = tomoyo_save_name(domainname);
if (!saved_domainname)
- return -ENOMEM;
+ goto out;
}
saved_program = tomoyo_save_name(program);
if (!saved_program)
- return -ENOMEM;
- new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
+ goto out;
+ if (!is_delete)
+ entry = kmalloc(sizeof(*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 ||
@@ -232,24 +233,21 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
continue;
ptr->is_deleted = is_delete;
error = 0;
- goto out;
+ break;
}
- if (is_delete) {
- error = -ENOENT;
- goto out;
+ if (!is_delete && error && tomoyo_memory_ok(entry)) {
+ entry->domainname = saved_domainname;
+ entry->program = saved_program;
+ entry->is_not = is_not;
+ entry->is_last_name = is_last_name;
+ list_add_tail_rcu(&entry->list,
+ &tomoyo_domain_initializer_list);
+ entry = NULL;
+ error = 0;
}
- 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);
+ out:
+ kfree(entry);
return error;
}
@@ -419,11 +417,11 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
const bool is_not,
const bool is_delete)
{
- struct tomoyo_domain_keeper_entry *new_entry;
+ struct tomoyo_domain_keeper_entry *entry = NULL;
struct tomoyo_domain_keeper_entry *ptr;
const struct tomoyo_path_info *saved_domainname;
const struct tomoyo_path_info *saved_program = NULL;
- int error = -ENOMEM;
+ int error = is_delete ? -ENOENT : -ENOMEM;
bool is_last_name = false;
if (!tomoyo_is_domain_def(domainname) &&
@@ -436,12 +434,13 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
return -EINVAL;
saved_program = tomoyo_save_name(program);
if (!saved_program)
- return -ENOMEM;
+ goto out;
}
saved_domainname = tomoyo_save_name(domainname);
if (!saved_domainname)
- return -ENOMEM;
- new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
+ goto out;
+ if (!is_delete)
+ entry = kmalloc(sizeof(*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 ||
@@ -450,24 +449,20 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
continue;
ptr->is_deleted = is_delete;
error = 0;
- goto out;
+ break;
}
- if (is_delete) {
- error = -ENOENT;
- goto out;
+ if (!is_delete && error && tomoyo_memory_ok(entry)) {
+ entry->domainname = saved_domainname;
+ entry->program = saved_program;
+ entry->is_not = is_not;
+ entry->is_last_name = is_last_name;
+ list_add_tail_rcu(&entry->list, &tomoyo_domain_keeper_list);
+ entry = NULL;
+ error = 0;
}
- 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);
+ out:
+ kfree(entry);
return error;
}
@@ -619,11 +614,11 @@ static int tomoyo_update_alias_entry(const char *original_name,
const char *aliased_name,
const bool is_delete)
{
- struct tomoyo_alias_entry *new_entry;
+ struct tomoyo_alias_entry *entry = NULL;
struct tomoyo_alias_entry *ptr;
const struct tomoyo_path_info *saved_original_name;
const struct tomoyo_path_info *saved_aliased_name;
- int error = -ENOMEM;
+ int error = is_delete ? -ENOENT : -ENOMEM;
if (!tomoyo_is_correct_path(original_name, 1, -1, -1, __func__) ||
!tomoyo_is_correct_path(aliased_name, 1, -1, -1, __func__))
@@ -631,8 +626,9 @@ static int tomoyo_update_alias_entry(const char *original_name,
saved_original_name = tomoyo_save_name(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);
+ goto out;
+ if (!is_delete)
+ entry = kmalloc(sizeof(*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 ||
@@ -640,22 +636,18 @@ static int tomoyo_update_alias_entry(const char *original_name,
continue;
ptr->is_deleted = is_delete;
error = 0;
- goto out;
+ break;
}
- if (is_delete) {
- error = -ENOENT;
- goto out;
+ if (!is_delete && error && tomoyo_memory_ok(entry)) {
+ entry->original_name = saved_original_name;
+ entry->aliased_name = saved_aliased_name;
+ list_add_tail_rcu(&entry->list, &tomoyo_alias_list);
+ entry = NULL;
+ error = 0;
}
- 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);
+ out:
+ kfree(entry);
return error;
}
@@ -722,32 +714,37 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
domainname,
const u8 profile)
{
+ struct tomoyo_domain_info *entry;
struct tomoyo_domain_info *domain;
const struct tomoyo_path_info *saved_domainname;
+ bool found = false;
- mutex_lock(&tomoyo_policy_lock);
- domain = tomoyo_find_domain(domainname);
- if (domain)
- goto out;
if (!tomoyo_is_correct_domain(domainname, __func__))
- goto out;
+ return NULL;
saved_domainname = tomoyo_save_name(domainname);
if (!saved_domainname)
- goto out;
- 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;
+ return NULL;
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ mutex_lock(&tomoyo_policy_lock);
+ list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
+ if (domain->is_deleted ||
+ tomoyo_pathcmp(saved_domainname, domain->domainname))
+ continue;
+ found = true;
+ break;
+ }
+ if (!found && tomoyo_memory_ok(entry)) {
+ INIT_LIST_HEAD(&entry->acl_info_list);
+ entry->domainname = saved_domainname;
+ entry->profile = profile;
+ list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
+ domain = entry;
+ entry = NULL;
+ found = true;
}
-
- out:
mutex_unlock(&tomoyo_policy_lock);
- return domain;
+ kfree(entry);
+ return found ? domain : NULL;
}
/**
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index 84c821a245c..f4a27714e07 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -215,38 +215,34 @@ static LIST_HEAD(tomoyo_globally_readable_list);
static int tomoyo_update_globally_readable_entry(const char *filename,
const bool is_delete)
{
- struct tomoyo_globally_readable_file_entry *new_entry;
+ struct tomoyo_globally_readable_file_entry *entry = NULL;
struct tomoyo_globally_readable_file_entry *ptr;
const struct tomoyo_path_info *saved_filename;
- int error = -ENOMEM;
+ int error = is_delete ? -ENOENT : -ENOMEM;
if (!tomoyo_is_correct_path(filename, 1, 0, -1, __func__))
return -EINVAL;
saved_filename = tomoyo_save_name(filename);
if (!saved_filename)
return -ENOMEM;
- new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
+ if (!is_delete)
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) {
if (ptr->filename != saved_filename)
continue;
ptr->is_deleted = is_delete;
error = 0;
- goto out;
+ break;
}
- if (is_delete) {
- error = -ENOENT;
- goto out;
+ if (!is_delete && error && tomoyo_memory_ok(entry)) {
+ entry->filename = saved_filename;
+ list_add_tail_rcu(&entry->list, &tomoyo_globally_readable_list);
+ entry = NULL;
+ error = 0;
}
- 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);
+ kfree(entry);
return error;
}
@@ -364,38 +360,35 @@ static LIST_HEAD(tomoyo_pattern_list);
static int tomoyo_update_file_pattern_entry(const char *pattern,
const bool is_delete)
{
- struct tomoyo_pattern_entry *new_entry;
+ struct tomoyo_pattern_entry *entry = NULL;
struct tomoyo_pattern_entry *ptr;
const struct tomoyo_path_info *saved_pattern;
- int error = -ENOMEM;
+ int error = is_delete ? -ENOENT : -ENOMEM;
- if (!tomoyo_is_correct_path(pattern, 0, 1, 0, __func__))
- return -EINVAL;
saved_pattern = tomoyo_save_name(pattern);
if (!saved_pattern)
- return -ENOMEM;
- new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
+ return error;
+ if (!saved_pattern->is_patterned)
+ goto out;
+ if (!is_delete)
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
if (saved_pattern != ptr->pattern)
continue;
ptr->is_deleted = is_delete;
error = 0;
- goto out;
+ break;
}
- if (is_delete) {
- error = -ENOENT;
- goto out;
+ if (!is_delete && error && tomoyo_memory_ok(entry)) {
+ entry->pattern = saved_pattern;
+ list_add_tail_rcu(&entry->list, &tomoyo_pattern_list);
+ entry = NULL;
+ error = 0;
}
- 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);
+ out:
+ kfree(entry);
return error;
}
@@ -518,37 +511,34 @@ static LIST_HEAD(tomoyo_no_rewrite_list);
static int tomoyo_update_no_rewrite_entry(const char *pattern,
const bool is_delete)
{
- struct tomoyo_no_rewrite_entry *new_entry, *ptr;
+ struct tomoyo_no_rewrite_entry *entry = NULL;
+ struct tomoyo_no_rewrite_entry *ptr;
const struct tomoyo_path_info *saved_pattern;
- int error = -ENOMEM;
+ int error = is_delete ? -ENOENT : -ENOMEM;
if (!tomoyo_is_correct_path(pattern, 0, 0, 0, __func__))
return -EINVAL;
saved_pattern = tomoyo_save_name(pattern);
if (!saved_pattern)
- return -ENOMEM;
- new_entry = kmalloc(sizeof(*new_entry), GFP_KERNEL);
+ return error;
+ if (!is_delete)
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
if (ptr->pattern != saved_pattern)
continue;
ptr->is_deleted = is_delete;
error = 0;
- goto out;
+ break;
}
- if (is_delete) {
- error = -ENOENT;
- goto out;
+ if (!is_delete && error && tomoyo_memory_ok(entry)) {
+ entry->pattern = saved_pattern;
+ list_add_tail_rcu(&entry->list, &tomoyo_no_rewrite_list);
+ entry = NULL;
+ error = 0;
}
- 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);
+ kfree(entry);
return error;
}
@@ -869,8 +859,8 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
(1 << TOMOYO_TYPE_READ_ACL) | (1 << TOMOYO_TYPE_WRITE_ACL);
const struct tomoyo_path_info *saved_filename;
struct tomoyo_acl_info *ptr;
- struct tomoyo_single_path_acl_record *acl;
- int error = -ENOMEM;
+ struct tomoyo_single_path_acl_record *entry = NULL;
+ int error = is_delete ? -ENOENT : -ENOMEM;
const u32 perm = 1 << type;
if (!domain)
@@ -880,67 +870,55 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
saved_filename = tomoyo_save_name(filename);
if (!saved_filename)
return -ENOMEM;
+ if (!is_delete)
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
- if (is_delete)
- goto delete;
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
+ struct tomoyo_single_path_acl_record *acl =
+ container_of(ptr, struct tomoyo_single_path_acl_record,
+ head);
if (ptr->type != TOMOYO_TYPE_SINGLE_PATH_ACL)
continue;
- acl = container_of(ptr, struct tomoyo_single_path_acl_record,
- head);
if (acl->filename != saved_filename)
continue;
- if (perm <= 0xFFFF)
- acl->perm |= perm;
- else
- acl->perm_high |= (perm >> 16);
- if ((acl->perm & rw_mask) == rw_mask)
- acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE_ACL;
- else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL))
- acl->perm |= rw_mask;
+ if (is_delete) {
+ if (perm <= 0xFFFF)
+ acl->perm &= ~perm;
+ else
+ acl->perm_high &= ~(perm >> 16);
+ if ((acl->perm & rw_mask) != rw_mask)
+ acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE_ACL);
+ else if (!(acl->perm &
+ (1 << TOMOYO_TYPE_READ_WRITE_ACL)))
+ acl->perm &= ~rw_mask;
+ } else {
+ if (perm <= 0xFFFF)
+ acl->perm |= perm;
+ else
+ acl->perm_high |= (perm >> 16);
+ if ((acl->perm & rw_mask) == rw_mask)
+ acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE_ACL;
+ else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL))
+ acl->perm |= rw_mask;
+ }
error = 0;
- goto out;
- }
- /* Not found. Append it to the tail. */
- acl = kmalloc(sizeof(*acl), GFP_KERNEL);
- if (!tomoyo_memory_ok(acl)) {
- kfree(acl);
- acl = NULL;
- goto out;
+ break;
}
- acl->head.type = TOMOYO_TYPE_SINGLE_PATH_ACL;
- if (perm <= 0xFFFF)
- acl->perm = perm;
- else
- acl->perm_high = (perm >> 16);
- if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL))
- acl->perm |= rw_mask;
- acl->filename = saved_filename;
- list_add_tail_rcu(&acl->head.list, &domain->acl_info_list);
- error = 0;
- goto out;
- delete:
- error = -ENOENT;
- list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
- if (ptr->type != TOMOYO_TYPE_SINGLE_PATH_ACL)
- continue;
- acl = container_of(ptr, struct tomoyo_single_path_acl_record,
- head);
- if (acl->filename != saved_filename)
- continue;
+ if (!is_delete && error && tomoyo_memory_ok(entry)) {
+ entry->head.type = TOMOYO_TYPE_SINGLE_PATH_ACL;
if (perm <= 0xFFFF)
- acl->perm &= ~perm;
+ entry->perm = perm;
else
- acl->perm_high &= ~(perm >> 16);
- if ((acl->perm & rw_mask) != rw_mask)
- acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE_ACL);
- else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)))
- acl->perm &= ~rw_mask;
+ entry->perm_high = (perm >> 16);
+ if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL))
+ entry->perm |= rw_mask;
+ entry->filename = saved_filename;
+ list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
+ entry = NULL;
error = 0;
- break;
}
- out:
mutex_unlock(&tomoyo_policy_lock);
+ kfree(entry);
return error;
}
@@ -965,8 +943,8 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
const struct tomoyo_path_info *saved_filename1;
const struct tomoyo_path_info *saved_filename2;
struct tomoyo_acl_info *ptr;
- struct tomoyo_double_path_acl_record *acl;
- int error = -ENOMEM;
+ struct tomoyo_double_path_acl_record *entry = NULL;
+ int error = is_delete ? -ENOENT : -ENOMEM;
const u8 perm = 1 << type;
if (!domain)
@@ -977,52 +955,38 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
saved_filename1 = tomoyo_save_name(filename1);
saved_filename2 = tomoyo_save_name(filename2);
if (!saved_filename1 || !saved_filename2)
- return -ENOMEM;
+ goto out;
+ if (!is_delete)
+ entry = kmalloc(sizeof(*entry), GFP_KERNEL);
mutex_lock(&tomoyo_policy_lock);
- if (is_delete)
- goto delete;
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
+ struct tomoyo_double_path_acl_record *acl =
+ container_of(ptr, struct tomoyo_double_path_acl_record,
+ head);
if (ptr->type != TOMOYO_TYPE_DOUBLE_PATH_ACL)
continue;
- acl = container_of(ptr, struct tomoyo_double_path_acl_record,
- head);
if (acl->filename1 != saved_filename1 ||
acl->filename2 != saved_filename2)
continue;
- acl->perm |= perm;
+ if (is_delete)
+ acl->perm &= ~perm;
+ else
+ acl->perm |= perm;
error = 0;
- goto out;
- }
- /* Not found. Append it to the tail. */
- acl = kmalloc(sizeof(*acl), GFP_KERNEL);
- if (!tomoyo_memory_ok(acl)) {
- kfree(acl);
- acl = NULL;
- goto out;
+ break;
}
- acl->head.type = TOMOYO_TYPE_DOUBLE_PATH_ACL;
- acl->perm = perm;
- acl->filename1 = saved_filename1;
- acl->filename2 = saved_filename2;
- list_add_tail_rcu(&acl->head.list, &domain->acl_info_list);
- error = 0;
- goto out;
- delete:
- error = -ENOENT;
- list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
- if (ptr->type != TOMOYO_TYPE_DOUBLE_PATH_ACL)
- continue;
- acl = container_of(ptr, struct tomoyo_double_path_acl_record,
- head);
- if (acl->filename1 != saved_filename1 ||
- acl->filename2 != saved_filename2)
- continue;
- acl->perm &= ~perm;
+ if (!is_delete && error && tomoyo_memory_ok(entry)) {
+ entry->head.type = TOMOYO_TYPE_DOUBLE_PATH_ACL;
+ entry->perm = perm;
+ entry->filename1 = saved_filename1;
+ entry->filename2 = saved_filename2;
+ list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
+ entry = NULL;
error = 0;
- break;
}
- out:
mutex_unlock(&tomoyo_policy_lock);
+ out:
+ kfree(entry);
return error;
}