Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759509AbZJMLj7 (ORCPT ); Tue, 13 Oct 2009 07:39:59 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1756236AbZJMLj6 (ORCPT ); Tue, 13 Oct 2009 07:39:58 -0400 Received: from wine.ocn.ne.jp ([122.1.235.145]:56019 "EHLO smtp.wine.ocn.ne.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751839AbZJMLj4 (ORCPT ); Tue, 13 Oct 2009 07:39:56 -0400 To: linux-security-module@vger.kernel.org Cc: linux-kernel@vger.kernel.org Subject: [PATCH] TOMOYO: Use RCU primitives for list operation From: Tetsuo Handa References: <20091004125327.105675949@I-love.SAKURA.ne.jp> <4ACE1CFE.3020507@canonical.com> <200910132034.DAE39014.OVLFFOMHJQFOSt@I-love.SAKURA.ne.jp> <200910132037.BHJ57351.QLVJtMHSFOFOOF@I-love.SAKURA.ne.jp> In-Reply-To: <200910132037.BHJ57351.QLVJtMHSFOFOOF@I-love.SAKURA.ne.jp> Message-Id: <200910132039.HAD48971.JFOOMQFSFOtVLH@I-love.SAKURA.ne.jp> X-Mailer: Winbiff [Version 2.51 PL2] X-Accept-Language: ja,en,zh Date: Tue, 13 Oct 2009 20:39:19 +0900 Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 25607 Lines: 727 [PATCH] TOMOYO: Use RCU primitives for list operation Remove down_read()/up_read() by replacing with RCU primitives. SRCU based garbage collector will be added in the future. Signed-off-by: Tetsuo Handa --- security/tomoyo/common.c | 52 ++++++++++----------------------------------- security/tomoyo/common.h | 14 ++++++------ security/tomoyo/domain.c | 38 ++++++++++---------------------- security/tomoyo/file.c | 50 ++++++++++++++----------------------------- security/tomoyo/realpath.c | 4 --- 5 files changed, 49 insertions(+), 109 deletions(-) --- security-testing-2.6.orig/security/tomoyo/common.c +++ security-testing-2.6/security/tomoyo/common.c @@ -365,9 +365,6 @@ bool tomoyo_is_domain_def(const unsigned * * @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. */ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname) @@ -377,7 +374,7 @@ struct tomoyo_domain_info *tomoyo_find_d 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; @@ -837,8 +834,7 @@ bool tomoyo_domain_quota_is_ok(struct to 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)) { @@ -891,7 +887,6 @@ bool tomoyo_domain_quota_is_ok(struct to 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) { @@ -1143,7 +1138,7 @@ static int tomoyo_update_manager_entry(c 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; @@ -1159,7 +1154,7 @@ static int tomoyo_update_manager_entry(c 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); @@ -1199,7 +1194,6 @@ static int tomoyo_read_manager_policy(st 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; @@ -1211,7 +1205,6 @@ static int tomoyo_read_manager_policy(st if (!done) break; } - up_read(&tomoyo_policy_manager_list_lock); head->read_eof = done; return 0; } @@ -1234,29 +1227,25 @@ static bool tomoyo_is_policy_manager(voi 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; @@ -1292,11 +1281,8 @@ static bool tomoyo_is_select_one(struct 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; @@ -1310,13 +1296,11 @@ static bool tomoyo_is_select_one(struct 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; @@ -1342,7 +1326,7 @@ static int tomoyo_delete_domain(char *do 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; @@ -1384,11 +1368,9 @@ static int tomoyo_write_domain_policy(st 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; @@ -1544,7 +1526,6 @@ static int tomoyo_read_domain_policy(str 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 = ""; @@ -1577,7 +1558,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 @@ -1587,7 +1567,6 @@ acl_loop: if (!done) break; } - up_read(&tomoyo_domain_acl_info_list_lock); if (!done) break; head->read_step = 3; @@ -1599,7 +1578,6 @@ tail_mark: if (head->read_single_domain) break; } - up_read(&tomoyo_domain_list_lock); head->read_eof = done; return 0; } @@ -1626,9 +1604,7 @@ static int tomoyo_write_domain_profile(s 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 @@ -1658,7 +1634,6 @@ static int tomoyo_read_domain_profile(st 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); @@ -1669,7 +1644,6 @@ static int tomoyo_read_domain_profile(st if (!done) break; } - up_read(&tomoyo_domain_list_lock); head->read_eof = done; return 0; } @@ -1889,15 +1863,13 @@ void tomoyo_load_policy(const char *file 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); } } --- security-testing-2.6.orig/security/tomoyo/common.h +++ security-testing-2.6/security/tomoyo/common.h @@ -442,16 +442,16 @@ extern struct tomoyo_domain_info tomoyo_ * @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)) #endif /* !defined(_SECURITY_TOMOYO_COMMON_H) */ --- security-testing-2.6.orig/security/tomoyo/domain.c +++ security-testing-2.6/security/tomoyo/domain.c @@ -246,7 +246,7 @@ static int tomoyo_update_domain_initiali 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 +266,7 @@ static int tomoyo_update_domain_initiali 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); @@ -285,7 +285,6 @@ bool tomoyo_read_domain_initializer_poli 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 +307,6 @@ bool tomoyo_read_domain_initializer_poli if (!done) break; } - up_read(&tomoyo_domain_initializer_list_lock); return done; } @@ -355,8 +353,7 @@ static bool tomoyo_is_domain_initializer 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 +373,6 @@ static bool tomoyo_is_domain_initializer } flag = true; } - up_read(&tomoyo_domain_initializer_list_lock); return flag; } @@ -459,7 +455,7 @@ static int tomoyo_update_domain_keeper_e 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 +475,7 @@ static int tomoyo_update_domain_keeper_e 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); @@ -519,7 +515,6 @@ bool tomoyo_read_domain_keeper_policy(st 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 +537,6 @@ bool tomoyo_read_domain_keeper_policy(st if (!done) break; } - up_read(&tomoyo_domain_keeper_list_lock); return done; } @@ -563,8 +557,7 @@ static bool tomoyo_is_domain_keeper(cons 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 +575,6 @@ static bool tomoyo_is_domain_keeper(cons } flag = true; } - up_read(&tomoyo_domain_keeper_list_lock); return flag; } @@ -646,7 +638,7 @@ static int tomoyo_update_alias_entry(con 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 +655,7 @@ static int tomoyo_update_alias_entry(con 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); @@ -682,7 +674,6 @@ bool tomoyo_read_alias_policy(struct tom 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 +686,6 @@ bool tomoyo_read_alias_policy(struct tom if (!done) break; } - up_read(&tomoyo_alias_list_lock); return done; } @@ -742,7 +732,7 @@ struct tomoyo_domain_info *tomoyo_find_o if (!saved_domainname) goto out; /* Can I reuse memory of deleted domain? */ - list_for_each_entry(domain, &tomoyo_domain_list, list) { + list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { struct task_struct *p; struct tomoyo_acl_info *ptr; bool flag; @@ -760,7 +750,7 @@ struct tomoyo_domain_info *tomoyo_find_o read_unlock(&tasklist_lock); if (flag) continue; - list_for_each_entry(ptr, &domain->acl_info_list, list) { + list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { ptr->type |= TOMOYO_ACL_DELETED; } tomoyo_set_domain_flag(domain, true, domain->flags); @@ -776,7 +766,7 @@ struct tomoyo_domain_info *tomoyo_find_o INIT_LIST_HEAD(&domain->acl_info_list); domain->domainname = saved_domainname; domain->profile = profile; - list_add_tail(&domain->list, &tomoyo_domain_list); + list_add_tail_rcu(&domain->list, &tomoyo_domain_list); } out: up_write(&tomoyo_domain_list_lock); @@ -849,8 +839,7 @@ int tomoyo_find_next_domain(struct linux if (tomoyo_pathcmp(&r, &s)) { struct tomoyo_alias_entry *ptr; /* Is this program allowed to be called via symbolic links? */ - down_read(&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->is_deleted || tomoyo_pathcmp(&r, ptr->original_name) || tomoyo_pathcmp(&s, ptr->aliased_name)) @@ -861,7 +850,6 @@ int tomoyo_find_next_domain(struct linux tomoyo_fill_path_info(&r); break; } - up_read(&tomoyo_alias_list_lock); } /* Check execute permission. */ @@ -892,9 +880,7 @@ int tomoyo_find_next_domain(struct linux } if (domain || strlen(new_domain_name) >= TOMOYO_MAX_PATHNAME_LEN) goto done; - down_read(&tomoyo_domain_list_lock); domain = tomoyo_find_domain(new_domain_name); - up_read(&tomoyo_domain_list_lock); if (domain) goto done; if (is_enforce) --- security-testing-2.6.orig/security/tomoyo/file.c +++ security-testing-2.6/security/tomoyo/file.c @@ -220,7 +220,7 @@ static int tomoyo_update_globally_readab if (!saved_filename) return -ENOMEM; down_write(&tomoyo_globally_readable_list_lock); - list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) { + list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) { if (ptr->filename != saved_filename) continue; ptr->is_deleted = is_delete; @@ -235,7 +235,7 @@ static int tomoyo_update_globally_readab if (!new_entry) goto out; new_entry->filename = saved_filename; - list_add_tail(&new_entry->list, &tomoyo_globally_readable_list); + list_add_tail_rcu(&new_entry->list, &tomoyo_globally_readable_list); error = 0; out: up_write(&tomoyo_globally_readable_list_lock); @@ -254,15 +254,13 @@ static bool tomoyo_is_globally_readable_ { struct tomoyo_globally_readable_file_entry *ptr; bool found = false; - down_read(&tomoyo_globally_readable_list_lock); - list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) { + list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list, list) { if (!ptr->is_deleted && tomoyo_path_matches_pattern(filename, ptr->filename)) { found = true; break; } } - up_read(&tomoyo_globally_readable_list_lock); return found; } @@ -291,7 +289,6 @@ bool tomoyo_read_globally_readable_polic struct list_head *pos; bool done = true; - down_read(&tomoyo_globally_readable_list_lock); list_for_each_cookie(pos, head->read_var2, &tomoyo_globally_readable_list) { struct tomoyo_globally_readable_file_entry *ptr; @@ -305,7 +302,6 @@ bool tomoyo_read_globally_readable_polic if (!done) break; } - up_read(&tomoyo_globally_readable_list_lock); return done; } @@ -363,7 +359,7 @@ static int tomoyo_update_file_pattern_en if (!saved_pattern) return -ENOMEM; down_write(&tomoyo_pattern_list_lock); - list_for_each_entry(ptr, &tomoyo_pattern_list, list) { + list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) { if (saved_pattern != ptr->pattern) continue; ptr->is_deleted = is_delete; @@ -378,7 +374,7 @@ static int tomoyo_update_file_pattern_en if (!new_entry) goto out; new_entry->pattern = saved_pattern; - list_add_tail(&new_entry->list, &tomoyo_pattern_list); + list_add_tail_rcu(&new_entry->list, &tomoyo_pattern_list); error = 0; out: up_write(&tomoyo_pattern_list_lock); @@ -398,8 +394,7 @@ tomoyo_get_file_pattern(const struct tom struct tomoyo_pattern_entry *ptr; const struct tomoyo_path_info *pattern = NULL; - down_read(&tomoyo_pattern_list_lock); - list_for_each_entry(ptr, &tomoyo_pattern_list, list) { + list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) { if (ptr->is_deleted) continue; if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) @@ -412,7 +407,6 @@ tomoyo_get_file_pattern(const struct tom break; } } - up_read(&tomoyo_pattern_list_lock); if (pattern) filename = pattern; return filename; @@ -443,7 +437,6 @@ bool tomoyo_read_file_pattern(struct tom struct list_head *pos; bool done = true; - down_read(&tomoyo_pattern_list_lock); list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) { struct tomoyo_pattern_entry *ptr; ptr = list_entry(pos, struct tomoyo_pattern_entry, list); @@ -454,7 +447,6 @@ bool tomoyo_read_file_pattern(struct tom if (!done) break; } - up_read(&tomoyo_pattern_list_lock); return done; } @@ -511,7 +503,7 @@ static int tomoyo_update_no_rewrite_entr if (!saved_pattern) return -ENOMEM; down_write(&tomoyo_no_rewrite_list_lock); - list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) { + list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) { if (ptr->pattern != saved_pattern) continue; ptr->is_deleted = is_delete; @@ -526,7 +518,7 @@ static int tomoyo_update_no_rewrite_entr if (!new_entry) goto out; new_entry->pattern = saved_pattern; - list_add_tail(&new_entry->list, &tomoyo_no_rewrite_list); + list_add_tail_rcu(&new_entry->list, &tomoyo_no_rewrite_list); error = 0; out: up_write(&tomoyo_no_rewrite_list_lock); @@ -546,8 +538,7 @@ static bool tomoyo_is_no_rewrite_file(co struct tomoyo_no_rewrite_entry *ptr; bool found = false; - down_read(&tomoyo_no_rewrite_list_lock); - list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) { + list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) { if (ptr->is_deleted) continue; if (!tomoyo_path_matches_pattern(filename, ptr->pattern)) @@ -555,7 +546,6 @@ static bool tomoyo_is_no_rewrite_file(co found = true; break; } - up_read(&tomoyo_no_rewrite_list_lock); return found; } @@ -584,7 +574,6 @@ bool tomoyo_read_no_rewrite_policy(struc struct list_head *pos; bool done = true; - down_read(&tomoyo_no_rewrite_list_lock); list_for_each_cookie(pos, head->read_var2, &tomoyo_no_rewrite_list) { struct tomoyo_no_rewrite_entry *ptr; ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list); @@ -595,7 +584,6 @@ bool tomoyo_read_no_rewrite_policy(struc if (!done) break; } - up_read(&tomoyo_no_rewrite_list_lock); return done; } @@ -661,8 +649,7 @@ static int tomoyo_check_single_path_acl2 struct tomoyo_acl_info *ptr; int error = -EPERM; - 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) { struct tomoyo_single_path_acl_record *acl; if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL) continue; @@ -680,7 +667,6 @@ static int tomoyo_check_single_path_acl2 error = 0; break; } - up_read(&tomoyo_domain_acl_info_list_lock); return error; } @@ -848,7 +834,7 @@ static int tomoyo_update_single_path_acl down_write(&tomoyo_domain_acl_info_list_lock); if (is_delete) goto delete; - list_for_each_entry(ptr, &domain->acl_info_list, list) { + list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL) continue; acl = container_of(ptr, struct tomoyo_single_path_acl_record, @@ -875,12 +861,12 @@ static int tomoyo_update_single_path_acl if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL)) acl->perm |= rw_mask; acl->filename = saved_filename; - list_add_tail(&acl->head.list, &domain->acl_info_list); + list_add_tail_rcu(&acl->head.list, &domain->acl_info_list); error = 0; goto out; delete: error = -ENOENT; - list_for_each_entry(ptr, &domain->acl_info_list, list) { + list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL) continue; acl = container_of(ptr, struct tomoyo_single_path_acl_record, @@ -937,7 +923,7 @@ static int tomoyo_update_double_path_acl down_write(&tomoyo_domain_acl_info_list_lock); if (is_delete) goto delete; - list_for_each_entry(ptr, &domain->acl_info_list, list) { + list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL) continue; acl = container_of(ptr, struct tomoyo_double_path_acl_record, @@ -960,12 +946,12 @@ static int tomoyo_update_double_path_acl acl->perm = perm; acl->filename1 = saved_filename1; acl->filename2 = saved_filename2; - list_add_tail(&acl->head.list, &domain->acl_info_list); + list_add_tail_rcu(&acl->head.list, &domain->acl_info_list); error = 0; goto out; delete: error = -ENOENT; - list_for_each_entry(ptr, &domain->acl_info_list, list) { + list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL) continue; acl = container_of(ptr, struct tomoyo_double_path_acl_record, @@ -1025,8 +1011,7 @@ static int tomoyo_check_double_path_acl( if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE)) return 0; - 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) { struct tomoyo_double_path_acl_record *acl; if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL) continue; @@ -1041,7 +1026,6 @@ static int tomoyo_check_double_path_acl( error = 0; break; } - up_read(&tomoyo_domain_acl_info_list_lock); return error; } --- security-testing-2.6.orig/security/tomoyo/realpath.c +++ security-testing-2.6/security/tomoyo/realpath.c @@ -387,11 +387,9 @@ void __init tomoyo_realpath_init(void) INIT_LIST_HEAD(&tomoyo_name_list[i]); INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list); tomoyo_kernel_domain.domainname = tomoyo_save_name(TOMOYO_ROOT_NAME); - list_add_tail(&tomoyo_kernel_domain.list, &tomoyo_domain_list); - down_read(&tomoyo_domain_list_lock); + list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list); if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain) panic("Can't register tomoyo_kernel_domain"); - up_read(&tomoyo_domain_list_lock); } /* Memory allocated for temporary purpose. */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/