]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - security/tomoyo/realpath.c
TOMOYO: Remove memory pool for string data.
[net-next-2.6.git] / security / tomoyo / realpath.c
index 18369d497eb80116da1d146ddc49268ae0b07229..9105e5e29da91212ebe2eb1fc41fdf8c4f3382f9 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/mnt_namespace.h>
 #include <linux/fs_struct.h>
 #include <linux/hash.h>
+#include <linux/magic.h>
 
 #include "common.h"
 #include "realpath.h"
@@ -112,7 +113,7 @@ int tomoyo_realpath_from_path2(struct path *path, char *newname,
                path_put(&ns_root);
                /* Prepend "/proc" prefix if using internal proc vfs mount. */
                if (!IS_ERR(sp) && (path->mnt->mnt_parent == path->mnt) &&
-                   (strcmp(path->mnt->mnt_sb->s_type->name, "proc") == 0)) {
+                   (path->mnt->mnt_sb->s_magic == PROC_SUPER_MAGIC)) {
                        sp -= 5;
                        if (sp >= newname)
                                memcpy(sp, "/proc", 5);
@@ -292,13 +293,6 @@ struct tomoyo_name_entry {
        struct tomoyo_path_info entry;
 };
 
-/* Structure for available memory region. */
-struct tomoyo_free_memory_block_list {
-       struct list_head list;
-       char *ptr;             /* Pointer to a free area. */
-       int len;               /* Length of the area.     */
-};
-
 /*
  * tomoyo_name_list is used for holding string data used by TOMOYO.
  * Since same string data is likely used for multiple times (e.g.
@@ -313,52 +307,32 @@ static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
  * @name: The string to store into the permernent memory.
  *
  * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
- *
- * The RAM is shared, so NEVER try to modify or kfree() the returned name.
  */
 const struct tomoyo_path_info *tomoyo_save_name(const char *name)
 {
-       static LIST_HEAD(fmb_list);
        static DEFINE_MUTEX(lock);
        struct tomoyo_name_entry *ptr;
        unsigned int hash;
-       /* fmb contains available size in bytes.
-          fmb is removed from the fmb_list when fmb->len becomes 0. */
-       struct tomoyo_free_memory_block_list *fmb;
        int len;
-       char *cp;
+       int allocated_len;
        struct list_head *head;
 
        if (!name)
                return NULL;
        len = strlen(name) + 1;
-       if (len > TOMOYO_MAX_PATHNAME_LEN) {
-               printk(KERN_WARNING "ERROR: Name too long "
-                      "for tomoyo_save_name().\n");
-               return NULL;
-       }
        hash = full_name_hash((const unsigned char *) name, len - 1);
        head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
-
        mutex_lock(&lock);
        list_for_each_entry(ptr, head, list) {
                if (hash == ptr->entry.hash && !strcmp(name, ptr->entry.name))
                        goto out;
        }
-       list_for_each_entry(fmb, &fmb_list, list) {
-               if (len <= fmb->len)
-                       goto ready;
-       }
-       if (!tomoyo_quota_for_savename ||
-           tomoyo_allocated_memory_for_savename + PATH_MAX
-           <= tomoyo_quota_for_savename)
-               cp = kzalloc(PATH_MAX, GFP_KERNEL);
-       else
-               cp = NULL;
-       fmb = kzalloc(sizeof(*fmb), GFP_KERNEL);
-       if (!cp || !fmb) {
-               kfree(cp);
-               kfree(fmb);
+       ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL);
+       allocated_len = ptr ? ksize(ptr) : 0;
+       if (!ptr || (tomoyo_quota_for_savename &&
+                    tomoyo_allocated_memory_for_savename + allocated_len
+                    > tomoyo_quota_for_savename)) {
+               kfree(ptr);
                printk(KERN_WARNING "ERROR: Out of memory "
                       "for tomoyo_save_name().\n");
                if (!tomoyo_policy_loaded)
@@ -366,24 +340,11 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
                ptr = NULL;
                goto out;
        }
-       tomoyo_allocated_memory_for_savename += PATH_MAX;
-       list_add(&fmb->list, &fmb_list);
-       fmb->ptr = cp;
-       fmb->len = PATH_MAX;
- ready:
-       ptr = tomoyo_alloc_element(sizeof(*ptr));
-       if (!ptr)
-               goto out;
-       ptr->entry.name = fmb->ptr;
-       memmove(fmb->ptr, name, len);
+       tomoyo_allocated_memory_for_savename += allocated_len;
+       ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
+       memmove((char *) ptr->entry.name, name, len);
        tomoyo_fill_path_info(&ptr->entry);
-       fmb->ptr += len;
-       fmb->len -= len;
        list_add_tail(&ptr->list, head);
-       if (fmb->len == 0) {
-               list_del(&fmb->list);
-               kfree(fmb);
-       }
  out:
        mutex_unlock(&lock);
        return ptr ? &ptr->entry : NULL;
@@ -401,11 +362,13 @@ void __init tomoyo_realpath_init(void)
                INIT_LIST_HEAD(&tomoyo_name_list[i]);
        INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list);
        tomoyo_kernel_domain.domainname = tomoyo_save_name(TOMOYO_ROOT_NAME);
-       list_add_tail(&tomoyo_kernel_domain.list, &tomoyo_domain_list);
-       down_read(&tomoyo_domain_list_lock);
+       /*
+        * tomoyo_read_lock() is not needed because this function is
+        * called before the first "delete" request.
+        */
+       list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list);
        if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain)
                panic("Can't register tomoyo_kernel_domain");
-       up_read(&tomoyo_domain_list_lock);
 }
 
 /* Memory allocated for temporary purpose. */