TOMOYO: Remove memory pool for string data.
authorTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Mon, 4 Jan 2010 21:39:00 +0000 (06:39 +0900)
committerJames Morris <jmorris@namei.org>
Sun, 10 Jan 2010 22:27:38 +0000 (09:27 +1100)
Currently, TOMOYO allocates memory for string data from memory pool allocated
by kmalloc(PAGE_SIZE). But that makes it difficult to kfree() when garbage
collector is added. Thus, remove memory pool and use kmalloc(strlen()).

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
security/tomoyo/realpath.c

index 62363b3..9105e5e 100644 (file)
@@ -293,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.
@@ -314,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)
@@ -367,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;