diff options
Diffstat (limited to 'security/tomoyo/gc.c')
-rw-r--r-- | security/tomoyo/gc.c | 130 |
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 { | |||
33 | struct tomoyo_gc_entry { | 33 | struct 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 | }; |
38 | static LIST_HEAD(tomoyo_gc_queue); | 38 | static LIST_HEAD(tomoyo_gc_queue); |
39 | static DEFINE_MUTEX(tomoyo_gc_mutex); | 39 | static DEFINE_MUTEX(tomoyo_gc_mutex); |
40 | 40 | ||
41 | /* Caller holds tomoyo_policy_lock mutex. */ | 41 | /* Caller holds tomoyo_policy_lock mutex. */ |
42 | static bool tomoyo_add_to_gc(const int type, void *element) | 42 | static 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 | ||
53 | static void tomoyo_del_allow_read | 54 | static 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 | ||
59 | static void tomoyo_del_file_pattern(struct tomoyo_pattern_entry *ptr) | 61 | static 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 | ||
64 | static void tomoyo_del_no_rewrite(struct tomoyo_no_rewrite_entry *ptr) | 68 | static 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 | ||
69 | static void tomoyo_del_domain_initializer | 75 | static 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 | ||
76 | static void tomoyo_del_domain_keeper(struct tomoyo_domain_keeper_entry *ptr) | 83 | static 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 | ||
82 | static void tomoyo_del_aggregator(struct tomoyo_aggregator_entry *ptr) | 91 | static 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 | ||
88 | static void tomoyo_del_alias(struct tomoyo_alias_entry *ptr) | 99 | static 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 | ||
94 | static void tomoyo_del_manager(struct tomoyo_policy_manager_entry *ptr) | 107 | static 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 | ||
99 | static void tomoyo_del_acl(struct tomoyo_acl_info *acl) | 114 | static 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 | ||
151 | static bool tomoyo_del_domain(struct tomoyo_domain_info *domain) | 165 | static 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 | ||
188 | static void tomoyo_del_name(const struct tomoyo_name_entry *ptr) | 204 | static 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 | ||
192 | static void tomoyo_del_path_group_member(struct tomoyo_path_group_member | 210 | static 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 | ||
198 | static void tomoyo_del_path_group(struct tomoyo_path_group *group) | 217 | static 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 | ||
203 | static void tomoyo_del_number_group_member(struct tomoyo_number_group_member | 224 | static 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 | ||
208 | static void tomoyo_del_number_group(struct tomoyo_number_group *group) | 230 | static 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 | } |