aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/tomoyo/gc.c130
1 files changed, 72 insertions, 58 deletions
diff --git a/security/tomoyo/gc.c b/security/tomoyo/gc.c
index d129317ca481..a54bd823fcd5 100644
--- a/security/tomoyo/gc.c
+++ b/security/tomoyo/gc.c
@@ -33,13 +33,13 @@ enum tomoyo_policy_id {
33struct tomoyo_gc_entry { 33struct tomoyo_gc_entry {
34 struct list_head list; 34 struct list_head list;
35 int type; 35 int type;
36 void *element; 36 struct list_head *element;
37}; 37};
38static LIST_HEAD(tomoyo_gc_queue); 38static LIST_HEAD(tomoyo_gc_queue);
39static DEFINE_MUTEX(tomoyo_gc_mutex); 39static DEFINE_MUTEX(tomoyo_gc_mutex);
40 40
41/* Caller holds tomoyo_policy_lock mutex. */ 41/* Caller holds tomoyo_policy_lock mutex. */
42static bool tomoyo_add_to_gc(const int type, void *element) 42static bool tomoyo_add_to_gc(const int type, struct list_head *element)
43{ 43{
44 struct tomoyo_gc_entry *entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 44 struct tomoyo_gc_entry *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
45 if (!entry) 45 if (!entry)
@@ -47,57 +47,74 @@ static bool tomoyo_add_to_gc(const int type, void *element)
47 entry->type = type; 47 entry->type = type;
48 entry->element = element; 48 entry->element = element;
49 list_add(&entry->list, &tomoyo_gc_queue); 49 list_add(&entry->list, &tomoyo_gc_queue);
50 list_del_rcu(element);
50 return true; 51 return true;
51} 52}
52 53
53static void tomoyo_del_allow_read 54static void tomoyo_del_allow_read(struct list_head *element)
54(struct tomoyo_globally_readable_file_entry *ptr)
55{ 55{
56 struct tomoyo_globally_readable_file_entry *ptr =
57 container_of(element, typeof(*ptr), head.list);
56 tomoyo_put_name(ptr->filename); 58 tomoyo_put_name(ptr->filename);
57} 59}
58 60
59static void tomoyo_del_file_pattern(struct tomoyo_pattern_entry *ptr) 61static void tomoyo_del_file_pattern(struct list_head *element)
60{ 62{
63 struct tomoyo_pattern_entry *ptr =
64 container_of(element, typeof(*ptr), head.list);
61 tomoyo_put_name(ptr->pattern); 65 tomoyo_put_name(ptr->pattern);
62} 66}
63 67
64static void tomoyo_del_no_rewrite(struct tomoyo_no_rewrite_entry *ptr) 68static void tomoyo_del_no_rewrite(struct list_head *element)
65{ 69{
70 struct tomoyo_no_rewrite_entry *ptr =
71 container_of(element, typeof(*ptr), head.list);
66 tomoyo_put_name(ptr->pattern); 72 tomoyo_put_name(ptr->pattern);
67} 73}
68 74
69static void tomoyo_del_domain_initializer 75static void tomoyo_del_domain_initializer(struct list_head *element)
70(struct tomoyo_domain_initializer_entry *ptr)
71{ 76{
77 struct tomoyo_domain_initializer_entry *ptr =
78 container_of(element, typeof(*ptr), head.list);
72 tomoyo_put_name(ptr->domainname); 79 tomoyo_put_name(ptr->domainname);
73 tomoyo_put_name(ptr->program); 80 tomoyo_put_name(ptr->program);
74} 81}
75 82
76static void tomoyo_del_domain_keeper(struct tomoyo_domain_keeper_entry *ptr) 83static void tomoyo_del_domain_keeper(struct list_head *element)
77{ 84{
85 struct tomoyo_domain_keeper_entry *ptr =
86 container_of(element, typeof(*ptr), head.list);
78 tomoyo_put_name(ptr->domainname); 87 tomoyo_put_name(ptr->domainname);
79 tomoyo_put_name(ptr->program); 88 tomoyo_put_name(ptr->program);
80} 89}
81 90
82static void tomoyo_del_aggregator(struct tomoyo_aggregator_entry *ptr) 91static void tomoyo_del_aggregator(struct list_head *element)
83{ 92{
93 struct tomoyo_aggregator_entry *ptr =
94 container_of(element, typeof(*ptr), head.list);
84 tomoyo_put_name(ptr->original_name); 95 tomoyo_put_name(ptr->original_name);
85 tomoyo_put_name(ptr->aggregated_name); 96 tomoyo_put_name(ptr->aggregated_name);
86} 97}
87 98
88static void tomoyo_del_alias(struct tomoyo_alias_entry *ptr) 99static void tomoyo_del_alias(struct list_head *element)
89{ 100{
101 struct tomoyo_alias_entry *ptr =
102 container_of(element, typeof(*ptr), head.list);
90 tomoyo_put_name(ptr->original_name); 103 tomoyo_put_name(ptr->original_name);
91 tomoyo_put_name(ptr->aliased_name); 104 tomoyo_put_name(ptr->aliased_name);
92} 105}
93 106
94static void tomoyo_del_manager(struct tomoyo_policy_manager_entry *ptr) 107static void tomoyo_del_manager(struct list_head *element)
95{ 108{
109 struct tomoyo_policy_manager_entry *ptr =
110 container_of(element, typeof(*ptr), head.list);
96 tomoyo_put_name(ptr->manager); 111 tomoyo_put_name(ptr->manager);
97} 112}
98 113
99static void tomoyo_del_acl(struct tomoyo_acl_info *acl) 114static void tomoyo_del_acl(struct list_head *element)
100{ 115{
116 struct tomoyo_acl_info *acl =
117 container_of(element, typeof(*acl), list);
101 switch (acl->type) { 118 switch (acl->type) {
102 case TOMOYO_TYPE_PATH_ACL: 119 case TOMOYO_TYPE_PATH_ACL:
103 { 120 {
@@ -142,14 +159,13 @@ static void tomoyo_del_acl(struct tomoyo_acl_info *acl)
142 tomoyo_put_number_union(&entry->flags); 159 tomoyo_put_number_union(&entry->flags);
143 } 160 }
144 break; 161 break;
145 default:
146 printk(KERN_WARNING "Unknown type\n");
147 break;
148 } 162 }
149} 163}
150 164
151static bool tomoyo_del_domain(struct tomoyo_domain_info *domain) 165static bool tomoyo_del_domain(struct list_head *element)
152{ 166{
167 struct tomoyo_domain_info *domain =
168 container_of(element, typeof(*domain), list);
153 struct tomoyo_acl_info *acl; 169 struct tomoyo_acl_info *acl;
154 struct tomoyo_acl_info *tmp; 170 struct tomoyo_acl_info *tmp;
155 /* 171 /*
@@ -177,7 +193,7 @@ static bool tomoyo_del_domain(struct tomoyo_domain_info *domain)
177 if (atomic_read(&domain->users)) 193 if (atomic_read(&domain->users))
178 return false; 194 return false;
179 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) { 195 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
180 tomoyo_del_acl(acl); 196 tomoyo_del_acl(&acl->list);
181 tomoyo_memory_free(acl); 197 tomoyo_memory_free(acl);
182 } 198 }
183 tomoyo_put_name(domain->domainname); 199 tomoyo_put_name(domain->domainname);
@@ -185,28 +201,36 @@ static bool tomoyo_del_domain(struct tomoyo_domain_info *domain)
185} 201}
186 202
187 203
188static void tomoyo_del_name(const struct tomoyo_name_entry *ptr) 204static void tomoyo_del_name(struct list_head *element)
189{ 205{
206 const struct tomoyo_name_entry *ptr =
207 container_of(element, typeof(*ptr), list);
190} 208}
191 209
192static void tomoyo_del_path_group_member(struct tomoyo_path_group_member 210static void tomoyo_del_path_group_member(struct list_head *element)
193 *member)
194{ 211{
212 struct tomoyo_path_group_member *member =
213 container_of(element, typeof(*member), head.list);
195 tomoyo_put_name(member->member_name); 214 tomoyo_put_name(member->member_name);
196} 215}
197 216
198static void tomoyo_del_path_group(struct tomoyo_path_group *group) 217static void tomoyo_del_path_group(struct list_head *element)
199{ 218{
219 struct tomoyo_path_group *group =
220 container_of(element, typeof(*group), list);
200 tomoyo_put_name(group->group_name); 221 tomoyo_put_name(group->group_name);
201} 222}
202 223
203static void tomoyo_del_number_group_member(struct tomoyo_number_group_member 224static void tomoyo_del_number_group_member(struct list_head *element)
204 *member)
205{ 225{
226 struct tomoyo_number_group_member *member =
227 container_of(element, typeof(*member), head.list);
206} 228}
207 229
208static void tomoyo_del_number_group(struct tomoyo_number_group *group) 230static void tomoyo_del_number_group(struct list_head *element)
209{ 231{
232 struct tomoyo_number_group *group =
233 container_of(element, typeof(*group), list);
210 tomoyo_put_name(group->group_name); 234 tomoyo_put_name(group->group_name);
211} 235}
212 236
@@ -229,7 +253,6 @@ static bool tomoyo_collect_member(struct list_head *member_list, int id)
229 continue; 253 continue;
230 if (!tomoyo_add_to_gc(id, &member->list)) 254 if (!tomoyo_add_to_gc(id, &member->list))
231 return false; 255 return false;
232 list_del_rcu(&member->list);
233 } 256 }
234 return true; 257 return true;
235} 258}
@@ -242,7 +265,6 @@ static bool tomoyo_collect_acl(struct tomoyo_domain_info *domain)
242 continue; 265 continue;
243 if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list)) 266 if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list))
244 return false; 267 return false;
245 list_del_rcu(&acl->list);
246 } 268 }
247 return true; 269 return true;
248} 270}
@@ -269,9 +291,7 @@ static void tomoyo_collect_entry(void)
269 * refer this domain after successful execve(). 291 * refer this domain after successful execve().
270 * We recheck domain->users after SRCU synchronization. 292 * We recheck domain->users after SRCU synchronization.
271 */ 293 */
272 if (tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, domain)) 294 if (!tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, &domain->list))
273 list_del_rcu(&domain->list);
274 else
275 goto unlock; 295 goto unlock;
276 } 296 }
277 } 297 }
@@ -280,9 +300,7 @@ static void tomoyo_collect_entry(void)
280 list_for_each_entry_rcu(ptr, &tomoyo_name_list[i], list) { 300 list_for_each_entry_rcu(ptr, &tomoyo_name_list[i], list) {
281 if (atomic_read(&ptr->users)) 301 if (atomic_read(&ptr->users))
282 continue; 302 continue;
283 if (tomoyo_add_to_gc(TOMOYO_ID_NAME, ptr)) 303 if (!tomoyo_add_to_gc(TOMOYO_ID_NAME, &ptr->list))
284 list_del_rcu(&ptr->list);
285 else
286 goto unlock; 304 goto unlock;
287 } 305 }
288 } 306 }
@@ -294,9 +312,8 @@ static void tomoyo_collect_entry(void)
294 if (!list_empty(&group->member_list) || 312 if (!list_empty(&group->member_list) ||
295 atomic_read(&group->users)) 313 atomic_read(&group->users))
296 continue; 314 continue;
297 if (tomoyo_add_to_gc(TOMOYO_ID_PATH_GROUP, group)) 315 if (!tomoyo_add_to_gc(TOMOYO_ID_PATH_GROUP,
298 list_del_rcu(&group->list); 316 &group->list))
299 else
300 goto unlock; 317 goto unlock;
301 } 318 }
302 } 319 }
@@ -309,9 +326,8 @@ static void tomoyo_collect_entry(void)
309 if (!list_empty(&group->member_list) || 326 if (!list_empty(&group->member_list) ||
310 atomic_read(&group->users)) 327 atomic_read(&group->users))
311 continue; 328 continue;
312 if (tomoyo_add_to_gc(TOMOYO_ID_NUMBER_GROUP, group)) 329 if (!tomoyo_add_to_gc(TOMOYO_ID_NUMBER_GROUP,
313 list_del_rcu(&group->list); 330 &group->list))
314 else
315 goto unlock; 331 goto unlock;
316 } 332 }
317 } 333 }
@@ -325,58 +341,56 @@ static void tomoyo_kfree_entry(void)
325 struct tomoyo_gc_entry *tmp; 341 struct tomoyo_gc_entry *tmp;
326 342
327 list_for_each_entry_safe(p, tmp, &tomoyo_gc_queue, list) { 343 list_for_each_entry_safe(p, tmp, &tomoyo_gc_queue, list) {
344 struct list_head *element = p->element;
328 switch (p->type) { 345 switch (p->type) {
329 case TOMOYO_ID_DOMAIN_INITIALIZER: 346 case TOMOYO_ID_DOMAIN_INITIALIZER:
330 tomoyo_del_domain_initializer(p->element); 347 tomoyo_del_domain_initializer(element);
331 break; 348 break;
332 case TOMOYO_ID_DOMAIN_KEEPER: 349 case TOMOYO_ID_DOMAIN_KEEPER:
333 tomoyo_del_domain_keeper(p->element); 350 tomoyo_del_domain_keeper(element);
334 break; 351 break;
335 case TOMOYO_ID_AGGREGATOR: 352 case TOMOYO_ID_AGGREGATOR:
336 tomoyo_del_aggregator(p->element); 353 tomoyo_del_aggregator(element);
337 break; 354 break;
338 case TOMOYO_ID_ALIAS: 355 case TOMOYO_ID_ALIAS:
339 tomoyo_del_alias(p->element); 356 tomoyo_del_alias(element);
340 break; 357 break;
341 case TOMOYO_ID_GLOBALLY_READABLE: 358 case TOMOYO_ID_GLOBALLY_READABLE:
342 tomoyo_del_allow_read(p->element); 359 tomoyo_del_allow_read(element);
343 break; 360 break;
344 case TOMOYO_ID_PATTERN: 361 case TOMOYO_ID_PATTERN:
345 tomoyo_del_file_pattern(p->element); 362 tomoyo_del_file_pattern(element);
346 break; 363 break;
347 case TOMOYO_ID_NO_REWRITE: 364 case TOMOYO_ID_NO_REWRITE:
348 tomoyo_del_no_rewrite(p->element); 365 tomoyo_del_no_rewrite(element);
349 break; 366 break;
350 case TOMOYO_ID_MANAGER: 367 case TOMOYO_ID_MANAGER:
351 tomoyo_del_manager(p->element); 368 tomoyo_del_manager(element);
352 break; 369 break;
353 case TOMOYO_ID_NAME: 370 case TOMOYO_ID_NAME:
354 tomoyo_del_name(p->element); 371 tomoyo_del_name(element);
355 break; 372 break;
356 case TOMOYO_ID_ACL: 373 case TOMOYO_ID_ACL:
357 tomoyo_del_acl(p->element); 374 tomoyo_del_acl(element);
358 break; 375 break;
359 case TOMOYO_ID_DOMAIN: 376 case TOMOYO_ID_DOMAIN:
360 if (!tomoyo_del_domain(p->element)) 377 if (!tomoyo_del_domain(element))
361 continue; 378 continue;
362 break; 379 break;
363 case TOMOYO_ID_PATH_GROUP_MEMBER: 380 case TOMOYO_ID_PATH_GROUP_MEMBER:
364 tomoyo_del_path_group_member(p->element); 381 tomoyo_del_path_group_member(element);
365 break; 382 break;
366 case TOMOYO_ID_PATH_GROUP: 383 case TOMOYO_ID_PATH_GROUP:
367 tomoyo_del_path_group(p->element); 384 tomoyo_del_path_group(element);
368 break; 385 break;
369 case TOMOYO_ID_NUMBER_GROUP_MEMBER: 386 case TOMOYO_ID_NUMBER_GROUP_MEMBER:
370 tomoyo_del_number_group_member(p->element); 387 tomoyo_del_number_group_member(element);
371 break; 388 break;
372 case TOMOYO_ID_NUMBER_GROUP: 389 case TOMOYO_ID_NUMBER_GROUP:
373 tomoyo_del_number_group(p->element); 390 tomoyo_del_number_group(element);
374 break;
375 default:
376 printk(KERN_WARNING "Unknown type\n");
377 break; 391 break;
378 } 392 }
379 tomoyo_memory_free(p->element); 393 tomoyo_memory_free(element);
380 list_del(&p->list); 394 list_del(&p->list);
381 kfree(p); 395 kfree(p);
382 } 396 }