TOMOYO: Add socket operation restriction support.
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / security / tomoyo / gc.c
blob7747ceb9a2214350c43aebaad5ef5da2c11cccbb
1 /*
2 * security/tomoyo/gc.c
4 * Copyright (C) 2005-2011 NTT DATA CORPORATION
5 */
7 #include "common.h"
8 #include <linux/kthread.h>
9 #include <linux/slab.h>
11 /* The list for "struct tomoyo_io_buffer". */
12 static LIST_HEAD(tomoyo_io_buffer_list);
13 /* Lock for protecting tomoyo_io_buffer_list. */
14 static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock);
16 /* Size of an element. */
17 static const u8 tomoyo_element_size[TOMOYO_MAX_POLICY] = {
18 [TOMOYO_ID_GROUP] = sizeof(struct tomoyo_group),
19 [TOMOYO_ID_ADDRESS_GROUP] = sizeof(struct tomoyo_address_group),
20 [TOMOYO_ID_PATH_GROUP] = sizeof(struct tomoyo_path_group),
21 [TOMOYO_ID_NUMBER_GROUP] = sizeof(struct tomoyo_number_group),
22 [TOMOYO_ID_AGGREGATOR] = sizeof(struct tomoyo_aggregator),
23 [TOMOYO_ID_TRANSITION_CONTROL] =
24 sizeof(struct tomoyo_transition_control),
25 [TOMOYO_ID_MANAGER] = sizeof(struct tomoyo_manager),
26 /* [TOMOYO_ID_CONDITION] = "struct tomoyo_condition"->size, */
27 /* [TOMOYO_ID_NAME] = "struct tomoyo_name"->size, */
28 /* [TOMOYO_ID_ACL] =
29 tomoyo_acl_size["struct tomoyo_acl_info"->type], */
30 [TOMOYO_ID_DOMAIN] = sizeof(struct tomoyo_domain_info),
33 /* Size of a domain ACL element. */
34 static const u8 tomoyo_acl_size[] = {
35 [TOMOYO_TYPE_PATH_ACL] = sizeof(struct tomoyo_path_acl),
36 [TOMOYO_TYPE_PATH2_ACL] = sizeof(struct tomoyo_path2_acl),
37 [TOMOYO_TYPE_PATH_NUMBER_ACL] = sizeof(struct tomoyo_path_number_acl),
38 [TOMOYO_TYPE_MKDEV_ACL] = sizeof(struct tomoyo_mkdev_acl),
39 [TOMOYO_TYPE_MOUNT_ACL] = sizeof(struct tomoyo_mount_acl),
40 [TOMOYO_TYPE_INET_ACL] = sizeof(struct tomoyo_inet_acl),
41 [TOMOYO_TYPE_UNIX_ACL] = sizeof(struct tomoyo_unix_acl),
42 [TOMOYO_TYPE_ENV_ACL] = sizeof(struct tomoyo_env_acl),
45 /**
46 * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not.
48 * @element: Pointer to "struct list_head".
50 * Returns true if @element is used by /sys/kernel/security/tomoyo/ users,
51 * false otherwise.
53 static bool tomoyo_struct_used_by_io_buffer(const struct list_head *element)
55 struct tomoyo_io_buffer *head;
56 bool in_use = false;
58 spin_lock(&tomoyo_io_buffer_list_lock);
59 list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
60 head->users++;
61 spin_unlock(&tomoyo_io_buffer_list_lock);
62 if (mutex_lock_interruptible(&head->io_sem)) {
63 in_use = true;
64 goto out;
66 if (head->r.domain == element || head->r.group == element ||
67 head->r.acl == element || &head->w.domain->list == element)
68 in_use = true;
69 mutex_unlock(&head->io_sem);
70 out:
71 spin_lock(&tomoyo_io_buffer_list_lock);
72 head->users--;
73 if (in_use)
74 break;
76 spin_unlock(&tomoyo_io_buffer_list_lock);
77 return in_use;
80 /**
81 * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not.
83 * @string: String to check.
84 * @size: Memory allocated for @string .
86 * Returns true if @string is used by /sys/kernel/security/tomoyo/ users,
87 * false otherwise.
89 static bool tomoyo_name_used_by_io_buffer(const char *string,
90 const size_t size)
92 struct tomoyo_io_buffer *head;
93 bool in_use = false;
95 spin_lock(&tomoyo_io_buffer_list_lock);
96 list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
97 int i;
98 head->users++;
99 spin_unlock(&tomoyo_io_buffer_list_lock);
100 if (mutex_lock_interruptible(&head->io_sem)) {
101 in_use = true;
102 goto out;
104 for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) {
105 const char *w = head->r.w[i];
106 if (w < string || w > string + size)
107 continue;
108 in_use = true;
109 break;
111 mutex_unlock(&head->io_sem);
112 out:
113 spin_lock(&tomoyo_io_buffer_list_lock);
114 head->users--;
115 if (in_use)
116 break;
118 spin_unlock(&tomoyo_io_buffer_list_lock);
119 return in_use;
122 /* Structure for garbage collection. */
123 struct tomoyo_gc {
124 struct list_head list;
125 enum tomoyo_policy_id type;
126 size_t size;
127 struct list_head *element;
129 /* List of entries to be deleted. */
130 static LIST_HEAD(tomoyo_gc_list);
131 /* Length of tomoyo_gc_list. */
132 static int tomoyo_gc_list_len;
135 * tomoyo_add_to_gc - Add an entry to to be deleted list.
137 * @type: One of values in "enum tomoyo_policy_id".
138 * @element: Pointer to "struct list_head".
140 * Returns true on success, false otherwise.
142 * Caller holds tomoyo_policy_lock mutex.
144 * Adding an entry needs kmalloc(). Thus, if we try to add thousands of
145 * entries at once, it will take too long time. Thus, do not add more than 128
146 * entries per a scan. But to be able to handle worst case where all entries
147 * are in-use, we accept one more entry per a scan.
149 * If we use singly linked list using "struct list_head"->prev (which is
150 * LIST_POISON2), we can avoid kmalloc().
152 static bool tomoyo_add_to_gc(const int type, struct list_head *element)
154 struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
155 if (!entry)
156 return false;
157 entry->type = type;
158 if (type == TOMOYO_ID_ACL)
159 entry->size = tomoyo_acl_size[
160 container_of(element,
161 typeof(struct tomoyo_acl_info),
162 list)->type];
163 else if (type == TOMOYO_ID_NAME)
164 entry->size = strlen(container_of(element,
165 typeof(struct tomoyo_name),
166 head.list)->entry.name) + 1;
167 else if (type == TOMOYO_ID_CONDITION)
168 entry->size =
169 container_of(element, typeof(struct tomoyo_condition),
170 head.list)->size;
171 else
172 entry->size = tomoyo_element_size[type];
173 entry->element = element;
174 list_add(&entry->list, &tomoyo_gc_list);
175 list_del_rcu(element);
176 return tomoyo_gc_list_len++ < 128;
180 * tomoyo_element_linked_by_gc - Validate next element of an entry.
182 * @element: Pointer to an element.
183 * @size: Size of @element in byte.
185 * Returns true if @element is linked by other elements in the garbage
186 * collector's queue, false otherwise.
188 static bool tomoyo_element_linked_by_gc(const u8 *element, const size_t size)
190 struct tomoyo_gc *p;
191 list_for_each_entry(p, &tomoyo_gc_list, list) {
192 const u8 *ptr = (const u8 *) p->element->next;
193 if (ptr < element || element + size < ptr)
194 continue;
195 return true;
197 return false;
201 * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control".
203 * @element: Pointer to "struct list_head".
205 * Returns nothing.
207 static void tomoyo_del_transition_control(struct list_head *element)
209 struct tomoyo_transition_control *ptr =
210 container_of(element, typeof(*ptr), head.list);
211 tomoyo_put_name(ptr->domainname);
212 tomoyo_put_name(ptr->program);
216 * tomoyo_del_aggregator - Delete members in "struct tomoyo_aggregator".
218 * @element: Pointer to "struct list_head".
220 * Returns nothing.
222 static void tomoyo_del_aggregator(struct list_head *element)
224 struct tomoyo_aggregator *ptr =
225 container_of(element, typeof(*ptr), head.list);
226 tomoyo_put_name(ptr->original_name);
227 tomoyo_put_name(ptr->aggregated_name);
231 * tomoyo_del_manager - Delete members in "struct tomoyo_manager".
233 * @element: Pointer to "struct list_head".
235 * Returns nothing.
237 static void tomoyo_del_manager(struct list_head *element)
239 struct tomoyo_manager *ptr =
240 container_of(element, typeof(*ptr), head.list);
241 tomoyo_put_name(ptr->manager);
245 * tomoyo_del_acl - Delete members in "struct tomoyo_acl_info".
247 * @element: Pointer to "struct list_head".
249 * Returns nothing.
251 static void tomoyo_del_acl(struct list_head *element)
253 struct tomoyo_acl_info *acl =
254 container_of(element, typeof(*acl), list);
255 tomoyo_put_condition(acl->cond);
256 switch (acl->type) {
257 case TOMOYO_TYPE_PATH_ACL:
259 struct tomoyo_path_acl *entry
260 = container_of(acl, typeof(*entry), head);
261 tomoyo_put_name_union(&entry->name);
263 break;
264 case TOMOYO_TYPE_PATH2_ACL:
266 struct tomoyo_path2_acl *entry
267 = container_of(acl, typeof(*entry), head);
268 tomoyo_put_name_union(&entry->name1);
269 tomoyo_put_name_union(&entry->name2);
271 break;
272 case TOMOYO_TYPE_PATH_NUMBER_ACL:
274 struct tomoyo_path_number_acl *entry
275 = container_of(acl, typeof(*entry), head);
276 tomoyo_put_name_union(&entry->name);
277 tomoyo_put_number_union(&entry->number);
279 break;
280 case TOMOYO_TYPE_MKDEV_ACL:
282 struct tomoyo_mkdev_acl *entry
283 = container_of(acl, typeof(*entry), head);
284 tomoyo_put_name_union(&entry->name);
285 tomoyo_put_number_union(&entry->mode);
286 tomoyo_put_number_union(&entry->major);
287 tomoyo_put_number_union(&entry->minor);
289 break;
290 case TOMOYO_TYPE_MOUNT_ACL:
292 struct tomoyo_mount_acl *entry
293 = container_of(acl, typeof(*entry), head);
294 tomoyo_put_name_union(&entry->dev_name);
295 tomoyo_put_name_union(&entry->dir_name);
296 tomoyo_put_name_union(&entry->fs_type);
297 tomoyo_put_number_union(&entry->flags);
299 break;
300 case TOMOYO_TYPE_ENV_ACL:
302 struct tomoyo_env_acl *entry =
303 container_of(acl, typeof(*entry), head);
305 tomoyo_put_name(entry->env);
307 break;
308 case TOMOYO_TYPE_INET_ACL:
310 struct tomoyo_inet_acl *entry =
311 container_of(acl, typeof(*entry), head);
313 tomoyo_put_group(entry->address.group);
314 tomoyo_put_number_union(&entry->port);
316 break;
317 case TOMOYO_TYPE_UNIX_ACL:
319 struct tomoyo_unix_acl *entry =
320 container_of(acl, typeof(*entry), head);
322 tomoyo_put_name_union(&entry->name);
324 break;
329 * tomoyo_del_domain - Delete members in "struct tomoyo_domain_info".
331 * @element: Pointer to "struct list_head".
333 * Returns true if deleted, false otherwise.
335 static bool tomoyo_del_domain(struct list_head *element)
337 struct tomoyo_domain_info *domain =
338 container_of(element, typeof(*domain), list);
339 struct tomoyo_acl_info *acl;
340 struct tomoyo_acl_info *tmp;
342 * Since we don't protect whole execve() operation using SRCU,
343 * we need to recheck domain->users at this point.
345 * (1) Reader starts SRCU section upon execve().
346 * (2) Reader traverses tomoyo_domain_list and finds this domain.
347 * (3) Writer marks this domain as deleted.
348 * (4) Garbage collector removes this domain from tomoyo_domain_list
349 * because this domain is marked as deleted and used by nobody.
350 * (5) Reader saves reference to this domain into
351 * "struct linux_binprm"->cred->security .
352 * (6) Reader finishes SRCU section, although execve() operation has
353 * not finished yet.
354 * (7) Garbage collector waits for SRCU synchronization.
355 * (8) Garbage collector kfree() this domain because this domain is
356 * used by nobody.
357 * (9) Reader finishes execve() operation and restores this domain from
358 * "struct linux_binprm"->cred->security.
360 * By updating domain->users at (5), we can solve this race problem
361 * by rechecking domain->users at (8).
363 if (atomic_read(&domain->users))
364 return false;
365 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
366 tomoyo_del_acl(&acl->list);
367 tomoyo_memory_free(acl);
369 tomoyo_put_name(domain->domainname);
370 return true;
374 * tomoyo_del_condition - Delete members in "struct tomoyo_condition".
376 * @element: Pointer to "struct list_head".
378 * Returns nothing.
380 void tomoyo_del_condition(struct list_head *element)
382 struct tomoyo_condition *cond = container_of(element, typeof(*cond),
383 head.list);
384 const u16 condc = cond->condc;
385 const u16 numbers_count = cond->numbers_count;
386 const u16 names_count = cond->names_count;
387 const u16 argc = cond->argc;
388 const u16 envc = cond->envc;
389 unsigned int i;
390 const struct tomoyo_condition_element *condp
391 = (const struct tomoyo_condition_element *) (cond + 1);
392 struct tomoyo_number_union *numbers_p
393 = (struct tomoyo_number_union *) (condp + condc);
394 struct tomoyo_name_union *names_p
395 = (struct tomoyo_name_union *) (numbers_p + numbers_count);
396 const struct tomoyo_argv *argv
397 = (const struct tomoyo_argv *) (names_p + names_count);
398 const struct tomoyo_envp *envp
399 = (const struct tomoyo_envp *) (argv + argc);
400 for (i = 0; i < numbers_count; i++)
401 tomoyo_put_number_union(numbers_p++);
402 for (i = 0; i < names_count; i++)
403 tomoyo_put_name_union(names_p++);
404 for (i = 0; i < argc; argv++, i++)
405 tomoyo_put_name(argv->value);
406 for (i = 0; i < envc; envp++, i++) {
407 tomoyo_put_name(envp->name);
408 tomoyo_put_name(envp->value);
413 * tomoyo_del_name - Delete members in "struct tomoyo_name".
415 * @element: Pointer to "struct list_head".
417 * Returns nothing.
419 static void tomoyo_del_name(struct list_head *element)
421 const struct tomoyo_name *ptr =
422 container_of(element, typeof(*ptr), head.list);
426 * tomoyo_del_path_group - Delete members in "struct tomoyo_path_group".
428 * @element: Pointer to "struct list_head".
430 * Returns nothing.
432 static void tomoyo_del_path_group(struct list_head *element)
434 struct tomoyo_path_group *member =
435 container_of(element, typeof(*member), head.list);
436 tomoyo_put_name(member->member_name);
440 * tomoyo_del_group - Delete "struct tomoyo_group".
442 * @element: Pointer to "struct list_head".
444 * Returns nothing.
446 static void tomoyo_del_group(struct list_head *element)
448 struct tomoyo_group *group =
449 container_of(element, typeof(*group), head.list);
450 tomoyo_put_name(group->group_name);
454 * tomoyo_del_address_group - Delete members in "struct tomoyo_address_group".
456 * @element: Pointer to "struct list_head".
458 * Returns nothing.
460 static inline void tomoyo_del_address_group(struct list_head *element)
462 /* Nothing to do. */
466 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group".
468 * @element: Pointer to "struct list_head".
470 * Returns nothing.
472 static void tomoyo_del_number_group(struct list_head *element)
474 struct tomoyo_number_group *member =
475 container_of(element, typeof(*member), head.list);
479 * tomoyo_collect_member - Delete elements with "struct tomoyo_acl_head".
481 * @id: One of values in "enum tomoyo_policy_id".
482 * @member_list: Pointer to "struct list_head".
484 * Returns true if some elements are deleted, false otherwise.
486 static bool tomoyo_collect_member(const enum tomoyo_policy_id id,
487 struct list_head *member_list)
489 struct tomoyo_acl_head *member;
490 list_for_each_entry(member, member_list, list) {
491 if (!member->is_deleted)
492 continue;
493 if (!tomoyo_add_to_gc(id, &member->list))
494 return false;
496 return true;
500 * tomoyo_collect_acl - Delete elements in "struct tomoyo_domain_info".
502 * @list: Pointer to "struct list_head".
504 * Returns true if some elements are deleted, false otherwise.
506 static bool tomoyo_collect_acl(struct list_head *list)
508 struct tomoyo_acl_info *acl;
509 list_for_each_entry(acl, list, list) {
510 if (!acl->is_deleted)
511 continue;
512 if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list))
513 return false;
515 return true;
519 * tomoyo_collect_entry - Scan lists for deleted elements.
521 * Returns nothing.
523 static void tomoyo_collect_entry(void)
525 int i;
526 enum tomoyo_policy_id id;
527 struct tomoyo_policy_namespace *ns;
528 int idx;
529 if (mutex_lock_interruptible(&tomoyo_policy_lock))
530 return;
531 idx = tomoyo_read_lock();
533 struct tomoyo_domain_info *domain;
534 list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
535 if (!tomoyo_collect_acl(&domain->acl_info_list))
536 goto unlock;
537 if (!domain->is_deleted || atomic_read(&domain->users))
538 continue;
540 * Nobody is referring this domain. But somebody may
541 * refer this domain after successful execve().
542 * We recheck domain->users after SRCU synchronization.
544 if (!tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, &domain->list))
545 goto unlock;
548 list_for_each_entry_rcu(ns, &tomoyo_namespace_list, namespace_list) {
549 for (id = 0; id < TOMOYO_MAX_POLICY; id++)
550 if (!tomoyo_collect_member(id, &ns->policy_list[id]))
551 goto unlock;
552 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
553 if (!tomoyo_collect_acl(&ns->acl_group[i]))
554 goto unlock;
555 for (i = 0; i < TOMOYO_MAX_GROUP; i++) {
556 struct list_head *list = &ns->group_list[i];
557 struct tomoyo_group *group;
558 switch (i) {
559 case 0:
560 id = TOMOYO_ID_PATH_GROUP;
561 break;
562 case 1:
563 id = TOMOYO_ID_NUMBER_GROUP;
564 break;
565 default:
566 id = TOMOYO_ID_ADDRESS_GROUP;
567 break;
569 list_for_each_entry(group, list, head.list) {
570 if (!tomoyo_collect_member
571 (id, &group->member_list))
572 goto unlock;
573 if (!list_empty(&group->member_list) ||
574 atomic_read(&group->head.users))
575 continue;
576 if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP,
577 &group->head.list))
578 goto unlock;
582 id = TOMOYO_ID_CONDITION;
583 for (i = 0; i < TOMOYO_MAX_HASH + 1; i++) {
584 struct list_head *list = !i ?
585 &tomoyo_condition_list : &tomoyo_name_list[i - 1];
586 struct tomoyo_shared_acl_head *ptr;
587 list_for_each_entry(ptr, list, list) {
588 if (atomic_read(&ptr->users))
589 continue;
590 if (!tomoyo_add_to_gc(id, &ptr->list))
591 goto unlock;
593 id = TOMOYO_ID_NAME;
595 unlock:
596 tomoyo_read_unlock(idx);
597 mutex_unlock(&tomoyo_policy_lock);
601 * tomoyo_kfree_entry - Delete entries in tomoyo_gc_list.
603 * Returns true if some entries were kfree()d, false otherwise.
605 static bool tomoyo_kfree_entry(void)
607 struct tomoyo_gc *p;
608 struct tomoyo_gc *tmp;
609 bool result = false;
611 list_for_each_entry_safe(p, tmp, &tomoyo_gc_list, list) {
612 struct list_head *element = p->element;
615 * list_del_rcu() in tomoyo_add_to_gc() guarantees that the
616 * list element became no longer reachable from the list which
617 * the element was originally on (e.g. tomoyo_domain_list).
618 * Also, synchronize_srcu() in tomoyo_gc_thread() guarantees
619 * that the list element became no longer referenced by syscall
620 * users.
622 * However, there are three users which may still be using the
623 * list element. We need to defer until all of these users
624 * forget the list element.
626 * Firstly, defer until "struct tomoyo_io_buffer"->r.{domain,
627 * group,acl} and "struct tomoyo_io_buffer"->w.domain forget
628 * the list element.
630 if (tomoyo_struct_used_by_io_buffer(element))
631 continue;
633 * Secondly, defer until all other elements in the
634 * tomoyo_gc_list list forget the list element.
636 if (tomoyo_element_linked_by_gc((const u8 *) element, p->size))
637 continue;
638 switch (p->type) {
639 case TOMOYO_ID_TRANSITION_CONTROL:
640 tomoyo_del_transition_control(element);
641 break;
642 case TOMOYO_ID_AGGREGATOR:
643 tomoyo_del_aggregator(element);
644 break;
645 case TOMOYO_ID_MANAGER:
646 tomoyo_del_manager(element);
647 break;
648 case TOMOYO_ID_CONDITION:
649 tomoyo_del_condition(element);
650 break;
651 case TOMOYO_ID_NAME:
653 * Thirdly, defer until all "struct tomoyo_io_buffer"
654 * ->r.w[] forget the list element.
656 if (tomoyo_name_used_by_io_buffer(
657 container_of(element, typeof(struct tomoyo_name),
658 head.list)->entry.name, p->size))
659 continue;
660 tomoyo_del_name(element);
661 break;
662 case TOMOYO_ID_ACL:
663 tomoyo_del_acl(element);
664 break;
665 case TOMOYO_ID_DOMAIN:
666 if (!tomoyo_del_domain(element))
667 continue;
668 break;
669 case TOMOYO_ID_PATH_GROUP:
670 tomoyo_del_path_group(element);
671 break;
672 case TOMOYO_ID_ADDRESS_GROUP:
673 tomoyo_del_address_group(element);
674 break;
675 case TOMOYO_ID_GROUP:
676 tomoyo_del_group(element);
677 break;
678 case TOMOYO_ID_NUMBER_GROUP:
679 tomoyo_del_number_group(element);
680 break;
681 case TOMOYO_MAX_POLICY:
682 break;
684 tomoyo_memory_free(element);
685 list_del(&p->list);
686 kfree(p);
687 tomoyo_gc_list_len--;
688 result = true;
690 return result;
694 * tomoyo_gc_thread - Garbage collector thread function.
696 * @unused: Unused.
698 * In case OOM-killer choose this thread for termination, we create this thread
699 * as a short live thread whenever /sys/kernel/security/tomoyo/ interface was
700 * close()d.
702 * Returns 0.
704 static int tomoyo_gc_thread(void *unused)
706 /* Garbage collector thread is exclusive. */
707 static DEFINE_MUTEX(tomoyo_gc_mutex);
708 if (!mutex_trylock(&tomoyo_gc_mutex))
709 goto out;
711 do {
712 tomoyo_collect_entry();
713 if (list_empty(&tomoyo_gc_list))
714 break;
715 synchronize_srcu(&tomoyo_ss);
716 } while (tomoyo_kfree_entry());
718 struct tomoyo_io_buffer *head;
719 struct tomoyo_io_buffer *tmp;
721 spin_lock(&tomoyo_io_buffer_list_lock);
722 list_for_each_entry_safe(head, tmp, &tomoyo_io_buffer_list,
723 list) {
724 if (head->users)
725 continue;
726 list_del(&head->list);
727 kfree(head->read_buf);
728 kfree(head->write_buf);
729 kfree(head);
731 spin_unlock(&tomoyo_io_buffer_list_lock);
733 mutex_unlock(&tomoyo_gc_mutex);
734 out:
735 /* This acts as do_exit(0). */
736 return 0;
740 * tomoyo_notify_gc - Register/unregister /sys/kernel/security/tomoyo/ users.
742 * @head: Pointer to "struct tomoyo_io_buffer".
743 * @is_register: True if register, false if unregister.
745 * Returns nothing.
747 void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register)
749 bool is_write = false;
751 spin_lock(&tomoyo_io_buffer_list_lock);
752 if (is_register) {
753 head->users = 1;
754 list_add(&head->list, &tomoyo_io_buffer_list);
755 } else {
756 is_write = head->write_buf != NULL;
757 if (!--head->users) {
758 list_del(&head->list);
759 kfree(head->read_buf);
760 kfree(head->write_buf);
761 kfree(head);
764 spin_unlock(&tomoyo_io_buffer_list_lock);
765 if (is_write) {
766 struct task_struct *task = kthread_create(tomoyo_gc_thread,
767 NULL,
768 "GC for TOMOYO");
769 if (!IS_ERR(task))
770 wake_up_process(task);