TOMOYO: Reduce lines by using common path for addition and deletion.
[safe/jmp/linux-2.6] / security / tomoyo / file.c
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;
 }