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