Skip to content

Commit

Permalink
tomoyo: Suppress RCU warning at list_for_each_entry_rcu().
Browse files Browse the repository at this point in the history
John Garry has reported that allmodconfig kernel on arm64 causes flood of
"RCU-list traversed in non-reader section!!" warning. I don't know what
change caused this warning, but this warning is safe because TOMOYO uses
SRCU lock instead. Let's suppress this warning by explicitly telling that
the caller is holding SRCU lock.

Reported-and-tested-by: John Garry <john.garry@huawei.com>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
  • Loading branch information
Tetsuo Handa authored and Tetsuo Handa committed Dec 16, 2019
1 parent 6f7c413 commit 6bd5ce6
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 13 deletions.
9 changes: 6 additions & 3 deletions security/tomoyo/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,8 @@ static bool tomoyo_manager(void)
exe = tomoyo_get_exe();
if (!exe)
return false;
list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER], head.list) {
list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER], head.list,
srcu_read_lock_held(&tomoyo_ss)) {
if (!ptr->head.is_deleted &&
(!tomoyo_pathcmp(domainname, ptr->manager) ||
!strcmp(exe, ptr->manager->name))) {
Expand Down Expand Up @@ -1095,7 +1096,8 @@ static int tomoyo_delete_domain(char *domainname)
if (mutex_lock_interruptible(&tomoyo_policy_lock))
return -EINTR;
/* Is there an active domain? */
list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
list_for_each_entry_rcu(domain, &tomoyo_domain_list, list,
srcu_read_lock_held(&tomoyo_ss)) {
/* Never delete tomoyo_kernel_domain */
if (domain == &tomoyo_kernel_domain)
continue;
Expand Down Expand Up @@ -2778,7 +2780,8 @@ void tomoyo_check_profile(void)

tomoyo_policy_loaded = true;
pr_info("TOMOYO: 2.6.0\n");
list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
list_for_each_entry_rcu(domain, &tomoyo_domain_list, list,
srcu_read_lock_held(&tomoyo_ss)) {
const u8 profile = domain->profile;
struct tomoyo_policy_namespace *ns = domain->ns;

Expand Down
15 changes: 10 additions & 5 deletions security/tomoyo/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,

if (mutex_lock_interruptible(&tomoyo_policy_lock))
return -ENOMEM;
list_for_each_entry_rcu(entry, list, list) {
list_for_each_entry_rcu(entry, list, list,
srcu_read_lock_held(&tomoyo_ss)) {
if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS)
continue;
if (!check_duplicate(entry, new_entry))
Expand Down Expand Up @@ -119,7 +120,8 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
}
if (mutex_lock_interruptible(&tomoyo_policy_lock))
goto out;
list_for_each_entry_rcu(entry, list, list) {
list_for_each_entry_rcu(entry, list, list,
srcu_read_lock_held(&tomoyo_ss)) {
if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS)
continue;
if (!tomoyo_same_acl_head(entry, new_entry) ||
Expand Down Expand Up @@ -166,7 +168,8 @@ void tomoyo_check_acl(struct tomoyo_request_info *r,
u16 i = 0;

retry:
list_for_each_entry_rcu(ptr, list, list) {
list_for_each_entry_rcu(ptr, list, list,
srcu_read_lock_held(&tomoyo_ss)) {
if (ptr->is_deleted || ptr->type != r->param_type)
continue;
if (!check_entry(r, ptr))
Expand Down Expand Up @@ -298,7 +301,8 @@ static inline bool tomoyo_scan_transition
{
const struct tomoyo_transition_control *ptr;

list_for_each_entry_rcu(ptr, list, head.list) {
list_for_each_entry_rcu(ptr, list, head.list,
srcu_read_lock_held(&tomoyo_ss)) {
if (ptr->head.is_deleted || ptr->type != type)
continue;
if (ptr->domainname) {
Expand Down Expand Up @@ -735,7 +739,8 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm)

/* Check 'aggregator' directive. */
candidate = &exename;
list_for_each_entry_rcu(ptr, list, head.list) {
list_for_each_entry_rcu(ptr, list, head.list,
srcu_read_lock_held(&tomoyo_ss)) {
if (ptr->head.is_deleted ||
!tomoyo_path_matches_pattern(&exename,
ptr->original_name))
Expand Down
9 changes: 6 additions & 3 deletions security/tomoyo/group.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
{
struct tomoyo_path_group *member;

list_for_each_entry_rcu(member, &group->member_list, head.list) {
list_for_each_entry_rcu(member, &group->member_list, head.list,
srcu_read_lock_held(&tomoyo_ss)) {
if (member->head.is_deleted)
continue;
if (!tomoyo_path_matches_pattern(pathname, member->member_name))
Expand Down Expand Up @@ -161,7 +162,8 @@ bool tomoyo_number_matches_group(const unsigned long min,
struct tomoyo_number_group *member;
bool matched = false;

list_for_each_entry_rcu(member, &group->member_list, head.list) {
list_for_each_entry_rcu(member, &group->member_list, head.list,
srcu_read_lock_held(&tomoyo_ss)) {
if (member->head.is_deleted)
continue;
if (min > member->number.values[1] ||
Expand Down Expand Up @@ -191,7 +193,8 @@ bool tomoyo_address_matches_group(const bool is_ipv6, const __be32 *address,
bool matched = false;
const u8 size = is_ipv6 ? 16 : 4;

list_for_each_entry_rcu(member, &group->member_list, head.list) {
list_for_each_entry_rcu(member, &group->member_list, head.list,
srcu_read_lock_held(&tomoyo_ss)) {
if (member->head.is_deleted)
continue;
if (member->address.is_ipv6 != is_ipv6)
Expand Down
6 changes: 4 additions & 2 deletions security/tomoyo/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,8 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)

name.name = domainname;
tomoyo_fill_path_info(&name);
list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
list_for_each_entry_rcu(domain, &tomoyo_domain_list, list,
srcu_read_lock_held(&tomoyo_ss)) {
if (!domain->is_deleted &&
!tomoyo_pathcmp(&name, domain->domainname))
return domain;
Expand Down Expand Up @@ -1028,7 +1029,8 @@ bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
return false;
if (!domain)
return true;
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list,
srcu_read_lock_held(&tomoyo_ss)) {
u16 perm;
u8 i;

Expand Down

0 comments on commit 6bd5ce6

Please sign in to comment.