0001
0002
0003
0004
0005
0006
0007
0008 #include "common.h"
0009 #include <linux/kthread.h>
0010 #include <linux/slab.h>
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 static inline void tomoyo_memory_free(void *ptr)
0022 {
0023 tomoyo_memory_used[TOMOYO_MEMORY_POLICY] -= ksize(ptr);
0024 kfree(ptr);
0025 }
0026
0027
0028 static LIST_HEAD(tomoyo_io_buffer_list);
0029
0030 static DEFINE_SPINLOCK(tomoyo_io_buffer_list_lock);
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040 static bool tomoyo_struct_used_by_io_buffer(const struct list_head *element)
0041 {
0042 struct tomoyo_io_buffer *head;
0043 bool in_use = false;
0044
0045 spin_lock(&tomoyo_io_buffer_list_lock);
0046 list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
0047 head->users++;
0048 spin_unlock(&tomoyo_io_buffer_list_lock);
0049 mutex_lock(&head->io_sem);
0050 if (head->r.domain == element || head->r.group == element ||
0051 head->r.acl == element || &head->w.domain->list == element)
0052 in_use = true;
0053 mutex_unlock(&head->io_sem);
0054 spin_lock(&tomoyo_io_buffer_list_lock);
0055 head->users--;
0056 if (in_use)
0057 break;
0058 }
0059 spin_unlock(&tomoyo_io_buffer_list_lock);
0060 return in_use;
0061 }
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 static bool tomoyo_name_used_by_io_buffer(const char *string)
0072 {
0073 struct tomoyo_io_buffer *head;
0074 const size_t size = strlen(string) + 1;
0075 bool in_use = false;
0076
0077 spin_lock(&tomoyo_io_buffer_list_lock);
0078 list_for_each_entry(head, &tomoyo_io_buffer_list, list) {
0079 int i;
0080
0081 head->users++;
0082 spin_unlock(&tomoyo_io_buffer_list_lock);
0083 mutex_lock(&head->io_sem);
0084 for (i = 0; i < TOMOYO_MAX_IO_READ_QUEUE; i++) {
0085 const char *w = head->r.w[i];
0086
0087 if (w < string || w > string + size)
0088 continue;
0089 in_use = true;
0090 break;
0091 }
0092 mutex_unlock(&head->io_sem);
0093 spin_lock(&tomoyo_io_buffer_list_lock);
0094 head->users--;
0095 if (in_use)
0096 break;
0097 }
0098 spin_unlock(&tomoyo_io_buffer_list_lock);
0099 return in_use;
0100 }
0101
0102
0103
0104
0105
0106
0107
0108
0109 static inline void tomoyo_del_transition_control(struct list_head *element)
0110 {
0111 struct tomoyo_transition_control *ptr =
0112 container_of(element, typeof(*ptr), head.list);
0113
0114 tomoyo_put_name(ptr->domainname);
0115 tomoyo_put_name(ptr->program);
0116 }
0117
0118
0119
0120
0121
0122
0123
0124
0125 static inline void tomoyo_del_aggregator(struct list_head *element)
0126 {
0127 struct tomoyo_aggregator *ptr =
0128 container_of(element, typeof(*ptr), head.list);
0129
0130 tomoyo_put_name(ptr->original_name);
0131 tomoyo_put_name(ptr->aggregated_name);
0132 }
0133
0134
0135
0136
0137
0138
0139
0140
0141 static inline void tomoyo_del_manager(struct list_head *element)
0142 {
0143 struct tomoyo_manager *ptr =
0144 container_of(element, typeof(*ptr), head.list);
0145
0146 tomoyo_put_name(ptr->manager);
0147 }
0148
0149
0150
0151
0152
0153
0154
0155
0156 static void tomoyo_del_acl(struct list_head *element)
0157 {
0158 struct tomoyo_acl_info *acl =
0159 container_of(element, typeof(*acl), list);
0160
0161 tomoyo_put_condition(acl->cond);
0162 switch (acl->type) {
0163 case TOMOYO_TYPE_PATH_ACL:
0164 {
0165 struct tomoyo_path_acl *entry
0166 = container_of(acl, typeof(*entry), head);
0167 tomoyo_put_name_union(&entry->name);
0168 }
0169 break;
0170 case TOMOYO_TYPE_PATH2_ACL:
0171 {
0172 struct tomoyo_path2_acl *entry
0173 = container_of(acl, typeof(*entry), head);
0174 tomoyo_put_name_union(&entry->name1);
0175 tomoyo_put_name_union(&entry->name2);
0176 }
0177 break;
0178 case TOMOYO_TYPE_PATH_NUMBER_ACL:
0179 {
0180 struct tomoyo_path_number_acl *entry
0181 = container_of(acl, typeof(*entry), head);
0182 tomoyo_put_name_union(&entry->name);
0183 tomoyo_put_number_union(&entry->number);
0184 }
0185 break;
0186 case TOMOYO_TYPE_MKDEV_ACL:
0187 {
0188 struct tomoyo_mkdev_acl *entry
0189 = container_of(acl, typeof(*entry), head);
0190 tomoyo_put_name_union(&entry->name);
0191 tomoyo_put_number_union(&entry->mode);
0192 tomoyo_put_number_union(&entry->major);
0193 tomoyo_put_number_union(&entry->minor);
0194 }
0195 break;
0196 case TOMOYO_TYPE_MOUNT_ACL:
0197 {
0198 struct tomoyo_mount_acl *entry
0199 = container_of(acl, typeof(*entry), head);
0200 tomoyo_put_name_union(&entry->dev_name);
0201 tomoyo_put_name_union(&entry->dir_name);
0202 tomoyo_put_name_union(&entry->fs_type);
0203 tomoyo_put_number_union(&entry->flags);
0204 }
0205 break;
0206 case TOMOYO_TYPE_ENV_ACL:
0207 {
0208 struct tomoyo_env_acl *entry =
0209 container_of(acl, typeof(*entry), head);
0210
0211 tomoyo_put_name(entry->env);
0212 }
0213 break;
0214 case TOMOYO_TYPE_INET_ACL:
0215 {
0216 struct tomoyo_inet_acl *entry =
0217 container_of(acl, typeof(*entry), head);
0218
0219 tomoyo_put_group(entry->address.group);
0220 tomoyo_put_number_union(&entry->port);
0221 }
0222 break;
0223 case TOMOYO_TYPE_UNIX_ACL:
0224 {
0225 struct tomoyo_unix_acl *entry =
0226 container_of(acl, typeof(*entry), head);
0227
0228 tomoyo_put_name_union(&entry->name);
0229 }
0230 break;
0231 case TOMOYO_TYPE_MANUAL_TASK_ACL:
0232 {
0233 struct tomoyo_task_acl *entry =
0234 container_of(acl, typeof(*entry), head);
0235
0236 tomoyo_put_name(entry->domainname);
0237 }
0238 break;
0239 }
0240 }
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251 static inline void tomoyo_del_domain(struct list_head *element)
0252 {
0253 struct tomoyo_domain_info *domain =
0254 container_of(element, typeof(*domain), list);
0255 struct tomoyo_acl_info *acl;
0256 struct tomoyo_acl_info *tmp;
0257
0258
0259
0260
0261
0262
0263 list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
0264 tomoyo_del_acl(&acl->list);
0265 tomoyo_memory_free(acl);
0266 }
0267 tomoyo_put_name(domain->domainname);
0268 }
0269
0270
0271
0272
0273
0274
0275
0276
0277 void tomoyo_del_condition(struct list_head *element)
0278 {
0279 struct tomoyo_condition *cond = container_of(element, typeof(*cond),
0280 head.list);
0281 const u16 condc = cond->condc;
0282 const u16 numbers_count = cond->numbers_count;
0283 const u16 names_count = cond->names_count;
0284 const u16 argc = cond->argc;
0285 const u16 envc = cond->envc;
0286 unsigned int i;
0287 const struct tomoyo_condition_element *condp
0288 = (const struct tomoyo_condition_element *) (cond + 1);
0289 struct tomoyo_number_union *numbers_p
0290 = (struct tomoyo_number_union *) (condp + condc);
0291 struct tomoyo_name_union *names_p
0292 = (struct tomoyo_name_union *) (numbers_p + numbers_count);
0293 const struct tomoyo_argv *argv
0294 = (const struct tomoyo_argv *) (names_p + names_count);
0295 const struct tomoyo_envp *envp
0296 = (const struct tomoyo_envp *) (argv + argc);
0297
0298 for (i = 0; i < numbers_count; i++)
0299 tomoyo_put_number_union(numbers_p++);
0300 for (i = 0; i < names_count; i++)
0301 tomoyo_put_name_union(names_p++);
0302 for (i = 0; i < argc; argv++, i++)
0303 tomoyo_put_name(argv->value);
0304 for (i = 0; i < envc; envp++, i++) {
0305 tomoyo_put_name(envp->name);
0306 tomoyo_put_name(envp->value);
0307 }
0308 }
0309
0310
0311
0312
0313
0314
0315
0316
0317 static inline void tomoyo_del_name(struct list_head *element)
0318 {
0319
0320 }
0321
0322
0323
0324
0325
0326
0327
0328
0329 static inline void tomoyo_del_path_group(struct list_head *element)
0330 {
0331 struct tomoyo_path_group *member =
0332 container_of(element, typeof(*member), head.list);
0333
0334 tomoyo_put_name(member->member_name);
0335 }
0336
0337
0338
0339
0340
0341
0342
0343
0344 static inline void tomoyo_del_group(struct list_head *element)
0345 {
0346 struct tomoyo_group *group =
0347 container_of(element, typeof(*group), head.list);
0348
0349 tomoyo_put_name(group->group_name);
0350 }
0351
0352
0353
0354
0355
0356
0357
0358
0359 static inline void tomoyo_del_address_group(struct list_head *element)
0360 {
0361
0362 }
0363
0364
0365
0366
0367
0368
0369
0370
0371 static inline void tomoyo_del_number_group(struct list_head *element)
0372 {
0373
0374 }
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386 static void tomoyo_try_to_gc(const enum tomoyo_policy_id type,
0387 struct list_head *element)
0388 {
0389
0390
0391
0392
0393
0394
0395 __list_del_entry(element);
0396 mutex_unlock(&tomoyo_policy_lock);
0397 synchronize_srcu(&tomoyo_ss);
0398
0399
0400
0401
0402
0403
0404
0405 if (tomoyo_struct_used_by_io_buffer(element))
0406 goto reinject;
0407 switch (type) {
0408 case TOMOYO_ID_TRANSITION_CONTROL:
0409 tomoyo_del_transition_control(element);
0410 break;
0411 case TOMOYO_ID_MANAGER:
0412 tomoyo_del_manager(element);
0413 break;
0414 case TOMOYO_ID_AGGREGATOR:
0415 tomoyo_del_aggregator(element);
0416 break;
0417 case TOMOYO_ID_GROUP:
0418 tomoyo_del_group(element);
0419 break;
0420 case TOMOYO_ID_PATH_GROUP:
0421 tomoyo_del_path_group(element);
0422 break;
0423 case TOMOYO_ID_ADDRESS_GROUP:
0424 tomoyo_del_address_group(element);
0425 break;
0426 case TOMOYO_ID_NUMBER_GROUP:
0427 tomoyo_del_number_group(element);
0428 break;
0429 case TOMOYO_ID_CONDITION:
0430 tomoyo_del_condition(element);
0431 break;
0432 case TOMOYO_ID_NAME:
0433
0434
0435
0436
0437 if (tomoyo_name_used_by_io_buffer
0438 (container_of(element, typeof(struct tomoyo_name),
0439 head.list)->entry.name))
0440 goto reinject;
0441 tomoyo_del_name(element);
0442 break;
0443 case TOMOYO_ID_ACL:
0444 tomoyo_del_acl(element);
0445 break;
0446 case TOMOYO_ID_DOMAIN:
0447
0448
0449
0450
0451 if (atomic_read(&container_of
0452 (element, typeof(struct tomoyo_domain_info),
0453 list)->users))
0454 goto reinject;
0455 break;
0456 case TOMOYO_MAX_POLICY:
0457 break;
0458 }
0459 mutex_lock(&tomoyo_policy_lock);
0460 if (type == TOMOYO_ID_DOMAIN)
0461 tomoyo_del_domain(element);
0462 tomoyo_memory_free(element);
0463 return;
0464 reinject:
0465
0466
0467
0468
0469
0470
0471
0472
0473 mutex_lock(&tomoyo_policy_lock);
0474 list_add_rcu(element, element->prev);
0475 }
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485 static void tomoyo_collect_member(const enum tomoyo_policy_id id,
0486 struct list_head *member_list)
0487 {
0488 struct tomoyo_acl_head *member;
0489 struct tomoyo_acl_head *tmp;
0490
0491 list_for_each_entry_safe(member, tmp, member_list, list) {
0492 if (!member->is_deleted)
0493 continue;
0494 member->is_deleted = TOMOYO_GC_IN_PROGRESS;
0495 tomoyo_try_to_gc(id, &member->list);
0496 }
0497 }
0498
0499
0500
0501
0502
0503
0504
0505
0506 static void tomoyo_collect_acl(struct list_head *list)
0507 {
0508 struct tomoyo_acl_info *acl;
0509 struct tomoyo_acl_info *tmp;
0510
0511 list_for_each_entry_safe(acl, tmp, list, list) {
0512 if (!acl->is_deleted)
0513 continue;
0514 acl->is_deleted = TOMOYO_GC_IN_PROGRESS;
0515 tomoyo_try_to_gc(TOMOYO_ID_ACL, &acl->list);
0516 }
0517 }
0518
0519
0520
0521
0522
0523
0524 static void tomoyo_collect_entry(void)
0525 {
0526 int i;
0527 enum tomoyo_policy_id id;
0528 struct tomoyo_policy_namespace *ns;
0529
0530 mutex_lock(&tomoyo_policy_lock);
0531 {
0532 struct tomoyo_domain_info *domain;
0533 struct tomoyo_domain_info *tmp;
0534
0535 list_for_each_entry_safe(domain, tmp, &tomoyo_domain_list,
0536 list) {
0537 tomoyo_collect_acl(&domain->acl_info_list);
0538 if (!domain->is_deleted || atomic_read(&domain->users))
0539 continue;
0540 tomoyo_try_to_gc(TOMOYO_ID_DOMAIN, &domain->list);
0541 }
0542 }
0543 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
0544 for (id = 0; id < TOMOYO_MAX_POLICY; id++)
0545 tomoyo_collect_member(id, &ns->policy_list[id]);
0546 for (i = 0; i < TOMOYO_MAX_ACL_GROUPS; i++)
0547 tomoyo_collect_acl(&ns->acl_group[i]);
0548 }
0549 {
0550 struct tomoyo_shared_acl_head *ptr;
0551 struct tomoyo_shared_acl_head *tmp;
0552
0553 list_for_each_entry_safe(ptr, tmp, &tomoyo_condition_list,
0554 list) {
0555 if (atomic_read(&ptr->users) > 0)
0556 continue;
0557 atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS);
0558 tomoyo_try_to_gc(TOMOYO_ID_CONDITION, &ptr->list);
0559 }
0560 }
0561 list_for_each_entry(ns, &tomoyo_namespace_list, namespace_list) {
0562 for (i = 0; i < TOMOYO_MAX_GROUP; i++) {
0563 struct list_head *list = &ns->group_list[i];
0564 struct tomoyo_group *group;
0565 struct tomoyo_group *tmp;
0566
0567 switch (i) {
0568 case 0:
0569 id = TOMOYO_ID_PATH_GROUP;
0570 break;
0571 case 1:
0572 id = TOMOYO_ID_NUMBER_GROUP;
0573 break;
0574 default:
0575 id = TOMOYO_ID_ADDRESS_GROUP;
0576 break;
0577 }
0578 list_for_each_entry_safe(group, tmp, list, head.list) {
0579 tomoyo_collect_member(id, &group->member_list);
0580 if (!list_empty(&group->member_list) ||
0581 atomic_read(&group->head.users) > 0)
0582 continue;
0583 atomic_set(&group->head.users,
0584 TOMOYO_GC_IN_PROGRESS);
0585 tomoyo_try_to_gc(TOMOYO_ID_GROUP,
0586 &group->head.list);
0587 }
0588 }
0589 }
0590 for (i = 0; i < TOMOYO_MAX_HASH; i++) {
0591 struct list_head *list = &tomoyo_name_list[i];
0592 struct tomoyo_shared_acl_head *ptr;
0593 struct tomoyo_shared_acl_head *tmp;
0594
0595 list_for_each_entry_safe(ptr, tmp, list, list) {
0596 if (atomic_read(&ptr->users) > 0)
0597 continue;
0598 atomic_set(&ptr->users, TOMOYO_GC_IN_PROGRESS);
0599 tomoyo_try_to_gc(TOMOYO_ID_NAME, &ptr->list);
0600 }
0601 }
0602 mutex_unlock(&tomoyo_policy_lock);
0603 }
0604
0605
0606
0607
0608
0609
0610
0611
0612 static int tomoyo_gc_thread(void *unused)
0613 {
0614
0615 static DEFINE_MUTEX(tomoyo_gc_mutex);
0616
0617 if (!mutex_trylock(&tomoyo_gc_mutex))
0618 goto out;
0619 tomoyo_collect_entry();
0620 {
0621 struct tomoyo_io_buffer *head;
0622 struct tomoyo_io_buffer *tmp;
0623
0624 spin_lock(&tomoyo_io_buffer_list_lock);
0625 list_for_each_entry_safe(head, tmp, &tomoyo_io_buffer_list,
0626 list) {
0627 if (head->users)
0628 continue;
0629 list_del(&head->list);
0630 kfree(head->read_buf);
0631 kfree(head->write_buf);
0632 kfree(head);
0633 }
0634 spin_unlock(&tomoyo_io_buffer_list_lock);
0635 }
0636 mutex_unlock(&tomoyo_gc_mutex);
0637 out:
0638
0639 return 0;
0640 }
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650 void tomoyo_notify_gc(struct tomoyo_io_buffer *head, const bool is_register)
0651 {
0652 bool is_write = false;
0653
0654 spin_lock(&tomoyo_io_buffer_list_lock);
0655 if (is_register) {
0656 head->users = 1;
0657 list_add(&head->list, &tomoyo_io_buffer_list);
0658 } else {
0659 is_write = head->write_buf != NULL;
0660 if (!--head->users) {
0661 list_del(&head->list);
0662 kfree(head->read_buf);
0663 kfree(head->write_buf);
0664 kfree(head);
0665 }
0666 }
0667 spin_unlock(&tomoyo_io_buffer_list_lock);
0668 if (is_write)
0669 kthread_run(tomoyo_gc_thread, NULL, "GC for TOMOYO");
0670 }