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