TOMOYO: Add refcounter on string data.

Add refcounter to "struct tomoyo_name_entry" and replace tomoyo_save_name()
with tomoyo_get_name()/tomoyo_put_name() pair so that we can kfree() when
garbage collector is added.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
Tetsuo Handa 2010-02-11 09:41:58 +09:00 committed by James Morris
parent ca0b7df337
commit bf24fb016c
5 changed files with 77 additions and 40 deletions

View file

@ -12,8 +12,8 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/security.h> #include <linux/security.h>
#include <linux/hardirq.h> #include <linux/hardirq.h>
#include "realpath.h"
#include "common.h" #include "common.h"
#include "realpath.h"
#include "tomoyo.h" #include "tomoyo.h"
/* Lock for protecting policy. */ /* Lock for protecting policy. */
@ -943,7 +943,9 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
return -EINVAL; return -EINVAL;
*cp = '\0'; *cp = '\0';
if (!strcmp(data, "COMMENT")) { if (!strcmp(data, "COMMENT")) {
profile->comment = tomoyo_save_name(cp + 1); const struct tomoyo_path_info *old_comment = profile->comment;
profile->comment = tomoyo_get_name(cp + 1);
tomoyo_put_name(old_comment);
return 0; return 0;
} }
for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) { for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) {
@ -1117,7 +1119,7 @@ static int tomoyo_update_manager_entry(const char *manager,
if (!tomoyo_is_correct_path(manager, 1, -1, -1, __func__)) if (!tomoyo_is_correct_path(manager, 1, -1, -1, __func__))
return -EINVAL; return -EINVAL;
} }
saved_manager = tomoyo_save_name(manager); saved_manager = tomoyo_get_name(manager);
if (!saved_manager) if (!saved_manager)
return -ENOMEM; return -ENOMEM;
if (!is_delete) if (!is_delete)
@ -1132,12 +1134,14 @@ static int tomoyo_update_manager_entry(const char *manager,
} }
if (!is_delete && error && tomoyo_memory_ok(entry)) { if (!is_delete && error && tomoyo_memory_ok(entry)) {
entry->manager = saved_manager; entry->manager = saved_manager;
saved_manager = NULL;
entry->is_domain = is_domain; entry->is_domain = is_domain;
list_add_tail_rcu(&entry->list, &tomoyo_policy_manager_list); list_add_tail_rcu(&entry->list, &tomoyo_policy_manager_list);
entry = NULL; entry = NULL;
error = 0; error = 0;
} }
mutex_unlock(&tomoyo_policy_lock); mutex_unlock(&tomoyo_policy_lock);
tomoyo_put_name(saved_manager);
kfree(entry); kfree(entry);
return error; return error;
} }

View file

@ -203,7 +203,7 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
{ {
struct tomoyo_domain_initializer_entry *entry = NULL; struct tomoyo_domain_initializer_entry *entry = NULL;
struct tomoyo_domain_initializer_entry *ptr; struct tomoyo_domain_initializer_entry *ptr;
const struct tomoyo_path_info *saved_program; const struct tomoyo_path_info *saved_program = NULL;
const struct tomoyo_path_info *saved_domainname = NULL; const struct tomoyo_path_info *saved_domainname = NULL;
int error = is_delete ? -ENOENT : -ENOMEM; int error = is_delete ? -ENOENT : -ENOMEM;
bool is_last_name = false; bool is_last_name = false;
@ -216,11 +216,11 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
is_last_name = true; is_last_name = true;
else if (!tomoyo_is_correct_domain(domainname, __func__)) else if (!tomoyo_is_correct_domain(domainname, __func__))
return -EINVAL; return -EINVAL;
saved_domainname = tomoyo_save_name(domainname); saved_domainname = tomoyo_get_name(domainname);
if (!saved_domainname) if (!saved_domainname)
goto out; goto out;
} }
saved_program = tomoyo_save_name(program); saved_program = tomoyo_get_name(program);
if (!saved_program) if (!saved_program)
goto out; goto out;
if (!is_delete) if (!is_delete)
@ -237,7 +237,9 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
} }
if (!is_delete && error && tomoyo_memory_ok(entry)) { if (!is_delete && error && tomoyo_memory_ok(entry)) {
entry->domainname = saved_domainname; entry->domainname = saved_domainname;
saved_domainname = NULL;
entry->program = saved_program; entry->program = saved_program;
saved_program = NULL;
entry->is_not = is_not; entry->is_not = is_not;
entry->is_last_name = is_last_name; entry->is_last_name = is_last_name;
list_add_tail_rcu(&entry->list, list_add_tail_rcu(&entry->list,
@ -247,6 +249,8 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
} }
mutex_unlock(&tomoyo_policy_lock); mutex_unlock(&tomoyo_policy_lock);
out: out:
tomoyo_put_name(saved_domainname);
tomoyo_put_name(saved_program);
kfree(entry); kfree(entry);
return error; return error;
} }
@ -419,7 +423,7 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
{ {
struct tomoyo_domain_keeper_entry *entry = NULL; struct tomoyo_domain_keeper_entry *entry = NULL;
struct tomoyo_domain_keeper_entry *ptr; struct tomoyo_domain_keeper_entry *ptr;
const struct tomoyo_path_info *saved_domainname; const struct tomoyo_path_info *saved_domainname = NULL;
const struct tomoyo_path_info *saved_program = NULL; const struct tomoyo_path_info *saved_program = NULL;
int error = is_delete ? -ENOENT : -ENOMEM; int error = is_delete ? -ENOENT : -ENOMEM;
bool is_last_name = false; bool is_last_name = false;
@ -432,11 +436,11 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
if (program) { if (program) {
if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__)) if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__))
return -EINVAL; return -EINVAL;
saved_program = tomoyo_save_name(program); saved_program = tomoyo_get_name(program);
if (!saved_program) if (!saved_program)
goto out; goto out;
} }
saved_domainname = tomoyo_save_name(domainname); saved_domainname = tomoyo_get_name(domainname);
if (!saved_domainname) if (!saved_domainname)
goto out; goto out;
if (!is_delete) if (!is_delete)
@ -453,7 +457,9 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
} }
if (!is_delete && error && tomoyo_memory_ok(entry)) { if (!is_delete && error && tomoyo_memory_ok(entry)) {
entry->domainname = saved_domainname; entry->domainname = saved_domainname;
saved_domainname = NULL;
entry->program = saved_program; entry->program = saved_program;
saved_program = NULL;
entry->is_not = is_not; entry->is_not = is_not;
entry->is_last_name = is_last_name; entry->is_last_name = is_last_name;
list_add_tail_rcu(&entry->list, &tomoyo_domain_keeper_list); list_add_tail_rcu(&entry->list, &tomoyo_domain_keeper_list);
@ -462,6 +468,8 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
} }
mutex_unlock(&tomoyo_policy_lock); mutex_unlock(&tomoyo_policy_lock);
out: out:
tomoyo_put_name(saved_domainname);
tomoyo_put_name(saved_program);
kfree(entry); kfree(entry);
return error; return error;
} }
@ -623,8 +631,8 @@ static int tomoyo_update_alias_entry(const char *original_name,
if (!tomoyo_is_correct_path(original_name, 1, -1, -1, __func__) || if (!tomoyo_is_correct_path(original_name, 1, -1, -1, __func__) ||
!tomoyo_is_correct_path(aliased_name, 1, -1, -1, __func__)) !tomoyo_is_correct_path(aliased_name, 1, -1, -1, __func__))
return -EINVAL; /* No patterns allowed. */ return -EINVAL; /* No patterns allowed. */
saved_original_name = tomoyo_save_name(original_name); saved_original_name = tomoyo_get_name(original_name);
saved_aliased_name = tomoyo_save_name(aliased_name); saved_aliased_name = tomoyo_get_name(aliased_name);
if (!saved_original_name || !saved_aliased_name) if (!saved_original_name || !saved_aliased_name)
goto out; goto out;
if (!is_delete) if (!is_delete)
@ -640,13 +648,17 @@ static int tomoyo_update_alias_entry(const char *original_name,
} }
if (!is_delete && error && tomoyo_memory_ok(entry)) { if (!is_delete && error && tomoyo_memory_ok(entry)) {
entry->original_name = saved_original_name; entry->original_name = saved_original_name;
saved_original_name = NULL;
entry->aliased_name = saved_aliased_name; entry->aliased_name = saved_aliased_name;
saved_aliased_name = NULL;
list_add_tail_rcu(&entry->list, &tomoyo_alias_list); list_add_tail_rcu(&entry->list, &tomoyo_alias_list);
entry = NULL; entry = NULL;
error = 0; error = 0;
} }
mutex_unlock(&tomoyo_policy_lock); mutex_unlock(&tomoyo_policy_lock);
out: out:
tomoyo_put_name(saved_original_name);
tomoyo_put_name(saved_aliased_name);
kfree(entry); kfree(entry);
return error; return error;
} }
@ -721,7 +733,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
if (!tomoyo_is_correct_domain(domainname, __func__)) if (!tomoyo_is_correct_domain(domainname, __func__))
return NULL; return NULL;
saved_domainname = tomoyo_save_name(domainname); saved_domainname = tomoyo_get_name(domainname);
if (!saved_domainname) if (!saved_domainname)
return NULL; return NULL;
entry = kzalloc(sizeof(*entry), GFP_KERNEL); entry = kzalloc(sizeof(*entry), GFP_KERNEL);
@ -736,6 +748,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
if (!found && tomoyo_memory_ok(entry)) { if (!found && tomoyo_memory_ok(entry)) {
INIT_LIST_HEAD(&entry->acl_info_list); INIT_LIST_HEAD(&entry->acl_info_list);
entry->domainname = saved_domainname; entry->domainname = saved_domainname;
saved_domainname = NULL;
entry->profile = profile; entry->profile = profile;
list_add_tail_rcu(&entry->list, &tomoyo_domain_list); list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
domain = entry; domain = entry;
@ -743,6 +756,7 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
found = true; found = true;
} }
mutex_unlock(&tomoyo_policy_lock); mutex_unlock(&tomoyo_policy_lock);
tomoyo_put_name(saved_domainname);
kfree(entry); kfree(entry);
return found ? domain : NULL; return found ? domain : NULL;
} }

View file

@ -222,7 +222,7 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
if (!tomoyo_is_correct_path(filename, 1, 0, -1, __func__)) if (!tomoyo_is_correct_path(filename, 1, 0, -1, __func__))
return -EINVAL; return -EINVAL;
saved_filename = tomoyo_save_name(filename); saved_filename = tomoyo_get_name(filename);
if (!saved_filename) if (!saved_filename)
return -ENOMEM; return -ENOMEM;
if (!is_delete) if (!is_delete)
@ -237,11 +237,13 @@ static int tomoyo_update_globally_readable_entry(const char *filename,
} }
if (!is_delete && error && tomoyo_memory_ok(entry)) { if (!is_delete && error && tomoyo_memory_ok(entry)) {
entry->filename = saved_filename; entry->filename = saved_filename;
saved_filename = NULL;
list_add_tail_rcu(&entry->list, &tomoyo_globally_readable_list); list_add_tail_rcu(&entry->list, &tomoyo_globally_readable_list);
entry = NULL; entry = NULL;
error = 0; error = 0;
} }
mutex_unlock(&tomoyo_policy_lock); mutex_unlock(&tomoyo_policy_lock);
tomoyo_put_name(saved_filename);
kfree(entry); kfree(entry);
return error; return error;
} }
@ -365,7 +367,7 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
const struct tomoyo_path_info *saved_pattern; const struct tomoyo_path_info *saved_pattern;
int error = is_delete ? -ENOENT : -ENOMEM; int error = is_delete ? -ENOENT : -ENOMEM;
saved_pattern = tomoyo_save_name(pattern); saved_pattern = tomoyo_get_name(pattern);
if (!saved_pattern) if (!saved_pattern)
return error; return error;
if (!saved_pattern->is_patterned) if (!saved_pattern->is_patterned)
@ -382,6 +384,7 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
} }
if (!is_delete && error && tomoyo_memory_ok(entry)) { if (!is_delete && error && tomoyo_memory_ok(entry)) {
entry->pattern = saved_pattern; entry->pattern = saved_pattern;
saved_pattern = NULL;
list_add_tail_rcu(&entry->list, &tomoyo_pattern_list); list_add_tail_rcu(&entry->list, &tomoyo_pattern_list);
entry = NULL; entry = NULL;
error = 0; error = 0;
@ -389,6 +392,7 @@ static int tomoyo_update_file_pattern_entry(const char *pattern,
mutex_unlock(&tomoyo_policy_lock); mutex_unlock(&tomoyo_policy_lock);
out: out:
kfree(entry); kfree(entry);
tomoyo_put_name(saved_pattern);
return error; return error;
} }
@ -518,7 +522,7 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
if (!tomoyo_is_correct_path(pattern, 0, 0, 0, __func__)) if (!tomoyo_is_correct_path(pattern, 0, 0, 0, __func__))
return -EINVAL; return -EINVAL;
saved_pattern = tomoyo_save_name(pattern); saved_pattern = tomoyo_get_name(pattern);
if (!saved_pattern) if (!saved_pattern)
return error; return error;
if (!is_delete) if (!is_delete)
@ -533,11 +537,13 @@ static int tomoyo_update_no_rewrite_entry(const char *pattern,
} }
if (!is_delete && error && tomoyo_memory_ok(entry)) { if (!is_delete && error && tomoyo_memory_ok(entry)) {
entry->pattern = saved_pattern; entry->pattern = saved_pattern;
saved_pattern = NULL;
list_add_tail_rcu(&entry->list, &tomoyo_no_rewrite_list); list_add_tail_rcu(&entry->list, &tomoyo_no_rewrite_list);
entry = NULL; entry = NULL;
error = 0; error = 0;
} }
mutex_unlock(&tomoyo_policy_lock); mutex_unlock(&tomoyo_policy_lock);
tomoyo_put_name(saved_pattern);
kfree(entry); kfree(entry);
return error; return error;
} }
@ -867,7 +873,7 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
return -EINVAL; return -EINVAL;
if (!tomoyo_is_correct_path(filename, 0, 0, 0, __func__)) if (!tomoyo_is_correct_path(filename, 0, 0, 0, __func__))
return -EINVAL; return -EINVAL;
saved_filename = tomoyo_save_name(filename); saved_filename = tomoyo_get_name(filename);
if (!saved_filename) if (!saved_filename)
return -ENOMEM; return -ENOMEM;
if (!is_delete) if (!is_delete)
@ -913,12 +919,14 @@ static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL)) if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL))
entry->perm |= rw_mask; entry->perm |= rw_mask;
entry->filename = saved_filename; entry->filename = saved_filename;
saved_filename = NULL;
list_add_tail_rcu(&entry->head.list, &domain->acl_info_list); list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
entry = NULL; entry = NULL;
error = 0; error = 0;
} }
mutex_unlock(&tomoyo_policy_lock); mutex_unlock(&tomoyo_policy_lock);
kfree(entry); kfree(entry);
tomoyo_put_name(saved_filename);
return error; return error;
} }
@ -952,8 +960,8 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
if (!tomoyo_is_correct_path(filename1, 0, 0, 0, __func__) || if (!tomoyo_is_correct_path(filename1, 0, 0, 0, __func__) ||
!tomoyo_is_correct_path(filename2, 0, 0, 0, __func__)) !tomoyo_is_correct_path(filename2, 0, 0, 0, __func__))
return -EINVAL; return -EINVAL;
saved_filename1 = tomoyo_save_name(filename1); saved_filename1 = tomoyo_get_name(filename1);
saved_filename2 = tomoyo_save_name(filename2); saved_filename2 = tomoyo_get_name(filename2);
if (!saved_filename1 || !saved_filename2) if (!saved_filename1 || !saved_filename2)
goto out; goto out;
if (!is_delete) if (!is_delete)
@ -979,13 +987,17 @@ static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
entry->head.type = TOMOYO_TYPE_DOUBLE_PATH_ACL; entry->head.type = TOMOYO_TYPE_DOUBLE_PATH_ACL;
entry->perm = perm; entry->perm = perm;
entry->filename1 = saved_filename1; entry->filename1 = saved_filename1;
saved_filename1 = NULL;
entry->filename2 = saved_filename2; entry->filename2 = saved_filename2;
saved_filename2 = NULL;
list_add_tail_rcu(&entry->head.list, &domain->acl_info_list); list_add_tail_rcu(&entry->head.list, &domain->acl_info_list);
entry = NULL; entry = NULL;
error = 0; error = 0;
} }
mutex_unlock(&tomoyo_policy_lock); mutex_unlock(&tomoyo_policy_lock);
out: out:
tomoyo_put_name(saved_filename1);
tomoyo_put_name(saved_filename2);
kfree(entry); kfree(entry);
return error; return error;
} }

View file

@ -253,21 +253,6 @@ static unsigned int tomoyo_quota_for_savename;
#define TOMOYO_HASH_BITS 8 #define TOMOYO_HASH_BITS 8
#define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS) #define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS)
/*
* tomoyo_name_entry is a structure which is used for linking
* "struct tomoyo_path_info" into tomoyo_name_list .
*
* Since tomoyo_name_list manages a list of strings which are shared by
* multiple processes (whereas "struct tomoyo_path_info" inside
* "struct tomoyo_path_info_with_data" is not shared), a reference counter will
* be added to "struct tomoyo_name_entry" rather than "struct tomoyo_path_info"
* when TOMOYO starts supporting garbage collector.
*/
struct tomoyo_name_entry {
struct list_head list;
struct tomoyo_path_info entry;
};
/* /*
* tomoyo_name_list is used for holding string data used by TOMOYO. * tomoyo_name_list is used for holding string data used by TOMOYO.
* Since same string data is likely used for multiple times (e.g. * Since same string data is likely used for multiple times (e.g.
@ -277,13 +262,13 @@ struct tomoyo_name_entry {
static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];
/** /**
* tomoyo_save_name - Allocate permanent memory for string data. * tomoyo_get_name - Allocate permanent memory for string data.
* *
* @name: The string to store into the permernent memory. * @name: The string to store into the permernent memory.
* *
* Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
*/ */
const struct tomoyo_path_info *tomoyo_save_name(const char *name) const struct tomoyo_path_info *tomoyo_get_name(const char *name)
{ {
static DEFINE_MUTEX(lock); static DEFINE_MUTEX(lock);
struct tomoyo_name_entry *ptr; struct tomoyo_name_entry *ptr;
@ -299,8 +284,10 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
mutex_lock(&lock); mutex_lock(&lock);
list_for_each_entry(ptr, head, list) { list_for_each_entry(ptr, head, list) {
if (hash == ptr->entry.hash && !strcmp(name, ptr->entry.name)) if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
goto out; continue;
atomic_inc(&ptr->users);
goto out;
} }
ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL); ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL);
allocated_len = ptr ? ksize(ptr) : 0; allocated_len = ptr ? ksize(ptr) : 0;
@ -309,7 +296,7 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
> tomoyo_quota_for_savename)) { > tomoyo_quota_for_savename)) {
kfree(ptr); kfree(ptr);
printk(KERN_WARNING "ERROR: Out of memory " printk(KERN_WARNING "ERROR: Out of memory "
"for tomoyo_save_name().\n"); "for tomoyo_get_name().\n");
if (!tomoyo_policy_loaded) if (!tomoyo_policy_loaded)
panic("MAC Initialization failed.\n"); panic("MAC Initialization failed.\n");
ptr = NULL; ptr = NULL;
@ -318,6 +305,7 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
tomoyo_allocated_memory_for_savename += allocated_len; tomoyo_allocated_memory_for_savename += allocated_len;
ptr->entry.name = ((char *) ptr) + sizeof(*ptr); ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
memmove((char *) ptr->entry.name, name, len); memmove((char *) ptr->entry.name, name, len);
atomic_set(&ptr->users, 1);
tomoyo_fill_path_info(&ptr->entry); tomoyo_fill_path_info(&ptr->entry);
list_add_tail(&ptr->list, head); list_add_tail(&ptr->list, head);
out: out:
@ -336,7 +324,7 @@ void __init tomoyo_realpath_init(void)
for (i = 0; i < TOMOYO_MAX_HASH; i++) for (i = 0; i < TOMOYO_MAX_HASH; i++)
INIT_LIST_HEAD(&tomoyo_name_list[i]); INIT_LIST_HEAD(&tomoyo_name_list[i]);
INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list); INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list);
tomoyo_kernel_domain.domainname = tomoyo_save_name(TOMOYO_ROOT_NAME); tomoyo_kernel_domain.domainname = tomoyo_get_name(TOMOYO_ROOT_NAME);
/* /*
* tomoyo_read_lock() is not needed because this function is * tomoyo_read_lock() is not needed because this function is
* called before the first "delete" request. * called before the first "delete" request.

View file

@ -43,7 +43,7 @@ bool tomoyo_memory_ok(void *ptr);
* Keep the given name on the RAM. * Keep the given name on the RAM.
* The RAM is shared, so NEVER try to modify or kfree() the returned name. * 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); const struct tomoyo_path_info *tomoyo_get_name(const char *name);
/* Check for memory usage. */ /* Check for memory usage. */
int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head); int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head);
@ -54,4 +54,23 @@ int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head);
/* Initialize realpath related code. */ /* Initialize realpath related code. */
void __init tomoyo_realpath_init(void); void __init tomoyo_realpath_init(void);
/*
* tomoyo_name_entry is a structure which is used for linking
* "struct tomoyo_path_info" into tomoyo_name_list .
*/
struct tomoyo_name_entry {
struct list_head list;
atomic_t users;
struct tomoyo_path_info entry;
};
static inline void tomoyo_put_name(const struct tomoyo_path_info *name)
{
if (name) {
struct tomoyo_name_entry *ptr =
container_of(name, struct tomoyo_name_entry, entry);
atomic_dec(&ptr->users);
}
}
#endif /* !defined(_SECURITY_TOMOYO_REALPATH_H) */ #endif /* !defined(_SECURITY_TOMOYO_REALPATH_H) */