summaryrefslogtreecommitdiffstats
path: root/security/tomoyo/realpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/realpath.c')
-rw-r--r--security/tomoyo/realpath.c60
1 files changed, 10 insertions, 50 deletions
diff --git a/security/tomoyo/realpath.c b/security/tomoyo/realpath.c
index 62363b3..9105e5e 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;
OpenPOWER on IntegriCloud