diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/tomoyo/realpath.c | 60 |
1 files changed, 10 insertions, 50 deletions
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c index 62363b3bc71..9105e5e29da 100644 --- a/security/tomoyo/realpath.c +++ b/security/tomoyo/realpath.c @@ -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; |