Commit fdb8ebb7 authored by Tetsuo Handa's avatar Tetsuo Handa Committed by James Morris
Browse files

TOMOYO: Use RCU primitives for list operation



Replace list operation with RCU primitives and replace
down_read()/up_read() with srcu_read_lock()/srcu_read_unlock().
Signed-off-by: default avatarTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-by: default avatarSerge Hallyn <serue@us.ibm.com>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent 86fc80f1
......@@ -365,10 +365,9 @@ bool tomoyo_is_domain_def(const unsigned char *buffer)
*
* @domainname: The domainname to find.
*
* Caller must call down_read(&tomoyo_domain_list_lock); or
* down_write(&tomoyo_domain_list_lock); .
*
* Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise.
*
* Caller holds tomoyo_read_lock().
*/
struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)
{
......@@ -377,7 +376,7 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)
name.name = domainname;
tomoyo_fill_path_info(&name);
list_for_each_entry(domain, &tomoyo_domain_list, list) {
list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
if (!domain->is_deleted &&
!tomoyo_pathcmp(&name, domain->domainname))
return domain;
......@@ -829,6 +828,8 @@ bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain)
* @domain: Pointer to "struct tomoyo_domain_info".
*
* Returns true if the domain is not exceeded quota, false otherwise.
*
* Caller holds tomoyo_read_lock().
*/
bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain)
{
......@@ -837,8 +838,7 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain)
if (!domain)
return true;
down_read(&tomoyo_domain_acl_info_list_lock);
list_for_each_entry(ptr, &domain->acl_info_list, list) {
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
if (ptr->type & TOMOYO_ACL_DELETED)
continue;
switch (tomoyo_acl_type2(ptr)) {
......@@ -866,7 +866,6 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain)
break;
}
}
up_read(&tomoyo_domain_acl_info_list_lock);
if (count < tomoyo_check_flags(domain, TOMOYO_MAX_ACCEPT_ENTRY))
return true;
if (!domain->quota_warned) {
......@@ -1096,6 +1095,8 @@ static DECLARE_RWSEM(tomoyo_policy_manager_list_lock);
* @is_delete: True if it is a delete request.
*
* Returns 0 on success, negative value otherwise.
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_update_manager_entry(const char *manager,
const bool is_delete)
......@@ -1118,7 +1119,7 @@ static int tomoyo_update_manager_entry(const char *manager,
if (!saved_manager)
return -ENOMEM;
down_write(&tomoyo_policy_manager_list_lock);
list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) {
list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
if (ptr->manager != saved_manager)
continue;
ptr->is_deleted = is_delete;
......@@ -1134,7 +1135,7 @@ static int tomoyo_update_manager_entry(const char *manager,
goto out;
new_entry->manager = saved_manager;
new_entry->is_domain = is_domain;
list_add_tail(&new_entry->list, &tomoyo_policy_manager_list);
list_add_tail_rcu(&new_entry->list, &tomoyo_policy_manager_list);
error = 0;
out:
up_write(&tomoyo_policy_manager_list_lock);
......@@ -1147,6 +1148,8 @@ static int tomoyo_update_manager_entry(const char *manager,
* @head: Pointer to "struct tomoyo_io_buffer".
*
* Returns 0 on success, negative value otherwise.
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head)
{
......@@ -1166,6 +1169,8 @@ static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head)
* @head: Pointer to "struct tomoyo_io_buffer".
*
* Returns 0.
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
{
......@@ -1174,7 +1179,6 @@ static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
if (head->read_eof)
return 0;
down_read(&tomoyo_policy_manager_list_lock);
list_for_each_cookie(pos, head->read_var2,
&tomoyo_policy_manager_list) {
struct tomoyo_policy_manager_entry *ptr;
......@@ -1186,7 +1190,6 @@ static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
if (!done)
break;
}
up_read(&tomoyo_policy_manager_list_lock);
head->read_eof = done;
return 0;
}
......@@ -1196,6 +1199,8 @@ static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
*
* Returns true if the current process is permitted to modify policy
* via /sys/kernel/security/tomoyo/ interface.
*
* Caller holds tomoyo_read_lock().
*/
static bool tomoyo_is_policy_manager(void)
{
......@@ -1209,29 +1214,25 @@ static bool tomoyo_is_policy_manager(void)
return true;
if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid))
return false;
down_read(&tomoyo_policy_manager_list_lock);
list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) {
list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
if (!ptr->is_deleted && ptr->is_domain
&& !tomoyo_pathcmp(domainname, ptr->manager)) {
found = true;
break;
}
}
up_read(&tomoyo_policy_manager_list_lock);
if (found)
return true;
exe = tomoyo_get_exe();
if (!exe)
return false;
down_read(&tomoyo_policy_manager_list_lock);
list_for_each_entry(ptr, &tomoyo_policy_manager_list, list) {
list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
if (!ptr->is_deleted && !ptr->is_domain
&& !strcmp(exe, ptr->manager->name)) {
found = true;
break;
}
}
up_read(&tomoyo_policy_manager_list_lock);
if (!found) { /* Reduce error messages. */
static pid_t last_pid;
const pid_t pid = current->pid;
......@@ -1252,6 +1253,8 @@ static bool tomoyo_is_policy_manager(void)
* @data: String to parse.
*
* Returns true on success, false otherwise.
*
* Caller holds tomoyo_read_lock().
*/
static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
const char *data)
......@@ -1267,11 +1270,8 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
domain = tomoyo_real_domain(p);
read_unlock(&tasklist_lock);
} else if (!strncmp(data, "domain=", 7)) {
if (tomoyo_is_domain_def(data + 7)) {
down_read(&tomoyo_domain_list_lock);
if (tomoyo_is_domain_def(data + 7))
domain = tomoyo_find_domain(data + 7);
up_read(&tomoyo_domain_list_lock);
}
} else
return false;
head->write_var1 = domain;
......@@ -1285,13 +1285,11 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
if (domain) {
struct tomoyo_domain_info *d;
head->read_var1 = NULL;
down_read(&tomoyo_domain_list_lock);
list_for_each_entry(d, &tomoyo_domain_list, list) {
list_for_each_entry_rcu(d, &tomoyo_domain_list, list) {
if (d == domain)
break;
head->read_var1 = &d->list;
}
up_read(&tomoyo_domain_list_lock);
head->read_var2 = NULL;
head->read_bit = 0;
head->read_step = 0;
......@@ -1307,6 +1305,8 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
* @domainname: The name of domain.
*
* Returns 0.
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_delete_domain(char *domainname)
{
......@@ -1317,7 +1317,7 @@ static int tomoyo_delete_domain(char *domainname)
tomoyo_fill_path_info(&name);
down_write(&tomoyo_domain_list_lock);
/* Is there an active domain? */
list_for_each_entry(domain, &tomoyo_domain_list, list) {
list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
/* Never delete tomoyo_kernel_domain */
if (domain == &tomoyo_kernel_domain)
continue;
......@@ -1337,6 +1337,8 @@ static int tomoyo_delete_domain(char *domainname)
* @head: Pointer to "struct tomoyo_io_buffer".
*
* Returns 0 on success, negative value otherwise.
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
{
......@@ -1359,11 +1361,9 @@ static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
domain = NULL;
if (is_delete)
tomoyo_delete_domain(data);
else if (is_select) {
down_read(&tomoyo_domain_list_lock);
else if (is_select)
domain = tomoyo_find_domain(data);
up_read(&tomoyo_domain_list_lock);
} else
else
domain = tomoyo_find_or_assign_new_domain(data, 0);
head->write_var1 = domain;
return 0;
......@@ -1508,6 +1508,8 @@ static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
* @head: Pointer to "struct tomoyo_io_buffer".
*
* Returns 0.
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
{
......@@ -1519,7 +1521,6 @@ static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
return 0;
if (head->read_step == 0)
head->read_step = 1;
down_read(&tomoyo_domain_list_lock);
list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) {
struct tomoyo_domain_info *domain;
const char *quota_exceeded = "";
......@@ -1552,7 +1553,6 @@ acl_loop:
if (head->read_step == 3)
goto tail_mark;
/* Print ACL entries in the domain. */
down_read(&tomoyo_domain_acl_info_list_lock);
list_for_each_cookie(apos, head->read_var2,
&domain->acl_info_list) {
struct tomoyo_acl_info *ptr
......@@ -1562,7 +1562,6 @@ acl_loop:
if (!done)
break;
}
up_read(&tomoyo_domain_acl_info_list_lock);
if (!done)
break;
head->read_step = 3;
......@@ -1574,7 +1573,6 @@ tail_mark:
if (head->read_single_domain)
break;
}
up_read(&tomoyo_domain_list_lock);
head->read_eof = done;
return 0;
}
......@@ -1590,6 +1588,8 @@ tail_mark:
*
* ( echo "select " $domainname; echo "use_profile " $profile ) |
* /usr/lib/ccs/loadpolicy -d
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
{
......@@ -1601,9 +1601,7 @@ static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
if (!cp)
return -EINVAL;
*cp = '\0';
down_read(&tomoyo_domain_list_lock);
domain = tomoyo_find_domain(cp + 1);
up_read(&tomoyo_domain_list_lock);
if (strict_strtoul(data, 10, &profile))
return -EINVAL;
if (domain && profile < TOMOYO_MAX_PROFILES
......@@ -1625,6 +1623,8 @@ static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
* awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" )
* domainname = $0; } else if ( $1 == "use_profile" ) {
* print $2 " " domainname; domainname = ""; } } ; '
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
{
......@@ -1633,7 +1633,6 @@ static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
if (head->read_eof)
return 0;
down_read(&tomoyo_domain_list_lock);
list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) {
struct tomoyo_domain_info *domain;
domain = list_entry(pos, struct tomoyo_domain_info, list);
......@@ -1644,7 +1643,6 @@ static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
if (!done)
break;
}
up_read(&tomoyo_domain_list_lock);
head->read_eof = done;
return 0;
}
......@@ -1701,6 +1699,8 @@ static int tomoyo_read_pid(struct tomoyo_io_buffer *head)
* @head: Pointer to "struct tomoyo_io_buffer".
*
* Returns 0 on success, negative value otherwise.
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head)
{
......@@ -1735,6 +1735,8 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head)
* @head: Pointer to "struct tomoyo_io_buffer".
*
* Returns 0 on success, -EINVAL otherwise.
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head)
{
......@@ -1864,15 +1866,13 @@ void tomoyo_load_policy(const char *filename)
tomoyo_policy_loaded = true;
{ /* Check all profiles currently assigned to domains are defined. */
struct tomoyo_domain_info *domain;
down_read(&tomoyo_domain_list_lock);
list_for_each_entry(domain, &tomoyo_domain_list, list) {
list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
const u8 profile = domain->profile;
if (tomoyo_profile_ptr[profile])
continue;
panic("Profile %u (used by '%s') not defined.\n",
profile, domain->domainname->name);
}
up_read(&tomoyo_domain_list_lock);
}
}
......@@ -1920,6 +1920,8 @@ static int tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
* @file: Pointer to "struct file".
*
* Associates policy handler and returns 0 on success, -ENOMEM otherwise.
*
* Caller acquires tomoyo_read_lock().
*/
static int tomoyo_open_control(const u8 type, struct file *file)
{
......@@ -2005,6 +2007,7 @@ static int tomoyo_open_control(const u8 type, struct file *file)
return -ENOMEM;
}
}
head->reader_idx = tomoyo_read_lock();
file->private_data = head;
/*
* Call the handler now if the file is
......@@ -2026,6 +2029,8 @@ static int tomoyo_open_control(const u8 type, struct file *file)
* @buffer_len: Size of @buffer.
*
* Returns bytes read on success, negative value otherwise.
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_read_control(struct file *file, char __user *buffer,
const int buffer_len)
......@@ -2069,6 +2074,8 @@ static int tomoyo_read_control(struct file *file, char __user *buffer,
* @buffer_len: Size of @buffer.
*
* Returns @buffer_len on success, negative value otherwise.
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_write_control(struct file *file, const char __user *buffer,
const int buffer_len)
......@@ -2119,11 +2126,14 @@ static int tomoyo_write_control(struct file *file, const char __user *buffer,
* @file: Pointer to "struct file".
*
* Releases memory and returns 0.
*
* Caller looses tomoyo_read_lock().
*/
static int tomoyo_close_control(struct file *file)
{
struct tomoyo_io_buffer *head = file->private_data;
tomoyo_read_unlock(head->reader_idx);
/* Release memory used for policy I/O. */
tomoyo_free(head->read_buf);
head->read_buf = NULL;
......
......@@ -269,6 +269,8 @@ struct tomoyo_io_buffer {
int (*write) (struct tomoyo_io_buffer *);
/* Exclusive lock for this structure. */
struct mutex io_sem;
/* Index returned by tomoyo_read_lock(). */
int reader_idx;
/* The position currently reading from. */
struct list_head *read_var1;
/* Extra variables for reading. */
......@@ -446,16 +448,28 @@ extern struct tomoyo_domain_info tomoyo_kernel_domain;
* @cookie: the &struct list_head to use as a cookie.
* @head: the head for your list.
*
* Same with list_for_each() except that this primitive uses @cookie
* Same with list_for_each_rcu() except that this primitive uses @cookie
* so that we can continue iteration.
* @cookie must be NULL when iteration starts, and @cookie will become
* NULL when iteration finishes.
*/
#define list_for_each_cookie(pos, cookie, head) \
for (({ if (!cookie) \
cookie = head; }), \
pos = (cookie)->next; \
prefetch(pos->next), pos != (head) || ((cookie) = NULL); \
(cookie) = pos, pos = pos->next)
#define list_for_each_cookie(pos, cookie, head) \
for (({ if (!cookie) \
cookie = head; }), \
pos = rcu_dereference((cookie)->next); \
prefetch(pos->next), pos != (head) || ((cookie) = NULL); \
(cookie) = pos, pos = rcu_dereference(pos->next))
extern struct srcu_struct tomoyo_ss;
static inline int tomoyo_read_lock(void)
{
return srcu_read_lock(&tomoyo_ss);
}
static inline void tomoyo_read_unlock(int idx)
{
srcu_read_unlock(&tomoyo_ss, idx);
}
#endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */
......@@ -217,6 +217,8 @@ static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock);
* @is_delete: True if it is a delete request.
*
* Returns 0 on success, negative value otherwise.
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_update_domain_initializer_entry(const char *domainname,
const char *program,
......@@ -246,7 +248,7 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
if (!saved_program)
return -ENOMEM;
down_write(&tomoyo_domain_initializer_list_lock);
list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) {
list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) {
if (ptr->is_not != is_not ||
ptr->domainname != saved_domainname ||
ptr->program != saved_program)
......@@ -266,7 +268,7 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
new_entry->program = saved_program;
new_entry->is_not = is_not;
new_entry->is_last_name = is_last_name;
list_add_tail(&new_entry->list, &tomoyo_domain_initializer_list);
list_add_tail_rcu(&new_entry->list, &tomoyo_domain_initializer_list);
error = 0;
out:
up_write(&tomoyo_domain_initializer_list_lock);
......@@ -279,13 +281,14 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname,
* @head: Pointer to "struct tomoyo_io_buffer".
*
* Returns true on success, false otherwise.
*
* Caller holds tomoyo_read_lock().
*/
bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head)
{
struct list_head *pos;
bool done = true;
down_read(&tomoyo_domain_initializer_list_lock);
list_for_each_cookie(pos, head->read_var2,
&tomoyo_domain_initializer_list) {
const char *no;
......@@ -308,7 +311,6 @@ bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head)
if (!done)
break;
}
up_read(&tomoyo_domain_initializer_list_lock);
return done;
}
......@@ -320,6 +322,8 @@ bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head)
* @is_delete: True if it is a delete request.
*
* Returns 0 on success, negative value otherwise.
*
* Caller holds tomoyo_read_lock().
*/
int tomoyo_write_domain_initializer_policy(char *data, const bool is_not,
const bool is_delete)
......@@ -345,6 +349,8 @@ int tomoyo_write_domain_initializer_policy(char *data, const bool is_not,
*
* Returns true if executing @program reinitializes domain transition,
* false otherwise.
*
* Caller holds tomoyo_read_lock().
*/
static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
domainname,
......@@ -355,8 +361,7 @@ static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
struct tomoyo_domain_initializer_entry *ptr;
bool flag = false;
down_read(&tomoyo_domain_initializer_list_lock);
list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) {
list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list, list) {
if (ptr->is_deleted)
continue;
if (ptr->domainname) {
......@@ -376,7 +381,6 @@ static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
}
flag = true;
}
up_read(&tomoyo_domain_initializer_list_lock);
return flag;
}
......@@ -430,6 +434,8 @@ static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock);
* @is_delete: True if it is a delete request.
*
* Returns 0 on success, negative value otherwise.
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_update_domain_keeper_entry(const char *domainname,
const char *program,
......@@ -459,7 +465,7 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
if (!saved_domainname)
return -ENOMEM;
down_write(&tomoyo_domain_keeper_list_lock);
list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) {
list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
if (ptr->is_not != is_not ||
ptr->domainname != saved_domainname ||
ptr->program != saved_program)
......@@ -479,7 +485,7 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
new_entry->program = saved_program;
new_entry->is_not = is_not;
new_entry->is_last_name = is_last_name;
list_add_tail(&new_entry->list, &tomoyo_domain_keeper_list);
list_add_tail_rcu(&new_entry->list, &tomoyo_domain_keeper_list);
error = 0;
out:
up_write(&tomoyo_domain_keeper_list_lock);
......@@ -493,6 +499,7 @@ static int tomoyo_update_domain_keeper_entry(const char *domainname,
* @is_not: True if it is "no_keep_domain" entry.
* @is_delete: True if it is a delete request.
*
* Caller holds tomoyo_read_lock().
*/
int tomoyo_write_domain_keeper_policy(char *data, const bool is_not,
const bool is_delete)
......@@ -513,13 +520,14 @@ int tomoyo_write_domain_keeper_policy(char *data, const bool is_not,
* @head: Pointer to "struct tomoyo_io_buffer".
*
* Returns true on success, false otherwise.
*
* Caller holds tomoyo_read_lock().
*/
bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head)
{
struct list_head *pos;
bool done = true;
down_read(&tomoyo_domain_keeper_list_lock);
list_for_each_cookie(pos, head->read_var2,
&tomoyo_domain_keeper_list) {
struct tomoyo_domain_keeper_entry *ptr;
......@@ -542,7 +550,6 @@ bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head)
if (!done)
break;
}
up_read(&tomoyo_domain_keeper_list_lock);
return done;
}
......@@ -555,6 +562,8 @@ bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head)
*
* Returns true if executing @program supresses domain transition,
* false otherwise.
*
* Caller holds tomoyo_read_lock().
*/
static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
const struct tomoyo_path_info *program,
......@@ -563,8 +572,7 @@ static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
struct tomoyo_domain_keeper_entry *ptr;
bool flag = false;
down_read(&tomoyo_domain_keeper_list_lock);
list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) {
list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
if (ptr->is_deleted)
continue;
if (!ptr->is_last_name) {
......@@ -582,7 +590,6 @@ static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
}
flag = true;
}
up_read(&tomoyo_domain_keeper_list_lock);
return flag;
}
......@@ -627,6 +634,8 @@ static DECLARE_RWSEM(tomoyo_alias_list_lock);
* @is_delete: True if it is a delete request.
*
* Returns 0 on success, negative value otherwise.
*
* Caller holds tomoyo_read_lock().
*/
static int tomoyo_update_alias_entry(const char *original_name,
const char *aliased_name,
......@@ -646,7 +655,7 @@ static int tomoyo_update_alias_entry(const char *original_name,
if (!saved_original_name || !saved_aliased_name)
return -ENOMEM;
down_write(&tomoyo_alias_list_lock);
list_for_each_entry(ptr, &tomoyo_alias_list, list) {
list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
if (ptr->original_name != saved_original_name ||
ptr->aliased_name != saved_aliased_name)
continue;
......@@ -663,7 +672,7 @@ static int tomoyo_update_alias_entry(const char *original_name,
goto out;
new_entry->original_name = saved_original_name;
new_entry->aliased_name = saved_aliased_name;
list_add_tail(&new_entry->list, &tomoyo_alias_list);
list_add_tail_rcu(&new_entry->list, &tomoyo_alias_list);
error = 0;
out:
up_write(&tomoyo_alias_list_lock);
......@@ -676,13 +685,14 @@ static int tomoyo_update_alias_entry(const char *original_name,
* @head: Pointer to "struct tomoyo_io_buffer".
*
* Returns true on success, false otherwise.
*
* Caller holds tomoyo_read_lock().
*/
bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head)
{
struct list_head *pos;
bool done = true;
down_read(&tomoyo_alias_list_lock);
list_for_each_cookie(pos, head->read_var2, &tomoyo_alias_list) {
struct tomoyo_alias_entry *ptr;
......@@ -695,7 +705,6 @@ bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head)
if (!done)
break;
}
up_read(&tomoyo_alias_list_lock);
return done;
}
......@@ -706,6 +715,8 @@ bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head)
* @is_delete: True if it is a delete request.
*
* Returns 0 on success, negative value otherwise.
*
* Caller holds tomoyo_read_lock().
*/
int tomoyo_write_alias_policy(char *data, const bool is_delete)
{
......@@ -724,6 +735,8 @@ int tomoyo_write_alias_policy(char *data, const bool is_delete)
* @profile: Profile number to assign if the domain was newly created.