gc.c revision a427fd14d3edf6396c4b9638dbc8e2972afaa05b
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 } 225} 226 227/** 228 * tomoyo_del_domain - Delete members in "struct tomoyo_domain_info". 229 * 230 * @element: Pointer to "struct list_head". 231 * 232 * Returns nothing. 233 * 234 * Caller holds tomoyo_policy_lock mutex. 235 */ 236static inline void tomoyo_del_domain(struct list_head *element) 237{ 238 struct tomoyo_domain_info *domain = 239 container_of(element, typeof(*domain), list); 240 struct tomoyo_acl_info *acl; 241 struct tomoyo_acl_info *tmp; 242 /* 243 * Since this domain is referenced from neither 244 * "struct tomoyo_io_buffer" nor "struct cred"->security, we can delete 245 * elements without checking for is_deleted flag. 246 */ 247 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) { 248 tomoyo_del_acl(&acl->list); 249 tomoyo_memory_free(acl); 250 } 251 tomoyo_put_name(domain->domainname); 252} 253 254/** 255 * tomoyo_del_condition - Delete members in "struct tomoyo_condition". 256 * 257 * @element: Pointer to "struct list_head". 258 * 259 * Returns nothing. 260 */ 261void tomoyo_del_condition(struct list_head *element) 262{ 263 struct tomoyo_condition *cond = container_of(element, typeof(*cond), 264 head.list); 265 const u16 condc = cond->condc; 266 const u16 numbers_count = cond->numbers_count; 267 const u16 names_count = cond->names_count; 268 const u16 argc = cond->argc; 269 const u16 envc = cond->envc; 270 unsigned int i; 271 const struct tomoyo_condition_element *condp 272 = (const struct tomoyo_condition_element *) (cond + 1); 273 struct tomoyo_number_union *numbers_p 274 = (struct tomoyo_number_union *) (condp + condc); 275 struct tomoyo_name_union *names_p 276 = (struct tomoyo_name_union *) (numbers_p + numbers_count); 277 const struct tomoyo_argv *argv 278 = (const struct tomoyo_argv *) (names_p + names_count); 279 const struct tomoyo_envp *envp 280 = (const struct tomoyo_envp *) (argv + argc); 281 for (i = 0; i < numbers_count; i++) 282 tomoyo_put_number_union(numbers_p++); 283 for (i = 0; i < names_count; i++) 284 tomoyo_put_name_union(names_p++); 285 for (i = 0; i < argc; argv++, i++) 286 tomoyo_put_name(argv->value); 287 for (i = 0; i < envc; envp++, i++) { 288 tomoyo_put_name(envp->name); 289 tomoyo_put_name(envp->value); 290 } 291} 292 293/** 294 * tomoyo_del_name - Delete members in "struct tomoyo_name". 295 * 296 * @element: Pointer to "struct list_head". 297 * 298 * Returns nothing. 299 */ 300static inline void tomoyo_del_name(struct list_head *element) 301{ 302 /* Nothing to do. */ 303} 304 305/** 306 * tomoyo_del_path_group - Delete members in "struct tomoyo_path_group". 307 * 308 * @element: Pointer to "struct list_head". 309 * 310 * Returns nothing. 311 */ 312static inline void tomoyo_del_path_group(struct list_head *element) 313{ 314 struct tomoyo_path_group *member = 315 container_of(element, typeof(*member), head.list); 316 tomoyo_put_name(member->member_name); 317} 318 319/** 320 * tomoyo_del_group - Delete "struct tomoyo_group". 321 * 322 * @element: Pointer to "struct list_head". 323 * 324 * Returns nothing. 325 */ 326static inline void tomoyo_del_group(struct list_head *element) 327{ 328 struct tomoyo_group *group = 329 container_of(element, typeof(*group), head.list); 330 tomoyo_put_name(group->group_name); 331} 332 333/** 334 * tomoyo_del_address_group - Delete members in "struct tomoyo_address_group". 335 * 336 * @element: Pointer to "struct list_head". 337 * 338 * Returns nothing. 339 */ 340static inline void tomoyo_del_address_group(struct list_head *element) 341{ 342 /* Nothing to do. */ 343} 344 345/** 346 * tomoyo_del_number_group - Delete members in "struct tomoyo_number_group". 347 * 348 * @element: Pointer to "struct list_head". 349 * 350 * Returns nothing. 351 */ 352static inline void tomoyo_del_number_group(struct list_head *element) 353{ 354 /* Nothing to do. */ 355} 356 357/** 358 * tomoyo_try_to_gc - Try to kfree() an entry. 359 * 360 * @type: One of values in "enum tomoyo_policy_id". 361 * @element: Pointer to "struct list_head". 362 * 363 * Returns nothing. 364 * 365 * Caller holds tomoyo_policy_lock mutex. 366 */ 367static void tomoyo_try_to_gc(const enum tomoyo_policy_id type, 368 struct list_head *element) 369{ 370 /* 371 * __list_del_entry() guarantees that the list element became no longer 372 * reachable from the list which the element was originally on (e.g. 373 * tomoyo_domain_list). Also, synchronize_srcu() guarantees that the 374 * list element became no longer referenced by syscall users. 375 */ 376 __list_del_entry(element); 377 mutex_unlock(&tomoyo_policy_lock); 378 synchronize_srcu(&tomoyo_ss); 379 /* 380 * However, there are two users which may still be using the list 381 * element. We need to defer until both users forget this element. 382 * 383 * Don't kfree() until "struct tomoyo_io_buffer"->r.{domain,group,acl} 384 * and "struct tomoyo_io_buffer"->w.domain forget this element. 385 */ 386 if (tomoyo_struct_used_by_io_buffer(element)) 387 goto reinject; 388 switch (type) { 389 case TOMOYO_ID_TRANSITION_CONTROL: 390 tomoyo_del_transition_control(element); 391 break; 392 case TOMOYO_ID_MANAGER: 393 tomoyo_del_manager(element); 394 break; 395 case TOMOYO_ID_AGGREGATOR: 396 tomoyo_del_aggregator(element); 397 break; 398 case TOMOYO_ID_GROUP: 399 tomoyo_del_group(element); 400 break; 401 case TOMOYO_ID_PATH_GROUP: 402 tomoyo_del_path_group(element); 403 break; 404 case TOMOYO_ID_ADDRESS_GROUP: 405 tomoyo_del_address_group(element); 406 break; 407 case TOMOYO_ID_NUMBER_GROUP: 408 tomoyo_del_number_group(element); 409 break; 410 case TOMOYO_ID_CONDITION: 411 tomoyo_del_condition(element); 412 break; 413 case TOMOYO_ID_NAME: 414 /* 415 * Don't kfree() until all "struct tomoyo_io_buffer"->r.w[] 416 * forget this element. 417 */ 418 if (tomoyo_name_used_by_io_buffer 419 (container_of(element, typeof(struct tomoyo_name), 420 head.list)->entry.name)) 421 goto reinject; 422 tomoyo_del_name(element); 423 break; 424 case TOMOYO_ID_ACL: 425 tomoyo_del_acl(element); 426 break; 427 case TOMOYO_ID_DOMAIN: 428 /* 429 * Don't kfree() until all "struct cred"->security forget this 430 * element. 431 */ 432 if (atomic_read(&container_of 433 (element, typeof(struct tomoyo_domain_info), 434 list)->users)) 435 goto reinject; 436 break; 437 case TOMOYO_MAX_POLICY: 438 break; 439 } 440 mutex_lock(&tomoyo_policy_lock); 441 if (type == TOMOYO_ID_DOMAIN) 442 tomoyo_del_domain(element); 443 tomoyo_memory_free(element); 444 return; 445reinject: 446 /* 447 * We can safely reinject this element here bacause 448 * (1) Appending list elements and removing list elements are protected 449 * by tomoyo_policy_lock mutex. 450 * (2) Only this function removes list elements and this function is 451 * exclusively executed by tomoyo_gc_mutex mutex. 452 * are true. 453 */ 454 mutex_lock(&tomoyo_policy_lock); 455 list_add_rcu(element, element->prev); 456} 457 458/** 459 * tomoyo_collect_member - Delete elements with "struct tomoyo_acl_head". 460 * 461 * @id: One of values in "enum tomoyo_policy_id". 462 * @member_list: Pointer to "struct list_head". 463 * 464 * Returns nothing. 465 */ 466static void tomoyo_collect_member(const enum tomoyo_policy_id id, 467 struct list_head *member_list) 468{ 469 struct tomoyo_acl_head *member; 470 struct tomoyo_acl_head *tmp; 471 list_for_each_entry_safe(member, tmp, member_list, list) { 472 if (!member->is_deleted) 473 continue; 474 member->is_deleted = TOMOYO_GC_IN_PROGRESS; 475 tomoyo_try_to_gc(id, &member->list); 476 } 477} 478 479/** 480 * tomoyo_collect_acl - Delete elements in "struct tomoyo_domain_info". 481 * 482 * @list: Pointer to "struct list_head". 483 * 484 * Returns nothing. 485 */ 486static void tomoyo_collect_acl(struct list_head *list) 487{ 488 struct tomoyo_acl_info *acl; 489 struct tomoyo_acl_info *tmp; 490 list_for_each_entry_safe(acl, tmp, list, list) { 491 if (!acl->is_deleted) 492 continue; 493 acl->is_deleted = TOMOYO_GC_IN_PROGRESS; 494 tomoyo_try_to_gc(TOMOYO_ID_ACL, &acl->list); 495 } 496} 497 498/** 499 * tomoyo_collect_entry - Try to kfree() deleted elements. 500 * 501 * Returns nothing. 502 */ 503static void tomoyo_collect_entry(void) 504{ 505 int i; 506 enum tomoyo_policy_id id; 507 struct tomoyo_policy_namespace *ns; 508 mutex_lock(&tomoyo_policy_lock); 509 { 510 struct tomoyo_domain_info *domain; 511 struct tomoyo_domain_info *tmp; 512 list_for_each_entry_safe(domain, tmp, &tomoyo_domain_list, 513 list) { 514 tomoyo_collect_acl(&domain->acl_info_list); 515 if (!domain->is_deleted || atomic_read(&domain->users)) 516 continue; 517 tomoyo_try_to_gc(TOMOYO_ID_DOMAIN, &domain->list); 518 } 519 } 520 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) { 521 for (id = 0; id < TOMOYO_MAX_POLICY; id++) 522 tomoyo_collect_member(id, &ns->policy_list[id]); 523 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++) 524 tomoyo_collect_acl(&ns->acl_group[i]); 525 } 526 { 527 struct tomoyo_shared_acl_head *ptr; 528 struct tomoyo_shared_acl_head *tmp; 529 list_for_each_entry_safe(ptr, tmp, &tomoyo_condition_list, 530 list) { 531 if (atomic_read(&ptr->users) > 0) 532 continue; 533 atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS); 534 tomoyo_try_to_gc(TOMOYO_ID_CONDITION, &ptr->list); 535 } 536 } 537 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) { 538 for (i = 0; i < TOMOYO_MAX_GROUP; i++) { 539 struct list_head *list = &ns->group_list[i]; 540 struct tomoyo_group *group; 541 struct tomoyo_group *tmp; 542 switch (i) { 543 case 0: 544 id = TOMOYO_ID_PATH_GROUP; 545 break; 546 case 1: 547 id = TOMOYO_ID_NUMBER_GROUP; 548 break; 549 default: 550 id = TOMOYO_ID_ADDRESS_GROUP; 551 break; 552 } 553 list_for_each_entry_safe(group, tmp, list, head.list) { 554 tomoyo_collect_member(id, &group->member_list); 555 if (!list_empty(&group->member_list) || 556 atomic_read(&group->head.users) > 0) 557 continue; 558 atomic_set(&group->head.users, 559 TOMOYO_GC_IN_PROGRESS); 560 tomoyo_try_to_gc(TOMOYO_ID_GROUP, 561 &group->head.list); 562 } 563 } 564 } 565 for (i = 0; i < TOMOYO_MAX_HASH; i++) { 566 struct list_head *list = &tomoyo_name_list[i]; 567 struct tomoyo_shared_acl_head *ptr; 568 struct tomoyo_shared_acl_head *tmp; 569 list_for_each_entry_safe(ptr, tmp, list, list) { 570 if (atomic_read(&ptr->users) > 0) 571 continue; 572 atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS); 573 tomoyo_try_to_gc(TOMOYO_ID_NAME, &ptr->list); 574 } 575 } 576 mutex_unlock(&tomoyo_policy_lock); 577} 578 579/** 580 * tomoyo_gc_thread - Garbage collector thread function. 581 * 582 * @unused: Unused. 583 * 584 * Returns 0. 585 */ 586static int tomoyo_gc_thread(void *unused) 587{ 588 /* Garbage collector thread is exclusive. */ 589 static DEFINE_MUTEX(tomoyo_gc_mutex); 590 if (!mutex_trylock(&tomoyo_gc_mutex)) 591 goto out; 592 tomoyo_collect_entry(); 593 { 594 struct tomoyo_io_buffer *head; 595 struct tomoyo_io_buffer *tmp; 596 597 spin_lock(&tomoyo_io_buffer_list_lock); 598 list_for_each_entry_safe(head, tmp, &tomoyo_io_buffer_list, 599 list) { 600 if (head->users) 601 continue; 602 list_del(&head->list); 603 kfree(head->read_buf); 604 kfree(head->write_buf); 605 kfree(head); 606 } 607 spin_unlock(&tomoyo_io_buffer_list_lock); 608 } 609 mutex_unlock(&tomoyo_gc_mutex); 610out: 611 /* This acts as do_exit(0). */ 612 return 0; 613} 614 615/** 616 * tomoyo_notify_gc - Register/unregister /sys/kernel/security/tomoyo/ users. 617 * 618 * @head: Pointer to "struct tomoyo_io_buffer". 619 * @is_register: True if register, false if unregister. 620 * 621 * Returns nothing. 622 */ 623void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register) 624{ 625 bool is_write = false; 626 627 spin_lock(&tomoyo_io_buffer_list_lock); 628 if (is_register) { 629 head->users = 1; 630 list_add(&head->list, &tomoyo_io_buffer_list); 631 } else { 632 is_write = head->write_buf != NULL; 633 if (!--head->users) { 634 list_del(&head->list); 635 kfree(head->read_buf); 636 kfree(head->write_buf); 637 kfree(head); 638 } 639 } 640 spin_unlock(&tomoyo_io_buffer_list_lock); 641 if (is_write) { 642 struct task_struct *task = kthread_create(tomoyo_gc_thread, 643 NULL, 644 "GC for TOMOYO"); 645 if (!IS_ERR(task)) 646 wake_up_process(task); 647 } 648} 649