1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2005-2011 NTT DATA CORPORATION
9 #include <linux/kthread.h>
10 #include <linux/slab.h>
13 * tomoyo_memory_free - Free memory for elements.
15 * @ptr: Pointer to allocated memory.
19 * Caller holds tomoyo_policy_lock mutex.
21 static inline void tomoyo_memory_free(void *ptr
)
23 tomoyo_memory_used
[TOMOYO_MEMORY_POLICY
] -= ksize(ptr
);
27 /* The list for "struct tomoyo_io_buffer". */
28 static LIST_HEAD(tomoyo_io_buffer_list
);
29 /* Lock for protecting tomoyo_io_buffer_list. */
30 static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock
);
33 * tomoyo_struct_used_by_io_buffer - Check whether the list element is used by /sys/kernel/security/tomoyo/ users or not.
35 * @element: Pointer to "struct list_head".
37 * Returns true if @element is used by /sys/kernel/security/tomoyo/ users,
40 static bool tomoyo_struct_used_by_io_buffer(const struct list_head
*element
)
42 struct tomoyo_io_buffer
*head
;
45 spin_lock(&tomoyo_io_buffer_list_lock
);
46 list_for_each_entry(head
, &tomoyo_io_buffer_list
, list
) {
48 spin_unlock(&tomoyo_io_buffer_list_lock
);
49 mutex_lock(&head
->io_sem
);
50 if (head
->r
.domain
== element
|| head
->r
.group
== element
||
51 head
->r
.acl
== element
|| &head
->w
.domain
->list
== element
)
53 mutex_unlock(&head
->io_sem
);
54 spin_lock(&tomoyo_io_buffer_list_lock
);
59 spin_unlock(&tomoyo_io_buffer_list_lock
);
64 * tomoyo_name_used_by_io_buffer - Check whether the string is used by /sys/kernel/security/tomoyo/ users or not.
66 * @string: String to check.
68 * Returns true if @string is used by /sys/kernel/security/tomoyo/ users,
71 static bool tomoyo_name_used_by_io_buffer(const char *string
)
73 struct tomoyo_io_buffer
*head
;
74 const size_t size
= strlen(string
) + 1;
77 spin_lock(&tomoyo_io_buffer_list_lock
);
78 list_for_each_entry(head
, &tomoyo_io_buffer_list
, list
) {
82 spin_unlock(&tomoyo_io_buffer_list_lock
);
83 mutex_lock(&head
->io_sem
);
84 for (i
= 0; i
< TOMOYO_MAX_IO_READ_QUEUE
; i
++) {
85 const char *w
= head
->r
.w
[i
];
87 if (w
< string
|| w
> string
+ size
)
92 mutex_unlock(&head
->io_sem
);
93 spin_lock(&tomoyo_io_buffer_list_lock
);
98 spin_unlock(&tomoyo_io_buffer_list_lock
);
103 * tomoyo_del_transition_control - Delete members in "struct tomoyo_transition_control".
105 * @element: Pointer to "struct list_head".
109 static inline void tomoyo_del_transition_control(struct list_head
*element
)
111 struct tomoyo_transition_control
*ptr
=
112 container_of(element
, typeof(*ptr
), head
.list
);
114 tomoyo_put_name(ptr
->domainname
);
115 tomoyo_put_name(ptr
->program
);
119 * tomoyo_del_aggregator - Delete members in "struct tomoyo_aggregator".
121 * @element: Pointer to "struct list_head".
125 static inline void tomoyo_del_aggregator(struct list_head
*element
)
127 struct tomoyo_aggregator
*ptr
=
128 container_of(element
, typeof(*ptr
), head
.list
);
130 tomoyo_put_name(ptr
->original_name
);
131 tomoyo_put_name(ptr
->aggregated_name
);
135 * tomoyo_del_manager - Delete members in "struct tomoyo_manager".
137 * @element: Pointer to "struct list_head".
141 static inline void tomoyo_del_manager(struct list_head
*element
)
143 struct tomoyo_manager
*ptr
=
144 container_of(element
, typeof(*ptr
), head
.list
);
146 tomoyo_put_name(ptr
->manager
);
150 * tomoyo_del_acl - Delete members in "struct tomoyo_acl_info".
152 * @element: Pointer to "struct list_head".
156 static void tomoyo_del_acl(struct list_head
*element
)
158 struct tomoyo_acl_info
*acl
=
159 container_of(element
, typeof(*acl
), list
);
161 tomoyo_put_condition(acl
->cond
);
163 case TOMOYO_TYPE_PATH_ACL
:
165 struct tomoyo_path_acl
*entry
166 = container_of(acl
, typeof(*entry
), head
);
167 tomoyo_put_name_union(&entry
->name
);
170 case TOMOYO_TYPE_PATH2_ACL
:
172 struct tomoyo_path2_acl
*entry
173 = container_of(acl
, typeof(*entry
), head
);
174 tomoyo_put_name_union(&entry
->name1
);
175 tomoyo_put_name_union(&entry
->name2
);
178 case TOMOYO_TYPE_PATH_NUMBER_ACL
:
180 struct tomoyo_path_number_acl
*entry
181 = container_of(acl
, typeof(*entry
), head
);
182 tomoyo_put_name_union(&entry
->name
);
183 tomoyo_put_number_union(&entry
->number
);
186 case TOMOYO_TYPE_MKDEV_ACL
:
188 struct tomoyo_mkdev_acl
*entry
189 = container_of(acl
, typeof(*entry
), head
);
190 tomoyo_put_name_union(&entry
->name
);
191 tomoyo_put_number_union(&entry
->mode
);
192 tomoyo_put_number_union(&entry
->major
);
193 tomoyo_put_number_union(&entry
->minor
);
196 case TOMOYO_TYPE_MOUNT_ACL
:
198 struct tomoyo_mount_acl
*entry
199 = container_of(acl
, typeof(*entry
), head
);
200 tomoyo_put_name_union(&entry
->dev_name
);
201 tomoyo_put_name_union(&entry
->dir_name
);
202 tomoyo_put_name_union(&entry
->fs_type
);
203 tomoyo_put_number_union(&entry
->flags
);
206 case TOMOYO_TYPE_ENV_ACL
:
208 struct tomoyo_env_acl
*entry
=
209 container_of(acl
, typeof(*entry
), head
);
211 tomoyo_put_name(entry
->env
);
214 case TOMOYO_TYPE_INET_ACL
:
216 struct tomoyo_inet_acl
*entry
=
217 container_of(acl
, typeof(*entry
), head
);
219 tomoyo_put_group(entry
->address
.group
);
220 tomoyo_put_number_union(&entry
->port
);
223 case TOMOYO_TYPE_UNIX_ACL
:
225 struct tomoyo_unix_acl
*entry
=
226 container_of(acl
, typeof(*entry
), head
);
228 tomoyo_put_name_union(&entry
->name
);
231 case TOMOYO_TYPE_MANUAL_TASK_ACL
:
233 struct tomoyo_task_acl
*entry
=
234 container_of(acl
, typeof(*entry
), head
);
236 tomoyo_put_name(entry
->domainname
);
243 * tomoyo_del_domain - Delete members in "struct tomoyo_domain_info".
245 * @element: Pointer to "struct list_head".
249 * Caller holds tomoyo_policy_lock mutex.
251 static inline void tomoyo_del_domain(struct list_head
*element
)
253 struct tomoyo_domain_info
*domain
=
254 container_of(element
, typeof(*domain
), list
);
255 struct tomoyo_acl_info
*acl
;
256 struct tomoyo_acl_info
*tmp
;
259 * Since this domain is referenced from neither
260 * "struct tomoyo_io_buffer" nor "struct cred"->security, we can delete
261 * elements without checking for is_deleted flag.
263 list_for_each_entry_safe(acl
, tmp
, &domain
->acl_info_list
, list
) {
264 tomoyo_del_acl(&acl
->list
);
265 tomoyo_memory_free(acl
);
267 tomoyo_put_name(domain
->domainname
);
271 * tomoyo_del_condition - Delete members in "struct tomoyo_condition".
273 * @element: Pointer to "struct list_head".
277 void tomoyo_del_condition(struct list_head
*element
)
279 struct tomoyo_condition
*cond
= container_of(element
, typeof(*cond
),
281 const u16 condc
= cond
->condc
;
282 const u16 numbers_count
= cond
->numbers_count
;
283 const u16 names_count
= cond
->names_count
;
284 const u16 argc
= cond
->argc
;
285 const u16 envc
= cond
->envc
;
287 const struct tomoyo_condition_element
*condp
288 = (const struct tomoyo_condition_element
*) (cond
+ 1);
289 struct tomoyo_number_union
*numbers_p
290 = (struct tomoyo_number_union
*) (condp
+ condc
);
291 struct tomoyo_name_union
*names_p
292 = (struct tomoyo_name_union
*) (numbers_p
+ numbers_count
);
293 const struct tomoyo_argv
*argv
294 = (const struct tomoyo_argv
*) (names_p
+ names_count
);
295 const struct tomoyo_envp
*envp
296 = (const struct tomoyo_envp
*) (argv
+ argc
);
298 for (i
= 0; i
< numbers_count
; i
++)
299 tomoyo_put_number_union(numbers_p
++);
300 for (i
= 0; i
< names_count
; i
++)
301 tomoyo_put_name_union(names_p
++);
302 for (i
= 0; i
< argc
; argv
++, i
++)
303 tomoyo_put_name(argv
->value
);
304 for (i
= 0; i
< envc
; envp
++, i
++) {
305 tomoyo_put_name(envp
->name
);
306 tomoyo_put_name(envp
->value
);
311 * tomoyo_del_name - Delete members in "struct tomoyo_name".
313 * @element: Pointer to "struct list_head".
317 static inline void tomoyo_del_name(struct list_head
*element
)
323 * tomoyo_del_path_group - Delete members in "struct tomoyo_path_group".
325 * @element: Pointer to "struct list_head".
329 static inline void tomoyo_del_path_group(struct list_head
*element
)
331 struct tomoyo_path_group
*member
=
332 container_of(element
, typeof(*member
), head
.list
);
334 tomoyo_put_name(member
->member_name
);
338 * tomoyo_del_group - Delete "struct tomoyo_group".
340 * @element: Pointer to "struct list_head".
344 static inline void tomoyo_del_group(struct list_head
*element
)
346 struct tomoyo_group
*group
=
347 container_of(element
, typeof(*group
), head
.list
);
349 tomoyo_put_name(group
->group_name
);
353 * tomoyo_del_address_group - Delete members in "struct tomoyo_address_group".
355 * @element: Pointer to "struct list_head".
359 static inline void tomoyo_del_address_group(struct list_head
*element
)
365 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group".
367 * @element: Pointer to "struct list_head".
371 static inline void tomoyo_del_number_group(struct list_head
*element
)
377 * tomoyo_try_to_gc - Try to kfree() an entry.
379 * @type: One of values in "enum tomoyo_policy_id".
380 * @element: Pointer to "struct list_head".
384 * Caller holds tomoyo_policy_lock mutex.
386 static void tomoyo_try_to_gc(const enum tomoyo_policy_id type
,
387 struct list_head
*element
)
390 * __list_del_entry() guarantees that the list element became no longer
391 * reachable from the list which the element was originally on (e.g.
392 * tomoyo_domain_list). Also, synchronize_srcu() guarantees that the
393 * list element became no longer referenced by syscall users.
395 __list_del_entry(element
);
396 mutex_unlock(&tomoyo_policy_lock
);
397 synchronize_srcu(&tomoyo_ss
);
399 * However, there are two users which may still be using the list
400 * element. We need to defer until both users forget this element.
402 * Don't kfree() until "struct tomoyo_io_buffer"->r.{domain,group,acl}
403 * and "struct tomoyo_io_buffer"->w.domain forget this element.
405 if (tomoyo_struct_used_by_io_buffer(element
))
408 case TOMOYO_ID_TRANSITION_CONTROL
:
409 tomoyo_del_transition_control(element
);
411 case TOMOYO_ID_MANAGER
:
412 tomoyo_del_manager(element
);
414 case TOMOYO_ID_AGGREGATOR
:
415 tomoyo_del_aggregator(element
);
417 case TOMOYO_ID_GROUP
:
418 tomoyo_del_group(element
);
420 case TOMOYO_ID_PATH_GROUP
:
421 tomoyo_del_path_group(element
);
423 case TOMOYO_ID_ADDRESS_GROUP
:
424 tomoyo_del_address_group(element
);
426 case TOMOYO_ID_NUMBER_GROUP
:
427 tomoyo_del_number_group(element
);
429 case TOMOYO_ID_CONDITION
:
430 tomoyo_del_condition(element
);
434 * Don't kfree() until all "struct tomoyo_io_buffer"->r.w[]
435 * forget this element.
437 if (tomoyo_name_used_by_io_buffer
438 (container_of(element
, typeof(struct tomoyo_name
),
439 head
.list
)->entry
.name
))
441 tomoyo_del_name(element
);
444 tomoyo_del_acl(element
);
446 case TOMOYO_ID_DOMAIN
:
448 * Don't kfree() until all "struct cred"->security forget this
451 if (atomic_read(&container_of
452 (element
, typeof(struct tomoyo_domain_info
),
456 case TOMOYO_MAX_POLICY
:
459 mutex_lock(&tomoyo_policy_lock
);
460 if (type
== TOMOYO_ID_DOMAIN
)
461 tomoyo_del_domain(element
);
462 tomoyo_memory_free(element
);
466 * We can safely reinject this element here bacause
467 * (1) Appending list elements and removing list elements are protected
468 * by tomoyo_policy_lock mutex.
469 * (2) Only this function removes list elements and this function is
470 * exclusively executed by tomoyo_gc_mutex mutex.
473 mutex_lock(&tomoyo_policy_lock
);
474 list_add_rcu(element
, element
->prev
);
478 * tomoyo_collect_member - Delete elements with "struct tomoyo_acl_head".
480 * @id: One of values in "enum tomoyo_policy_id".
481 * @member_list: Pointer to "struct list_head".
485 static void tomoyo_collect_member(const enum tomoyo_policy_id id
,
486 struct list_head
*member_list
)
488 struct tomoyo_acl_head
*member
;
489 struct tomoyo_acl_head
*tmp
;
491 list_for_each_entry_safe(member
, tmp
, member_list
, list
) {
492 if (!member
->is_deleted
)
494 member
->is_deleted
= TOMOYO_GC_IN_PROGRESS
;
495 tomoyo_try_to_gc(id
, &member
->list
);
500 * tomoyo_collect_acl - Delete elements in "struct tomoyo_domain_info".
502 * @list: Pointer to "struct list_head".
506 static void tomoyo_collect_acl(struct list_head
*list
)
508 struct tomoyo_acl_info
*acl
;
509 struct tomoyo_acl_info
*tmp
;
511 list_for_each_entry_safe(acl
, tmp
, list
, list
) {
512 if (!acl
->is_deleted
)
514 acl
->is_deleted
= TOMOYO_GC_IN_PROGRESS
;
515 tomoyo_try_to_gc(TOMOYO_ID_ACL
, &acl
->list
);
520 * tomoyo_collect_entry - Try to kfree() deleted elements.
524 static void tomoyo_collect_entry(void)
527 enum tomoyo_policy_id id
;
528 struct tomoyo_policy_namespace
*ns
;
530 mutex_lock(&tomoyo_policy_lock
);
532 struct tomoyo_domain_info
*domain
;
533 struct tomoyo_domain_info
*tmp
;
535 list_for_each_entry_safe(domain
, tmp
, &tomoyo_domain_list
,
537 tomoyo_collect_acl(&domain
->acl_info_list
);
538 if (!domain
->is_deleted
|| atomic_read(&domain
->users
))
540 tomoyo_try_to_gc(TOMOYO_ID_DOMAIN
, &domain
->list
);
543 list_for_each_entry(ns
, &tomoyo_namespace_list
, namespace_list
) {
544 for (id
= 0; id
< TOMOYO_MAX_POLICY
; id
++)
545 tomoyo_collect_member(id
, &ns
->policy_list
[id
]);
546 for (i
= 0; i
< TOMOYO_MAX_ACL_GROUPS
; i
++)
547 tomoyo_collect_acl(&ns
->acl_group
[i
]);
550 struct tomoyo_shared_acl_head
*ptr
;
551 struct tomoyo_shared_acl_head
*tmp
;
553 list_for_each_entry_safe(ptr
, tmp
, &tomoyo_condition_list
,
555 if (atomic_read(&ptr
->users
) > 0)
557 atomic_set(&ptr
->users
, TOMOYO_GC_IN_PROGRESS
);
558 tomoyo_try_to_gc(TOMOYO_ID_CONDITION
, &ptr
->list
);
561 list_for_each_entry(ns
, &tomoyo_namespace_list
, namespace_list
) {
562 for (i
= 0; i
< TOMOYO_MAX_GROUP
; i
++) {
563 struct list_head
*list
= &ns
->group_list
[i
];
564 struct tomoyo_group
*group
;
565 struct tomoyo_group
*tmp
;
569 id
= TOMOYO_ID_PATH_GROUP
;
572 id
= TOMOYO_ID_NUMBER_GROUP
;
575 id
= TOMOYO_ID_ADDRESS_GROUP
;
578 list_for_each_entry_safe(group
, tmp
, list
, head
.list
) {
579 tomoyo_collect_member(id
, &group
->member_list
);
580 if (!list_empty(&group
->member_list
) ||
581 atomic_read(&group
->head
.users
) > 0)
583 atomic_set(&group
->head
.users
,
584 TOMOYO_GC_IN_PROGRESS
);
585 tomoyo_try_to_gc(TOMOYO_ID_GROUP
,
590 for (i
= 0; i
< TOMOYO_MAX_HASH
; i
++) {
591 struct list_head
*list
= &tomoyo_name_list
[i
];
592 struct tomoyo_shared_acl_head
*ptr
;
593 struct tomoyo_shared_acl_head
*tmp
;
595 list_for_each_entry_safe(ptr
, tmp
, list
, list
) {
596 if (atomic_read(&ptr
->users
) > 0)
598 atomic_set(&ptr
->users
, TOMOYO_GC_IN_PROGRESS
);
599 tomoyo_try_to_gc(TOMOYO_ID_NAME
, &ptr
->list
);
602 mutex_unlock(&tomoyo_policy_lock
);
606 * tomoyo_gc_thread - Garbage collector thread function.
612 static int tomoyo_gc_thread(void *unused
)
614 /* Garbage collector thread is exclusive. */
615 static DEFINE_MUTEX(tomoyo_gc_mutex
);
617 if (!mutex_trylock(&tomoyo_gc_mutex
))
619 tomoyo_collect_entry();
621 struct tomoyo_io_buffer
*head
;
622 struct tomoyo_io_buffer
*tmp
;
624 spin_lock(&tomoyo_io_buffer_list_lock
);
625 list_for_each_entry_safe(head
, tmp
, &tomoyo_io_buffer_list
,
629 list_del(&head
->list
);
630 kfree(head
->read_buf
);
631 kfree(head
->write_buf
);
634 spin_unlock(&tomoyo_io_buffer_list_lock
);
636 mutex_unlock(&tomoyo_gc_mutex
);
638 /* This acts as do_exit(0). */
643 * tomoyo_notify_gc - Register/unregister /sys/kernel/security/tomoyo/ users.
645 * @head: Pointer to "struct tomoyo_io_buffer".
646 * @is_register: True if register, false if unregister.
650 void tomoyo_notify_gc(struct tomoyo_io_buffer
*head
, const bool is_register
)
652 bool is_write
= false;
654 spin_lock(&tomoyo_io_buffer_list_lock
);
657 list_add(&head
->list
, &tomoyo_io_buffer_list
);
659 is_write
= head
->write_buf
!= NULL
;
660 if (!--head
->users
) {
661 list_del(&head
->list
);
662 kfree(head
->read_buf
);
663 kfree(head
->write_buf
);
667 spin_unlock(&tomoyo_io_buffer_list_lock
);
669 kthread_run(tomoyo_gc_thread
, NULL
, "GC for TOMOYO");