]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - security/tomoyo/common.c
TOMOYO: Reduce lines by using common path for addition and deletion.
[net-next-2.6.git] / security / tomoyo / common.c
index f01b9364db2dd14914eb61bc568c36f054de1f48..a53ee059da4818f5841bf35e62ceb18d2b6f5de1 100644 (file)
@@ -16,6 +16,9 @@
 #include "common.h"
 #include "tomoyo.h"
 
+/* Lock for protecting policy. */
+DEFINE_MUTEX(tomoyo_policy_lock);
+
 /* Has loading policy done? */
 bool tomoyo_policy_loaded;
 
@@ -747,7 +750,7 @@ bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
  *
  * Returns the tomoyo_realpath() of current process on success, NULL otherwise.
  *
- * This function uses tomoyo_alloc(), so the caller must call tomoyo_free()
+ * This function uses kzalloc(), so the caller must call kfree()
  * if this function didn't return NULL.
  */
 static const char *tomoyo_get_exe(void)
@@ -839,9 +842,7 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain)
        if (!domain)
                return true;
        list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
-               if (ptr->type & TOMOYO_ACL_DELETED)
-                       continue;
-               switch (tomoyo_acl_type2(ptr)) {
+               switch (ptr->type) {
                        struct tomoyo_single_path_acl_record *acl;
                        u32 perm;
                        u8 i;
@@ -897,9 +898,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. */
@@ -1086,7 +1089,6 @@ struct tomoyo_policy_manager_entry {
  * # cat /sys/kernel/security/tomoyo/manager
  */
 static LIST_HEAD(tomoyo_policy_manager_list);
-static DECLARE_RWSEM(tomoyo_policy_manager_list_lock);
 
 /**
  * tomoyo_update_manager_entry - Add a manager entry.
@@ -1101,10 +1103,10 @@ static DECLARE_RWSEM(tomoyo_policy_manager_list_lock);
 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)) {
@@ -1118,27 +1120,25 @@ static int tomoyo_update_manager_entry(const char *manager,
        saved_manager = tomoyo_save_name(manager);
        if (!saved_manager)
                return -ENOMEM;
-       down_write(&tomoyo_policy_manager_list_lock);
+       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;
        }
-       new_entry = tomoyo_alloc_element(sizeof(*new_entry));
-       if (!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);
-       error = 0;
- out:
-       up_write(&tomoyo_policy_manager_list_lock);
+       mutex_unlock(&tomoyo_policy_lock);
+       kfree(entry);
        return error;
 }
 
@@ -1242,7 +1242,7 @@ static bool tomoyo_is_policy_manager(void)
                        last_pid = pid;
                }
        }
-       tomoyo_free(exe);
+       kfree(exe);
        return found;
 }
 
@@ -1315,7 +1315,7 @@ static int tomoyo_delete_domain(char *domainname)
 
        name.name = domainname;
        tomoyo_fill_path_info(&name);
-       down_write(&tomoyo_domain_list_lock);
+       mutex_lock(&tomoyo_policy_lock);
        /* Is there an active domain? */
        list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
                /* Never delete tomoyo_kernel_domain */
@@ -1327,7 +1327,7 @@ static int tomoyo_delete_domain(char *domainname)
                domain->is_deleted = true;
                break;
        }
-       up_write(&tomoyo_domain_list_lock);
+       mutex_unlock(&tomoyo_policy_lock);
        return 0;
 }
 
@@ -1378,8 +1378,7 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
                return 0;
        }
        if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
-               tomoyo_set_domain_flag(domain, is_delete,
-                              TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ);
+               domain->ignore_global_allow_read = !is_delete;
                return 0;
        }
        return tomoyo_write_file_policy(data, domain, is_delete);
@@ -1480,10 +1479,8 @@ static bool tomoyo_print_double_path_acl(struct tomoyo_io_buffer *head,
 static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
                               struct tomoyo_acl_info *ptr)
 {
-       const u8 acl_type = tomoyo_acl_type2(ptr);
+       const u8 acl_type = ptr->type;
 
-       if (acl_type & TOMOYO_ACL_DELETED)
-               return true;
        if (acl_type == TOMOYO_TYPE_SINGLE_PATH_ACL) {
                struct tomoyo_single_path_acl_record *acl
                        = container_of(ptr,
@@ -1534,10 +1531,9 @@ static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
                /* Print domainname and flags. */
                if (domain->quota_warned)
                        quota_exceeded = "quota_exceeded\n";
-               if (domain->flags & TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED)
+               if (domain->transition_failed)
                        transition_failed = "transition_failed\n";
-               if (domain->flags &
-                   TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ)
+               if (domain->ignore_global_allow_read)
                        ignore_global_allow_read
                                = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
                done = tomoyo_io_printf(head, "%s\n" TOMOYO_KEYWORD_USE_PROFILE
@@ -1925,7 +1921,7 @@ static int tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
  */
 static int tomoyo_open_control(const u8 type, struct file *file)
 {
-       struct tomoyo_io_buffer *head = tomoyo_alloc(sizeof(*head));
+       struct tomoyo_io_buffer *head = kzalloc(sizeof(*head), GFP_KERNEL);
 
        if (!head)
                return -ENOMEM;
@@ -1986,9 +1982,9 @@ static int tomoyo_open_control(const u8 type, struct file *file)
        } else {
                if (!head->readbuf_size)
                        head->readbuf_size = 4096 * 2;
-               head->read_buf = tomoyo_alloc(head->readbuf_size);
+               head->read_buf = kzalloc(head->readbuf_size, GFP_KERNEL);
                if (!head->read_buf) {
-                       tomoyo_free(head);
+                       kfree(head);
                        return -ENOMEM;
                }
        }
@@ -2000,10 +1996,10 @@ static int tomoyo_open_control(const u8 type, struct file *file)
                head->write = NULL;
        } else if (head->write) {
                head->writebuf_size = 4096 * 2;
-               head->write_buf = tomoyo_alloc(head->writebuf_size);
+               head->write_buf = kzalloc(head->writebuf_size, GFP_KERNEL);
                if (!head->write_buf) {
-                       tomoyo_free(head->read_buf);
-                       tomoyo_free(head);
+                       kfree(head->read_buf);
+                       kfree(head);
                        return -ENOMEM;
                }
        }
@@ -2135,45 +2131,16 @@ static int tomoyo_close_control(struct file *file)
 
        tomoyo_read_unlock(head->reader_idx);
        /* Release memory used for policy I/O. */
-       tomoyo_free(head->read_buf);
+       kfree(head->read_buf);
        head->read_buf = NULL;
-       tomoyo_free(head->write_buf);
+       kfree(head->write_buf);
        head->write_buf = NULL;
-       tomoyo_free(head);
+       kfree(head);
        head = NULL;
        file->private_data = NULL;
        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.
  *