TOMOYO: Reduce lines by using common path for addition and deletion.
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Sun, 7 Feb 2010 11:23:59 +0000 (20:23 +0900)
committerJames Morris <jmorris@namei.org>
Thu, 11 Feb 2010 06:09:45 +0000 (17:09 +1100)
Since the codes for adding an entry and removing an entry are similar, we can
save some lines by using "if (is_delete) { ... } else { ... }" branches.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
security/tomoyo/common.c
security/tomoyo/domain.c
security/tomoyo/file.c

index ae3ed73..a53ee05 100644 (file)
@@ -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;
 }
 
index ec612ae..229de1e 100644 (file)
@@ -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;
 }
 
 /**
index 84c821a..f4a2771 100644 (file)
@@ -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;
 }