Linux Audio

Check our new training course

Loading...
v4.6
  1/*
  2 * security/tomoyo/gc.c
  3 *
  4 * Copyright (C) 2005-2011  NTT DATA CORPORATION
  5 */
  6
  7#include "common.h"
  8#include <linux/kthread.h>
  9#include <linux/slab.h>
 10
 11/**
 12 * tomoyo_memory_free - Free memory for elements.
 13 *
 14 * @ptr:  Pointer to allocated memory.
 15 *
 16 * Returns nothing.
 17 *
 18 * Caller holds tomoyo_policy_lock mutex.
 19 */
 20static inline void tomoyo_memory_free(void *ptr)
 21{
 22	tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= ksize(ptr);
 23	kfree(ptr);
 24}
 25
 26/* The list for "struct tomoyo_io_buffer". */
 27static LIST_HEAD(tomoyo_io_buffer_list);
 28/* Lock for protecting tomoyo_io_buffer_list. */
 29static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock);
 30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 31/**
 32 * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not.
 33 *
 34 * @element: Pointer to "struct list_head".
 35 *
 36 * Returns true if @element is used by /sys/kernel/security/tomoyo/ users,
 37 * false otherwise.
 38 */
 39static bool tomoyo_struct_used_by_io_buffer(const struct list_head *element)
 40{
 41	struct tomoyo_io_buffer *head;
 42	bool in_use = false;
 43
 44	spin_lock(&tomoyo_io_buffer_list_lock);
 45	list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
 46		head->users++;
 47		spin_unlock(&tomoyo_io_buffer_list_lock);
 48		mutex_lock(&head->io_sem);
 
 
 
 49		if (head->r.domain == element || head->r.group == element ||
 50		    head->r.acl == element || &head->w.domain->list == element)
 51			in_use = true;
 52		mutex_unlock(&head->io_sem);
 
 53		spin_lock(&tomoyo_io_buffer_list_lock);
 54		head->users--;
 55		if (in_use)
 56			break;
 57	}
 58	spin_unlock(&tomoyo_io_buffer_list_lock);
 59	return in_use;
 60}
 61
 62/**
 63 * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not.
 64 *
 65 * @string: String to check.
 
 66 *
 67 * Returns true if @string is used by /sys/kernel/security/tomoyo/ users,
 68 * false otherwise.
 69 */
 70static bool tomoyo_name_used_by_io_buffer(const char *string)
 
 71{
 72	struct tomoyo_io_buffer *head;
 73	const size_t size = strlen(string) + 1;
 74	bool in_use = false;
 75
 76	spin_lock(&tomoyo_io_buffer_list_lock);
 77	list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
 78		int i;
 79		head->users++;
 80		spin_unlock(&tomoyo_io_buffer_list_lock);
 81		mutex_lock(&head->io_sem);
 
 
 
 82		for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) {
 83			const char *w = head->r.w[i];
 84			if (w < string || w > string + size)
 85				continue;
 86			in_use = true;
 87			break;
 88		}
 89		mutex_unlock(&head->io_sem);
 
 90		spin_lock(&tomoyo_io_buffer_list_lock);
 91		head->users--;
 92		if (in_use)
 93			break;
 94	}
 95	spin_unlock(&tomoyo_io_buffer_list_lock);
 96	return in_use;
 97}
 98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 99/**
100 * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control".
101 *
102 * @element: Pointer to "struct list_head".
103 *
104 * Returns nothing.
105 */
106static inline void tomoyo_del_transition_control(struct list_head *element)
107{
108	struct tomoyo_transition_control *ptr =
109		container_of(element, typeof(*ptr), head.list);
110	tomoyo_put_name(ptr->domainname);
111	tomoyo_put_name(ptr->program);
112}
113
114/**
115 * tomoyo_del_aggregator - Delete members in "struct tomoyo_aggregator".
116 *
117 * @element: Pointer to "struct list_head".
118 *
119 * Returns nothing.
120 */
121static inline void tomoyo_del_aggregator(struct list_head *element)
122{
123	struct tomoyo_aggregator *ptr =
124		container_of(element, typeof(*ptr), head.list);
125	tomoyo_put_name(ptr->original_name);
126	tomoyo_put_name(ptr->aggregated_name);
127}
128
129/**
130 * tomoyo_del_manager - Delete members in "struct tomoyo_manager".
131 *
132 * @element: Pointer to "struct list_head".
133 *
134 * Returns nothing.
135 */
136static inline void tomoyo_del_manager(struct list_head *element)
137{
138	struct tomoyo_manager *ptr =
139		container_of(element, typeof(*ptr), head.list);
140	tomoyo_put_name(ptr->manager);
141}
142
143/**
144 * tomoyo_del_acl - Delete members in "struct tomoyo_acl_info".
145 *
146 * @element: Pointer to "struct list_head".
147 *
148 * Returns nothing.
149 */
150static void tomoyo_del_acl(struct list_head *element)
151{
152	struct tomoyo_acl_info *acl =
153		container_of(element, typeof(*acl), list);
154	tomoyo_put_condition(acl->cond);
155	switch (acl->type) {
156	case TOMOYO_TYPE_PATH_ACL:
157		{
158			struct tomoyo_path_acl *entry
159				= container_of(acl, typeof(*entry), head);
160			tomoyo_put_name_union(&entry->name);
161		}
162		break;
163	case TOMOYO_TYPE_PATH2_ACL:
164		{
165			struct tomoyo_path2_acl *entry
166				= container_of(acl, typeof(*entry), head);
167			tomoyo_put_name_union(&entry->name1);
168			tomoyo_put_name_union(&entry->name2);
169		}
170		break;
171	case TOMOYO_TYPE_PATH_NUMBER_ACL:
172		{
173			struct tomoyo_path_number_acl *entry
174				= container_of(acl, typeof(*entry), head);
175			tomoyo_put_name_union(&entry->name);
176			tomoyo_put_number_union(&entry->number);
177		}
178		break;
179	case TOMOYO_TYPE_MKDEV_ACL:
180		{
181			struct tomoyo_mkdev_acl *entry
182				= container_of(acl, typeof(*entry), head);
183			tomoyo_put_name_union(&entry->name);
184			tomoyo_put_number_union(&entry->mode);
185			tomoyo_put_number_union(&entry->major);
186			tomoyo_put_number_union(&entry->minor);
187		}
188		break;
189	case TOMOYO_TYPE_MOUNT_ACL:
190		{
191			struct tomoyo_mount_acl *entry
192				= container_of(acl, typeof(*entry), head);
193			tomoyo_put_name_union(&entry->dev_name);
194			tomoyo_put_name_union(&entry->dir_name);
195			tomoyo_put_name_union(&entry->fs_type);
196			tomoyo_put_number_union(&entry->flags);
197		}
198		break;
199	case TOMOYO_TYPE_ENV_ACL:
200		{
201			struct tomoyo_env_acl *entry =
202				container_of(acl, typeof(*entry), head);
203
204			tomoyo_put_name(entry->env);
205		}
206		break;
207	case TOMOYO_TYPE_INET_ACL:
208		{
209			struct tomoyo_inet_acl *entry =
210				container_of(acl, typeof(*entry), head);
211
212			tomoyo_put_group(entry->address.group);
213			tomoyo_put_number_union(&entry->port);
214		}
215		break;
216	case TOMOYO_TYPE_UNIX_ACL:
217		{
218			struct tomoyo_unix_acl *entry =
219				container_of(acl, typeof(*entry), head);
220
221			tomoyo_put_name_union(&entry->name);
222		}
223		break;
224	case TOMOYO_TYPE_MANUAL_TASK_ACL:
225		{
226			struct tomoyo_task_acl *entry =
227				container_of(acl, typeof(*entry), head);
228			tomoyo_put_name(entry->domainname);
229		}
230		break;
231	}
232}
233
234/**
235 * tomoyo_del_domain - Delete members in "struct tomoyo_domain_info".
236 *
237 * @element: Pointer to "struct list_head".
238 *
239 * Returns nothing.
240 *
241 * Caller holds tomoyo_policy_lock mutex.
242 */
243static inline void tomoyo_del_domain(struct list_head *element)
244{
245	struct tomoyo_domain_info *domain =
246		container_of(element, typeof(*domain), list);
247	struct tomoyo_acl_info *acl;
248	struct tomoyo_acl_info *tmp;
249	/*
250	 * Since this domain is referenced from neither
251	 * "struct tomoyo_io_buffer" nor "struct cred"->security, we can delete
252	 * elements without checking for is_deleted flag.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253	 */
 
 
254	list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
255		tomoyo_del_acl(&acl->list);
256		tomoyo_memory_free(acl);
257	}
258	tomoyo_put_name(domain->domainname);
 
259}
260
261/**
262 * tomoyo_del_condition - Delete members in "struct tomoyo_condition".
263 *
264 * @element: Pointer to "struct list_head".
265 *
266 * Returns nothing.
267 */
268void tomoyo_del_condition(struct list_head *element)
269{
270	struct tomoyo_condition *cond = container_of(element, typeof(*cond),
271						     head.list);
272	const u16 condc = cond->condc;
273	const u16 numbers_count = cond->numbers_count;
274	const u16 names_count = cond->names_count;
275	const u16 argc = cond->argc;
276	const u16 envc = cond->envc;
277	unsigned int i;
278	const struct tomoyo_condition_element *condp
279		= (const struct tomoyo_condition_element *) (cond + 1);
280	struct tomoyo_number_union *numbers_p
281		= (struct tomoyo_number_union *) (condp + condc);
282	struct tomoyo_name_union *names_p
283		= (struct tomoyo_name_union *) (numbers_p + numbers_count);
284	const struct tomoyo_argv *argv
285		= (const struct tomoyo_argv *) (names_p + names_count);
286	const struct tomoyo_envp *envp
287		= (const struct tomoyo_envp *) (argv + argc);
288	for (i = 0; i < numbers_count; i++)
289		tomoyo_put_number_union(numbers_p++);
290	for (i = 0; i < names_count; i++)
291		tomoyo_put_name_union(names_p++);
292	for (i = 0; i < argc; argv++, i++)
293		tomoyo_put_name(argv->value);
294	for (i = 0; i < envc; envp++, i++) {
295		tomoyo_put_name(envp->name);
296		tomoyo_put_name(envp->value);
297	}
298}
299
300/**
301 * tomoyo_del_name - Delete members in "struct tomoyo_name".
302 *
303 * @element: Pointer to "struct list_head".
304 *
305 * Returns nothing.
306 */
307static inline void tomoyo_del_name(struct list_head *element)
308{
309	/* Nothing to do. */
 
310}
311
312/**
313 * tomoyo_del_path_group - Delete members in "struct tomoyo_path_group".
314 *
315 * @element: Pointer to "struct list_head".
316 *
317 * Returns nothing.
318 */
319static inline void tomoyo_del_path_group(struct list_head *element)
320{
321	struct tomoyo_path_group *member =
322		container_of(element, typeof(*member), head.list);
323	tomoyo_put_name(member->member_name);
324}
325
326/**
327 * tomoyo_del_group - Delete "struct tomoyo_group".
328 *
329 * @element: Pointer to "struct list_head".
330 *
331 * Returns nothing.
332 */
333static inline void tomoyo_del_group(struct list_head *element)
334{
335	struct tomoyo_group *group =
336		container_of(element, typeof(*group), head.list);
337	tomoyo_put_name(group->group_name);
338}
339
340/**
341 * tomoyo_del_address_group - Delete members in "struct tomoyo_address_group".
342 *
343 * @element: Pointer to "struct list_head".
344 *
345 * Returns nothing.
346 */
347static inline void tomoyo_del_address_group(struct list_head *element)
348{
349	/* Nothing to do. */
350}
351
352/**
353 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group".
354 *
355 * @element: Pointer to "struct list_head".
356 *
357 * Returns nothing.
358 */
359static inline void tomoyo_del_number_group(struct list_head *element)
360{
361	/* Nothing to do. */
362}
363
364/**
365 * tomoyo_try_to_gc - Try to kfree() an entry.
366 *
367 * @type:    One of values in "enum tomoyo_policy_id".
368 * @element: Pointer to "struct list_head".
369 *
370 * Returns nothing.
371 *
372 * Caller holds tomoyo_policy_lock mutex.
373 */
374static void tomoyo_try_to_gc(const enum tomoyo_policy_id type,
375			     struct list_head *element)
376{
377	/*
378	 * __list_del_entry() guarantees that the list element became no longer
379	 * reachable from the list which the element was originally on (e.g.
380	 * tomoyo_domain_list). Also, synchronize_srcu() guarantees that the
381	 * list element became no longer referenced by syscall users.
382	 */
383	__list_del_entry(element);
384	mutex_unlock(&tomoyo_policy_lock);
385	synchronize_srcu(&tomoyo_ss);
386	/*
387	 * However, there are two users which may still be using the list
388	 * element. We need to defer until both users forget this element.
389	 *
390	 * Don't kfree() until "struct tomoyo_io_buffer"->r.{domain,group,acl}
391	 * and "struct tomoyo_io_buffer"->w.domain forget this element.
392	 */
393	if (tomoyo_struct_used_by_io_buffer(element))
394		goto reinject;
395	switch (type) {
396	case TOMOYO_ID_TRANSITION_CONTROL:
397		tomoyo_del_transition_control(element);
398		break;
399	case TOMOYO_ID_MANAGER:
400		tomoyo_del_manager(element);
401		break;
402	case TOMOYO_ID_AGGREGATOR:
403		tomoyo_del_aggregator(element);
404		break;
405	case TOMOYO_ID_GROUP:
406		tomoyo_del_group(element);
407		break;
408	case TOMOYO_ID_PATH_GROUP:
409		tomoyo_del_path_group(element);
410		break;
411	case TOMOYO_ID_ADDRESS_GROUP:
412		tomoyo_del_address_group(element);
413		break;
414	case TOMOYO_ID_NUMBER_GROUP:
415		tomoyo_del_number_group(element);
416		break;
417	case TOMOYO_ID_CONDITION:
418		tomoyo_del_condition(element);
419		break;
420	case TOMOYO_ID_NAME:
421		/*
422		 * Don't kfree() until all "struct tomoyo_io_buffer"->r.w[]
423		 * forget this element.
424		 */
425		if (tomoyo_name_used_by_io_buffer
426		    (container_of(element, typeof(struct tomoyo_name),
427				  head.list)->entry.name))
428			goto reinject;
429		tomoyo_del_name(element);
430		break;
431	case TOMOYO_ID_ACL:
432		tomoyo_del_acl(element);
433		break;
434	case TOMOYO_ID_DOMAIN:
435		/*
436		 * Don't kfree() until all "struct cred"->security forget this
437		 * element.
438		 */
439		if (atomic_read(&container_of
440				(element, typeof(struct tomoyo_domain_info),
441				 list)->users))
442			goto reinject;
443		break;
444	case TOMOYO_MAX_POLICY:
445		break;
446	}
447	mutex_lock(&tomoyo_policy_lock);
448	if (type == TOMOYO_ID_DOMAIN)
449		tomoyo_del_domain(element);
450	tomoyo_memory_free(element);
451	return;
452reinject:
453	/*
454	 * We can safely reinject this element here bacause
455	 * (1) Appending list elements and removing list elements are protected
456	 *     by tomoyo_policy_lock mutex.
457	 * (2) Only this function removes list elements and this function is
458	 *     exclusively executed by tomoyo_gc_mutex mutex.
459	 * are true.
460	 */
461	mutex_lock(&tomoyo_policy_lock);
462	list_add_rcu(element, element->prev);
463}
464
465/**
466 * tomoyo_collect_member - Delete elements with "struct tomoyo_acl_head".
467 *
468 * @id:          One of values in "enum tomoyo_policy_id".
469 * @member_list: Pointer to "struct list_head".
470 *
471 * Returns nothing.
472 */
473static void tomoyo_collect_member(const enum tomoyo_policy_id id,
474				  struct list_head *member_list)
475{
476	struct tomoyo_acl_head *member;
477	struct tomoyo_acl_head *tmp;
478	list_for_each_entry_safe(member, tmp, member_list, list) {
479		if (!member->is_deleted)
480			continue;
481		member->is_deleted = TOMOYO_GC_IN_PROGRESS;
482		tomoyo_try_to_gc(id, &member->list);
483	}
 
484}
485
486/**
487 * tomoyo_collect_acl - Delete elements in "struct tomoyo_domain_info".
488 *
489 * @list: Pointer to "struct list_head".
490 *
491 * Returns nothing.
492 */
493static void tomoyo_collect_acl(struct list_head *list)
494{
495	struct tomoyo_acl_info *acl;
496	struct tomoyo_acl_info *tmp;
497	list_for_each_entry_safe(acl, tmp, list, list) {
498		if (!acl->is_deleted)
499			continue;
500		acl->is_deleted = TOMOYO_GC_IN_PROGRESS;
501		tomoyo_try_to_gc(TOMOYO_ID_ACL, &acl->list);
502	}
 
503}
504
505/**
506 * tomoyo_collect_entry - Try to kfree() deleted elements.
507 *
508 * Returns nothing.
509 */
510static void tomoyo_collect_entry(void)
511{
512	int i;
513	enum tomoyo_policy_id id;
514	struct tomoyo_policy_namespace *ns;
515	mutex_lock(&tomoyo_policy_lock);
 
 
 
516	{
517		struct tomoyo_domain_info *domain;
518		struct tomoyo_domain_info *tmp;
519		list_for_each_entry_safe(domain, tmp, &tomoyo_domain_list,
520					 list) {
521			tomoyo_collect_acl(&domain->acl_info_list);
522			if (!domain->is_deleted || atomic_read(&domain->users))
523				continue;
524			tomoyo_try_to_gc(TOMOYO_ID_DOMAIN, &domain->list);
 
 
 
 
 
 
525		}
526	}
527	list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
528		for (id = 0; id < TOMOYO_MAX_POLICY; id++)
529			tomoyo_collect_member(id, &ns->policy_list[id]);
 
530		for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
531			tomoyo_collect_acl(&ns->acl_group[i]);
532	}
533	{
534		struct tomoyo_shared_acl_head *ptr;
535		struct tomoyo_shared_acl_head *tmp;
536		list_for_each_entry_safe(ptr, tmp, &tomoyo_condition_list,
537					 list) {
538			if (atomic_read(&ptr->users) > 0)
539				continue;
540			atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS);
541			tomoyo_try_to_gc(TOMOYO_ID_CONDITION, &ptr->list);
542		}
543	}
544	list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
545		for (i = 0; i < TOMOYO_MAX_GROUP; i++) {
546			struct list_head *list = &ns->group_list[i];
547			struct tomoyo_group *group;
548			struct tomoyo_group *tmp;
549			switch (i) {
550			case 0:
551				id = TOMOYO_ID_PATH_GROUP;
552				break;
553			case 1:
554				id = TOMOYO_ID_NUMBER_GROUP;
555				break;
556			default:
557				id = TOMOYO_ID_ADDRESS_GROUP;
558				break;
559			}
560			list_for_each_entry_safe(group, tmp, list, head.list) {
561				tomoyo_collect_member(id, &group->member_list);
 
 
562				if (!list_empty(&group->member_list) ||
563				    atomic_read(&group->head.users) > 0)
564					continue;
565				atomic_set(&group->head.users,
566					   TOMOYO_GC_IN_PROGRESS);
567				tomoyo_try_to_gc(TOMOYO_ID_GROUP,
568						 &group->head.list);
569			}
570		}
571	}
572	for (i = 0; i < TOMOYO_MAX_HASH; i++) {
573		struct list_head *list = &tomoyo_name_list[i];
 
 
574		struct tomoyo_shared_acl_head *ptr;
575		struct tomoyo_shared_acl_head *tmp;
576		list_for_each_entry_safe(ptr, tmp, list, list) {
577			if (atomic_read(&ptr->users) > 0)
578				continue;
579			atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS);
580			tomoyo_try_to_gc(TOMOYO_ID_NAME, &ptr->list);
581		}
 
582	}
 
 
583	mutex_unlock(&tomoyo_policy_lock);
584}
585
586/**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
587 * tomoyo_gc_thread - Garbage collector thread function.
588 *
589 * @unused: Unused.
590 *
 
 
 
 
591 * Returns 0.
592 */
593static int tomoyo_gc_thread(void *unused)
594{
595	/* Garbage collector thread is exclusive. */
596	static DEFINE_MUTEX(tomoyo_gc_mutex);
597	if (!mutex_trylock(&tomoyo_gc_mutex))
598		goto out;
599	tomoyo_collect_entry();
 
 
 
 
 
 
600	{
601		struct tomoyo_io_buffer *head;
602		struct tomoyo_io_buffer *tmp;
603
604		spin_lock(&tomoyo_io_buffer_list_lock);
605		list_for_each_entry_safe(head, tmp, &tomoyo_io_buffer_list,
606					 list) {
607			if (head->users)
608				continue;
609			list_del(&head->list);
610			kfree(head->read_buf);
611			kfree(head->write_buf);
612			kfree(head);
613		}
614		spin_unlock(&tomoyo_io_buffer_list_lock);
615	}
616	mutex_unlock(&tomoyo_gc_mutex);
617out:
618	/* This acts as do_exit(0). */
619	return 0;
620}
621
622/**
623 * tomoyo_notify_gc - Register/unregister /sys/kernel/security/tomoyo/ users.
624 *
625 * @head:        Pointer to "struct tomoyo_io_buffer".
626 * @is_register: True if register, false if unregister.
627 *
628 * Returns nothing.
629 */
630void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register)
631{
632	bool is_write = false;
633
634	spin_lock(&tomoyo_io_buffer_list_lock);
635	if (is_register) {
636		head->users = 1;
637		list_add(&head->list, &tomoyo_io_buffer_list);
638	} else {
639		is_write = head->write_buf != NULL;
640		if (!--head->users) {
641			list_del(&head->list);
642			kfree(head->read_buf);
643			kfree(head->write_buf);
644			kfree(head);
645		}
646	}
647	spin_unlock(&tomoyo_io_buffer_list_lock);
648	if (is_write) {
649		struct task_struct *task = kthread_create(tomoyo_gc_thread,
650							  NULL,
651							  "GC for TOMOYO");
652		if (!IS_ERR(task))
653			wake_up_process(task);
654	}
655}
v3.1
  1/*
  2 * security/tomoyo/gc.c
  3 *
  4 * Copyright (C) 2005-2011  NTT DATA CORPORATION
  5 */
  6
  7#include "common.h"
  8#include <linux/kthread.h>
  9#include <linux/slab.h>
 10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 11/* The list for "struct tomoyo_io_buffer". */
 12static LIST_HEAD(tomoyo_io_buffer_list);
 13/* Lock for protecting tomoyo_io_buffer_list. */
 14static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock);
 15
 16/* Size of an element. */
 17static const u8 tomoyo_element_size[TOMOYO_MAX_POLICY] = {
 18	[TOMOYO_ID_GROUP] = sizeof(struct tomoyo_group),
 19	[TOMOYO_ID_PATH_GROUP] = sizeof(struct tomoyo_path_group),
 20	[TOMOYO_ID_NUMBER_GROUP] = sizeof(struct tomoyo_number_group),
 21	[TOMOYO_ID_AGGREGATOR] = sizeof(struct tomoyo_aggregator),
 22	[TOMOYO_ID_TRANSITION_CONTROL] =
 23	sizeof(struct tomoyo_transition_control),
 24	[TOMOYO_ID_MANAGER] = sizeof(struct tomoyo_manager),
 25	/* [TOMOYO_ID_CONDITION] = "struct tomoyo_condition"->size, */
 26	/* [TOMOYO_ID_NAME] = "struct tomoyo_name"->size, */
 27	/* [TOMOYO_ID_ACL] =
 28	   tomoyo_acl_size["struct tomoyo_acl_info"->type], */
 29	[TOMOYO_ID_DOMAIN] = sizeof(struct tomoyo_domain_info),
 30};
 31
 32/* Size of a domain ACL element. */
 33static const u8 tomoyo_acl_size[] = {
 34	[TOMOYO_TYPE_PATH_ACL] = sizeof(struct tomoyo_path_acl),
 35	[TOMOYO_TYPE_PATH2_ACL] = sizeof(struct tomoyo_path2_acl),
 36	[TOMOYO_TYPE_PATH_NUMBER_ACL] = sizeof(struct tomoyo_path_number_acl),
 37	[TOMOYO_TYPE_MKDEV_ACL] = sizeof(struct tomoyo_mkdev_acl),
 38	[TOMOYO_TYPE_MOUNT_ACL] = sizeof(struct tomoyo_mount_acl),
 39};
 40
 41/**
 42 * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not.
 43 *
 44 * @element: Pointer to "struct list_head".
 45 *
 46 * Returns true if @element is used by /sys/kernel/security/tomoyo/ users,
 47 * false otherwise.
 48 */
 49static bool tomoyo_struct_used_by_io_buffer(const struct list_head *element)
 50{
 51	struct tomoyo_io_buffer *head;
 52	bool in_use = false;
 53
 54	spin_lock(&tomoyo_io_buffer_list_lock);
 55	list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
 56		head->users++;
 57		spin_unlock(&tomoyo_io_buffer_list_lock);
 58		if (mutex_lock_interruptible(&head->io_sem)) {
 59			in_use = true;
 60			goto out;
 61		}
 62		if (head->r.domain == element || head->r.group == element ||
 63		    head->r.acl == element || &head->w.domain->list == element)
 64			in_use = true;
 65		mutex_unlock(&head->io_sem);
 66out:
 67		spin_lock(&tomoyo_io_buffer_list_lock);
 68		head->users--;
 69		if (in_use)
 70			break;
 71	}
 72	spin_unlock(&tomoyo_io_buffer_list_lock);
 73	return in_use;
 74}
 75
 76/**
 77 * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not.
 78 *
 79 * @string: String to check.
 80 * @size:   Memory allocated for @string .
 81 *
 82 * Returns true if @string is used by /sys/kernel/security/tomoyo/ users,
 83 * false otherwise.
 84 */
 85static bool tomoyo_name_used_by_io_buffer(const char *string,
 86					  const size_t size)
 87{
 88	struct tomoyo_io_buffer *head;
 
 89	bool in_use = false;
 90
 91	spin_lock(&tomoyo_io_buffer_list_lock);
 92	list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
 93		int i;
 94		head->users++;
 95		spin_unlock(&tomoyo_io_buffer_list_lock);
 96		if (mutex_lock_interruptible(&head->io_sem)) {
 97			in_use = true;
 98			goto out;
 99		}
100		for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) {
101			const char *w = head->r.w[i];
102			if (w < string || w > string + size)
103				continue;
104			in_use = true;
105			break;
106		}
107		mutex_unlock(&head->io_sem);
108out:
109		spin_lock(&tomoyo_io_buffer_list_lock);
110		head->users--;
111		if (in_use)
112			break;
113	}
114	spin_unlock(&tomoyo_io_buffer_list_lock);
115	return in_use;
116}
117
118/* Structure for garbage collection. */
119struct tomoyo_gc {
120	struct list_head list;
121	enum tomoyo_policy_id type;
122	size_t size;
123	struct list_head *element;
124};
125/* List of entries to be deleted. */
126static LIST_HEAD(tomoyo_gc_list);
127/* Length of tomoyo_gc_list. */
128static int tomoyo_gc_list_len;
129
130/**
131 * tomoyo_add_to_gc - Add an entry to to be deleted list.
132 *
133 * @type:    One of values in "enum tomoyo_policy_id".
134 * @element: Pointer to "struct list_head".
135 *
136 * Returns true on success, false otherwise.
137 *
138 * Caller holds tomoyo_policy_lock mutex.
139 *
140 * Adding an entry needs kmalloc(). Thus, if we try to add thousands of
141 * entries at once, it will take too long time. Thus, do not add more than 128
142 * entries per a scan. But to be able to handle worst case where all entries
143 * are in-use, we accept one more entry per a scan.
144 *
145 * If we use singly linked list using "struct list_head"->prev (which is
146 * LIST_POISON2), we can avoid kmalloc().
147 */
148static bool tomoyo_add_to_gc(const int type, struct list_head *element)
149{
150	struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
151	if (!entry)
152		return false;
153	entry->type = type;
154	if (type == TOMOYO_ID_ACL)
155		entry->size = tomoyo_acl_size[
156			      container_of(element,
157					   typeof(struct tomoyo_acl_info),
158					   list)->type];
159	else if (type == TOMOYO_ID_NAME)
160		entry->size = strlen(container_of(element,
161						  typeof(struct tomoyo_name),
162						  head.list)->entry.name) + 1;
163	else if (type == TOMOYO_ID_CONDITION)
164		entry->size =
165			container_of(element, typeof(struct tomoyo_condition),
166				     head.list)->size;
167	else
168		entry->size = tomoyo_element_size[type];
169	entry->element = element;
170	list_add(&entry->list, &tomoyo_gc_list);
171	list_del_rcu(element);
172	return tomoyo_gc_list_len++ < 128;
173}
174
175/**
176 * tomoyo_element_linked_by_gc - Validate next element of an entry.
177 *
178 * @element: Pointer to an element.
179 * @size:    Size of @element in byte.
180 *
181 * Returns true if @element is linked by other elements in the garbage
182 * collector's queue, false otherwise.
183 */
184static bool tomoyo_element_linked_by_gc(const u8 *element, const size_t size)
185{
186	struct tomoyo_gc *p;
187	list_for_each_entry(p, &tomoyo_gc_list, list) {
188		const u8 *ptr = (const u8 *) p->element->next;
189		if (ptr < element || element + size < ptr)
190			continue;
191		return true;
192	}
193	return false;
194}
195
196/**
197 * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control".
198 *
199 * @element: Pointer to "struct list_head".
200 *
201 * Returns nothing.
202 */
203static void tomoyo_del_transition_control(struct list_head *element)
204{
205	struct tomoyo_transition_control *ptr =
206		container_of(element, typeof(*ptr), head.list);
207	tomoyo_put_name(ptr->domainname);
208	tomoyo_put_name(ptr->program);
209}
210
211/**
212 * tomoyo_del_aggregator - Delete members in "struct tomoyo_aggregator".
213 *
214 * @element: Pointer to "struct list_head".
215 *
216 * Returns nothing.
217 */
218static void tomoyo_del_aggregator(struct list_head *element)
219{
220	struct tomoyo_aggregator *ptr =
221		container_of(element, typeof(*ptr), head.list);
222	tomoyo_put_name(ptr->original_name);
223	tomoyo_put_name(ptr->aggregated_name);
224}
225
226/**
227 * tomoyo_del_manager - Delete members in "struct tomoyo_manager".
228 *
229 * @element: Pointer to "struct list_head".
230 *
231 * Returns nothing.
232 */
233static void tomoyo_del_manager(struct list_head *element)
234{
235	struct tomoyo_manager *ptr =
236		container_of(element, typeof(*ptr), head.list);
237	tomoyo_put_name(ptr->manager);
238}
239
240/**
241 * tomoyo_del_acl - Delete members in "struct tomoyo_acl_info".
242 *
243 * @element: Pointer to "struct list_head".
244 *
245 * Returns nothing.
246 */
247static void tomoyo_del_acl(struct list_head *element)
248{
249	struct tomoyo_acl_info *acl =
250		container_of(element, typeof(*acl), list);
251	tomoyo_put_condition(acl->cond);
252	switch (acl->type) {
253	case TOMOYO_TYPE_PATH_ACL:
254		{
255			struct tomoyo_path_acl *entry
256				= container_of(acl, typeof(*entry), head);
257			tomoyo_put_name_union(&entry->name);
258		}
259		break;
260	case TOMOYO_TYPE_PATH2_ACL:
261		{
262			struct tomoyo_path2_acl *entry
263				= container_of(acl, typeof(*entry), head);
264			tomoyo_put_name_union(&entry->name1);
265			tomoyo_put_name_union(&entry->name2);
266		}
267		break;
268	case TOMOYO_TYPE_PATH_NUMBER_ACL:
269		{
270			struct tomoyo_path_number_acl *entry
271				= container_of(acl, typeof(*entry), head);
272			tomoyo_put_name_union(&entry->name);
273			tomoyo_put_number_union(&entry->number);
274		}
275		break;
276	case TOMOYO_TYPE_MKDEV_ACL:
277		{
278			struct tomoyo_mkdev_acl *entry
279				= container_of(acl, typeof(*entry), head);
280			tomoyo_put_name_union(&entry->name);
281			tomoyo_put_number_union(&entry->mode);
282			tomoyo_put_number_union(&entry->major);
283			tomoyo_put_number_union(&entry->minor);
284		}
285		break;
286	case TOMOYO_TYPE_MOUNT_ACL:
287		{
288			struct tomoyo_mount_acl *entry
289				= container_of(acl, typeof(*entry), head);
290			tomoyo_put_name_union(&entry->dev_name);
291			tomoyo_put_name_union(&entry->dir_name);
292			tomoyo_put_name_union(&entry->fs_type);
293			tomoyo_put_number_union(&entry->flags);
294		}
295		break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296	}
297}
298
299/**
300 * tomoyo_del_domain - Delete members in "struct tomoyo_domain_info".
301 *
302 * @element: Pointer to "struct list_head".
303 *
304 * Returns true if deleted, false otherwise.
 
 
305 */
306static bool tomoyo_del_domain(struct list_head *element)
307{
308	struct tomoyo_domain_info *domain =
309		container_of(element, typeof(*domain), list);
310	struct tomoyo_acl_info *acl;
311	struct tomoyo_acl_info *tmp;
312	/*
313	 * Since we don't protect whole execve() operation using SRCU,
314	 * we need to recheck domain->users at this point.
315	 *
316	 * (1) Reader starts SRCU section upon execve().
317	 * (2) Reader traverses tomoyo_domain_list and finds this domain.
318	 * (3) Writer marks this domain as deleted.
319	 * (4) Garbage collector removes this domain from tomoyo_domain_list
320	 *     because this domain is marked as deleted and used by nobody.
321	 * (5) Reader saves reference to this domain into
322	 *     "struct linux_binprm"->cred->security .
323	 * (6) Reader finishes SRCU section, although execve() operation has
324	 *     not finished yet.
325	 * (7) Garbage collector waits for SRCU synchronization.
326	 * (8) Garbage collector kfree() this domain because this domain is
327	 *     used by nobody.
328	 * (9) Reader finishes execve() operation and restores this domain from
329	 *     "struct linux_binprm"->cred->security.
330	 *
331	 * By updating domain->users at (5), we can solve this race problem
332	 * by rechecking domain->users at (8).
333	 */
334	if (atomic_read(&domain->users))
335		return false;
336	list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
337		tomoyo_del_acl(&acl->list);
338		tomoyo_memory_free(acl);
339	}
340	tomoyo_put_name(domain->domainname);
341	return true;
342}
343
344/**
345 * tomoyo_del_condition - Delete members in "struct tomoyo_condition".
346 *
347 * @element: Pointer to "struct list_head".
348 *
349 * Returns nothing.
350 */
351void tomoyo_del_condition(struct list_head *element)
352{
353	struct tomoyo_condition *cond = container_of(element, typeof(*cond),
354						     head.list);
355	const u16 condc = cond->condc;
356	const u16 numbers_count = cond->numbers_count;
357	const u16 names_count = cond->names_count;
358	const u16 argc = cond->argc;
359	const u16 envc = cond->envc;
360	unsigned int i;
361	const struct tomoyo_condition_element *condp
362		= (const struct tomoyo_condition_element *) (cond + 1);
363	struct tomoyo_number_union *numbers_p
364		= (struct tomoyo_number_union *) (condp + condc);
365	struct tomoyo_name_union *names_p
366		= (struct tomoyo_name_union *) (numbers_p + numbers_count);
367	const struct tomoyo_argv *argv
368		= (const struct tomoyo_argv *) (names_p + names_count);
369	const struct tomoyo_envp *envp
370		= (const struct tomoyo_envp *) (argv + argc);
371	for (i = 0; i < numbers_count; i++)
372		tomoyo_put_number_union(numbers_p++);
373	for (i = 0; i < names_count; i++)
374		tomoyo_put_name_union(names_p++);
375	for (i = 0; i < argc; argv++, i++)
376		tomoyo_put_name(argv->value);
377	for (i = 0; i < envc; envp++, i++) {
378		tomoyo_put_name(envp->name);
379		tomoyo_put_name(envp->value);
380	}
381}
382
383/**
384 * tomoyo_del_name - Delete members in "struct tomoyo_name".
385 *
386 * @element: Pointer to "struct list_head".
387 *
388 * Returns nothing.
389 */
390static void tomoyo_del_name(struct list_head *element)
391{
392	const struct tomoyo_name *ptr =
393		container_of(element, typeof(*ptr), head.list);
394}
395
396/**
397 * tomoyo_del_path_group - Delete members in "struct tomoyo_path_group".
398 *
399 * @element: Pointer to "struct list_head".
400 *
401 * Returns nothing.
402 */
403static void tomoyo_del_path_group(struct list_head *element)
404{
405	struct tomoyo_path_group *member =
406		container_of(element, typeof(*member), head.list);
407	tomoyo_put_name(member->member_name);
408}
409
410/**
411 * tomoyo_del_group - Delete "struct tomoyo_group".
412 *
413 * @element: Pointer to "struct list_head".
414 *
415 * Returns nothing.
416 */
417static void tomoyo_del_group(struct list_head *element)
418{
419	struct tomoyo_group *group =
420		container_of(element, typeof(*group), head.list);
421	tomoyo_put_name(group->group_name);
422}
423
424/**
 
 
 
 
 
 
 
 
 
 
 
 
425 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group".
426 *
427 * @element: Pointer to "struct list_head".
428 *
429 * Returns nothing.
430 */
431static void tomoyo_del_number_group(struct list_head *element)
432{
433	struct tomoyo_number_group *member =
434		container_of(element, typeof(*member), head.list);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435}
436
437/**
438 * tomoyo_collect_member - Delete elements with "struct tomoyo_acl_head".
439 *
440 * @id:          One of values in "enum tomoyo_policy_id".
441 * @member_list: Pointer to "struct list_head".
442 *
443 * Returns true if some elements are deleted, false otherwise.
444 */
445static bool tomoyo_collect_member(const enum tomoyo_policy_id id,
446				  struct list_head *member_list)
447{
448	struct tomoyo_acl_head *member;
449	list_for_each_entry(member, member_list, list) {
 
450		if (!member->is_deleted)
451			continue;
452		if (!tomoyo_add_to_gc(id, &member->list))
453			return false;
454	}
455	return true;
456}
457
458/**
459 * tomoyo_collect_acl - Delete elements in "struct tomoyo_domain_info".
460 *
461 * @list: Pointer to "struct list_head".
462 *
463 * Returns true if some elements are deleted, false otherwise.
464 */
465static bool tomoyo_collect_acl(struct list_head *list)
466{
467	struct tomoyo_acl_info *acl;
468	list_for_each_entry(acl, list, list) {
 
469		if (!acl->is_deleted)
470			continue;
471		if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list))
472			return false;
473	}
474	return true;
475}
476
477/**
478 * tomoyo_collect_entry - Scan lists for deleted elements.
479 *
480 * Returns nothing.
481 */
482static void tomoyo_collect_entry(void)
483{
484	int i;
485	enum tomoyo_policy_id id;
486	struct tomoyo_policy_namespace *ns;
487	int idx;
488	if (mutex_lock_interruptible(&tomoyo_policy_lock))
489		return;
490	idx = tomoyo_read_lock();
491	{
492		struct tomoyo_domain_info *domain;
493		list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
494			if (!tomoyo_collect_acl(&domain->acl_info_list))
495				goto unlock;
 
496			if (!domain->is_deleted || atomic_read(&domain->users))
497				continue;
498			/*
499			 * Nobody is referring this domain. But somebody may
500			 * refer this domain after successful execve().
501			 * We recheck domain->users after SRCU synchronization.
502			 */
503			if (!tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, &domain->list))
504				goto unlock;
505		}
506	}
507	list_for_each_entry_rcu(ns, &tomoyo_namespace_list, namespace_list) {
508		for (id = 0; id < TOMOYO_MAX_POLICY; id++)
509			if (!tomoyo_collect_member(id, &ns->policy_list[id]))
510				goto unlock;
511		for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
512			if (!tomoyo_collect_acl(&ns->acl_group[i]))
513				goto unlock;
 
 
 
 
 
 
 
 
 
 
 
 
514		for (i = 0; i < TOMOYO_MAX_GROUP; i++) {
515			struct list_head *list = &ns->group_list[i];
516			struct tomoyo_group *group;
 
517			switch (i) {
518			case 0:
519				id = TOMOYO_ID_PATH_GROUP;
520				break;
 
 
 
521			default:
522				id = TOMOYO_ID_NUMBER_GROUP;
523				break;
524			}
525			list_for_each_entry(group, list, head.list) {
526				if (!tomoyo_collect_member
527				    (id, &group->member_list))
528					goto unlock;
529				if (!list_empty(&group->member_list) ||
530				    atomic_read(&group->head.users))
531					continue;
532				if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP,
533						      &group->head.list))
534					goto unlock;
 
535			}
536		}
537	}
538	id = TOMOYO_ID_CONDITION;
539	for (i = 0; i < TOMOYO_MAX_HASH + 1; i++) {
540		struct list_head *list = !i ?
541			&tomoyo_condition_list : &tomoyo_name_list[i - 1];
542		struct tomoyo_shared_acl_head *ptr;
543		list_for_each_entry(ptr, list, list) {
544			if (atomic_read(&ptr->users))
 
545				continue;
546			if (!tomoyo_add_to_gc(id, &ptr->list))
547				goto unlock;
548		}
549		id = TOMOYO_ID_NAME;
550	}
551unlock:
552	tomoyo_read_unlock(idx);
553	mutex_unlock(&tomoyo_policy_lock);
554}
555
556/**
557 * tomoyo_kfree_entry - Delete entries in tomoyo_gc_list.
558 *
559 * Returns true if some entries were kfree()d, false otherwise.
560 */
561static bool tomoyo_kfree_entry(void)
562{
563	struct tomoyo_gc *p;
564	struct tomoyo_gc *tmp;
565	bool result = false;
566
567	list_for_each_entry_safe(p, tmp, &tomoyo_gc_list, list) {
568		struct list_head *element = p->element;
569
570		/*
571		 * list_del_rcu() in tomoyo_add_to_gc() guarantees that the
572		 * list element became no longer reachable from the list which
573		 * the element was originally on (e.g. tomoyo_domain_list).
574		 * Also, synchronize_srcu() in tomoyo_gc_thread() guarantees
575		 * that the list element became no longer referenced by syscall
576		 * users.
577		 *
578		 * However, there are three users which may still be using the
579		 * list element. We need to defer until all of these users
580		 * forget the list element.
581		 *
582		 * Firstly, defer until "struct tomoyo_io_buffer"->r.{domain,
583		 * group,acl} and "struct tomoyo_io_buffer"->w.domain forget
584		 * the list element.
585		 */
586		if (tomoyo_struct_used_by_io_buffer(element))
587			continue;
588		/*
589		 * Secondly, defer until all other elements in the
590		 * tomoyo_gc_list list forget the list element.
591		 */
592		if (tomoyo_element_linked_by_gc((const u8 *) element, p->size))
593			continue;
594		switch (p->type) {
595		case TOMOYO_ID_TRANSITION_CONTROL:
596			tomoyo_del_transition_control(element);
597			break;
598		case TOMOYO_ID_AGGREGATOR:
599			tomoyo_del_aggregator(element);
600			break;
601		case TOMOYO_ID_MANAGER:
602			tomoyo_del_manager(element);
603			break;
604		case TOMOYO_ID_CONDITION:
605			tomoyo_del_condition(element);
606			break;
607		case TOMOYO_ID_NAME:
608			/*
609			 * Thirdly, defer until all "struct tomoyo_io_buffer"
610			 * ->r.w[] forget the list element.
611			 */
612			if (tomoyo_name_used_by_io_buffer(
613			    container_of(element, typeof(struct tomoyo_name),
614					 head.list)->entry.name, p->size))
615				continue;
616			tomoyo_del_name(element);
617			break;
618		case TOMOYO_ID_ACL:
619			tomoyo_del_acl(element);
620			break;
621		case TOMOYO_ID_DOMAIN:
622			if (!tomoyo_del_domain(element))
623				continue;
624			break;
625		case TOMOYO_ID_PATH_GROUP:
626			tomoyo_del_path_group(element);
627			break;
628		case TOMOYO_ID_GROUP:
629			tomoyo_del_group(element);
630			break;
631		case TOMOYO_ID_NUMBER_GROUP:
632			tomoyo_del_number_group(element);
633			break;
634		case TOMOYO_MAX_POLICY:
635			break;
636		}
637		tomoyo_memory_free(element);
638		list_del(&p->list);
639		kfree(p);
640		tomoyo_gc_list_len--;
641		result = true;
642	}
643	return result;
644}
645
646/**
647 * tomoyo_gc_thread - Garbage collector thread function.
648 *
649 * @unused: Unused.
650 *
651 * In case OOM-killer choose this thread for termination, we create this thread
652 * as a short live thread whenever /sys/kernel/security/tomoyo/ interface was
653 * close()d.
654 *
655 * Returns 0.
656 */
657static int tomoyo_gc_thread(void *unused)
658{
659	/* Garbage collector thread is exclusive. */
660	static DEFINE_MUTEX(tomoyo_gc_mutex);
661	if (!mutex_trylock(&tomoyo_gc_mutex))
662		goto out;
663	daemonize("GC for TOMOYO");
664	do {
665		tomoyo_collect_entry();
666		if (list_empty(&tomoyo_gc_list))
667			break;
668		synchronize_srcu(&tomoyo_ss);
669	} while (tomoyo_kfree_entry());
670	{
671		struct tomoyo_io_buffer *head;
672		struct tomoyo_io_buffer *tmp;
673
674		spin_lock(&tomoyo_io_buffer_list_lock);
675		list_for_each_entry_safe(head, tmp, &tomoyo_io_buffer_list,
676					 list) {
677			if (head->users)
678				continue;
679			list_del(&head->list);
680			kfree(head->read_buf);
681			kfree(head->write_buf);
682			kfree(head);
683		}
684		spin_unlock(&tomoyo_io_buffer_list_lock);
685	}
686	mutex_unlock(&tomoyo_gc_mutex);
687out:
688	/* This acts as do_exit(0). */
689	return 0;
690}
691
692/**
693 * tomoyo_notify_gc - Register/unregister /sys/kernel/security/tomoyo/ users.
694 *
695 * @head:        Pointer to "struct tomoyo_io_buffer".
696 * @is_register: True if register, false if unregister.
697 *
698 * Returns nothing.
699 */
700void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register)
701{
702	bool is_write = false;
703
704	spin_lock(&tomoyo_io_buffer_list_lock);
705	if (is_register) {
706		head->users = 1;
707		list_add(&head->list, &tomoyo_io_buffer_list);
708	} else {
709		is_write = head->write_buf != NULL;
710		if (!--head->users) {
711			list_del(&head->list);
712			kfree(head->read_buf);
713			kfree(head->write_buf);
714			kfree(head);
715		}
716	}
717	spin_unlock(&tomoyo_io_buffer_list_lock);
718	if (is_write) {
719		struct task_struct *task = kthread_create(tomoyo_gc_thread,
720							  NULL,
721							  "GC for TOMOYO");
722		if (!IS_ERR(task))
723			wake_up_process(task);
724	}
725}