Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tomoyo: Suppress RCU warning at list_for_each_entry_rcu().

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>

+26 -13
+6 -3
security/tomoyo/common.c
··· 951 951 exe = tomoyo_get_exe(); 952 952 if (!exe) 953 953 return false; 954 - list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER], head.list) { 954 + list_for_each_entry_rcu(ptr, &tomoyo_kernel_namespace.policy_list[TOMOYO_ID_MANAGER], head.list, 955 + srcu_read_lock_held(&tomoyo_ss)) { 955 956 if (!ptr->head.is_deleted && 956 957 (!tomoyo_pathcmp(domainname, ptr->manager) || 957 958 !strcmp(exe, ptr->manager->name))) { ··· 1096 1095 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 1097 1096 return -EINTR; 1098 1097 /* Is there an active domain? */ 1099 - list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 1098 + list_for_each_entry_rcu(domain, &tomoyo_domain_list, list, 1099 + srcu_read_lock_held(&tomoyo_ss)) { 1100 1100 /* Never delete tomoyo_kernel_domain */ 1101 1101 if (domain == &tomoyo_kernel_domain) 1102 1102 continue; ··· 2780 2778 2781 2779 tomoyo_policy_loaded = true; 2782 2780 pr_info("TOMOYO: 2.6.0\n"); 2783 - list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 2781 + list_for_each_entry_rcu(domain, &tomoyo_domain_list, list, 2782 + srcu_read_lock_held(&tomoyo_ss)) { 2784 2783 const u8 profile = domain->profile; 2785 2784 struct tomoyo_policy_namespace *ns = domain->ns; 2786 2785
+10 -5
security/tomoyo/domain.c
··· 41 41 42 42 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 43 43 return -ENOMEM; 44 - list_for_each_entry_rcu(entry, list, list) { 44 + list_for_each_entry_rcu(entry, list, list, 45 + srcu_read_lock_held(&tomoyo_ss)) { 45 46 if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS) 46 47 continue; 47 48 if (!check_duplicate(entry, new_entry)) ··· 120 119 } 121 120 if (mutex_lock_interruptible(&tomoyo_policy_lock)) 122 121 goto out; 123 - list_for_each_entry_rcu(entry, list, list) { 122 + list_for_each_entry_rcu(entry, list, list, 123 + srcu_read_lock_held(&tomoyo_ss)) { 124 124 if (entry->is_deleted == TOMOYO_GC_IN_PROGRESS) 125 125 continue; 126 126 if (!tomoyo_same_acl_head(entry, new_entry) || ··· 168 166 u16 i = 0; 169 167 170 168 retry: 171 - list_for_each_entry_rcu(ptr, list, list) { 169 + list_for_each_entry_rcu(ptr, list, list, 170 + srcu_read_lock_held(&tomoyo_ss)) { 172 171 if (ptr->is_deleted || ptr->type != r->param_type) 173 172 continue; 174 173 if (!check_entry(r, ptr)) ··· 301 298 { 302 299 const struct tomoyo_transition_control *ptr; 303 300 304 - list_for_each_entry_rcu(ptr, list, head.list) { 301 + list_for_each_entry_rcu(ptr, list, head.list, 302 + srcu_read_lock_held(&tomoyo_ss)) { 305 303 if (ptr->head.is_deleted || ptr->type != type) 306 304 continue; 307 305 if (ptr->domainname) { ··· 739 735 740 736 /* Check 'aggregator' directive. */ 741 737 candidate = &exename; 742 - list_for_each_entry_rcu(ptr, list, head.list) { 738 + list_for_each_entry_rcu(ptr, list, head.list, 739 + srcu_read_lock_held(&tomoyo_ss)) { 743 740 if (ptr->head.is_deleted || 744 741 !tomoyo_path_matches_pattern(&exename, 745 742 ptr->original_name))
+6 -3
security/tomoyo/group.c
··· 133 133 { 134 134 struct tomoyo_path_group *member; 135 135 136 - list_for_each_entry_rcu(member, &group->member_list, head.list) { 136 + list_for_each_entry_rcu(member, &group->member_list, head.list, 137 + srcu_read_lock_held(&tomoyo_ss)) { 137 138 if (member->head.is_deleted) 138 139 continue; 139 140 if (!tomoyo_path_matches_pattern(pathname, member->member_name)) ··· 162 161 struct tomoyo_number_group *member; 163 162 bool matched = false; 164 163 165 - list_for_each_entry_rcu(member, &group->member_list, head.list) { 164 + list_for_each_entry_rcu(member, &group->member_list, head.list, 165 + srcu_read_lock_held(&tomoyo_ss)) { 166 166 if (member->head.is_deleted) 167 167 continue; 168 168 if (min > member->number.values[1] || ··· 193 191 bool matched = false; 194 192 const u8 size = is_ipv6 ? 16 : 4; 195 193 196 - list_for_each_entry_rcu(member, &group->member_list, head.list) { 194 + list_for_each_entry_rcu(member, &group->member_list, head.list, 195 + srcu_read_lock_held(&tomoyo_ss)) { 197 196 if (member->head.is_deleted) 198 197 continue; 199 198 if (member->address.is_ipv6 != is_ipv6)
+4 -2
security/tomoyo/util.c
··· 594 594 595 595 name.name = domainname; 596 596 tomoyo_fill_path_info(&name); 597 - list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) { 597 + list_for_each_entry_rcu(domain, &tomoyo_domain_list, list, 598 + srcu_read_lock_held(&tomoyo_ss)) { 598 599 if (!domain->is_deleted && 599 600 !tomoyo_pathcmp(&name, domain->domainname)) 600 601 return domain; ··· 1029 1028 return false; 1030 1029 if (!domain) 1031 1030 return true; 1032 - list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) { 1031 + list_for_each_entry_rcu(ptr, &domain->acl_info_list, list, 1032 + srcu_read_lock_held(&tomoyo_ss)) { 1033 1033 u16 perm; 1034 1034 u8 i; 1035 1035