gc.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*
  2. * security/tomoyo/gc.c
  3. *
  4. * Implementation of the Domain-Based Mandatory Access Control.
  5. *
  6. * Copyright (C) 2005-2010 NTT DATA CORPORATION
  7. *
  8. */
  9. #include "common.h"
  10. #include <linux/kthread.h>
  11. #include <linux/slab.h>
  12. struct tomoyo_gc {
  13. struct list_head list;
  14. int type;
  15. struct list_head *element;
  16. };
  17. static LIST_HEAD(tomoyo_gc_queue);
  18. static DEFINE_MUTEX(tomoyo_gc_mutex);
  19. /* Caller holds tomoyo_policy_lock mutex. */
  20. static bool tomoyo_add_to_gc(const int type, struct list_head *element)
  21. {
  22. struct tomoyo_gc *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
  23. if (!entry)
  24. return false;
  25. entry->type = type;
  26. entry->element = element;
  27. list_add(&entry->list, &tomoyo_gc_queue);
  28. list_del_rcu(element);
  29. return true;
  30. }
  31. static void tomoyo_del_transition_control(struct list_head *element)
  32. {
  33. struct tomoyo_transition_control *ptr =
  34. container_of(element, typeof(*ptr), head.list);
  35. tomoyo_put_name(ptr->domainname);
  36. tomoyo_put_name(ptr->program);
  37. }
  38. static void tomoyo_del_aggregator(struct list_head *element)
  39. {
  40. struct tomoyo_aggregator *ptr =
  41. container_of(element, typeof(*ptr), head.list);
  42. tomoyo_put_name(ptr->original_name);
  43. tomoyo_put_name(ptr->aggregated_name);
  44. }
  45. static void tomoyo_del_manager(struct list_head *element)
  46. {
  47. struct tomoyo_manager *ptr =
  48. container_of(element, typeof(*ptr), head.list);
  49. tomoyo_put_name(ptr->manager);
  50. }
  51. static void tomoyo_del_acl(struct list_head *element)
  52. {
  53. struct tomoyo_acl_info *acl =
  54. container_of(element, typeof(*acl), list);
  55. switch (acl->type) {
  56. case TOMOYO_TYPE_PATH_ACL:
  57. {
  58. struct tomoyo_path_acl *entry
  59. = container_of(acl, typeof(*entry), head);
  60. tomoyo_put_name_union(&entry->name);
  61. }
  62. break;
  63. case TOMOYO_TYPE_PATH2_ACL:
  64. {
  65. struct tomoyo_path2_acl *entry
  66. = container_of(acl, typeof(*entry), head);
  67. tomoyo_put_name_union(&entry->name1);
  68. tomoyo_put_name_union(&entry->name2);
  69. }
  70. break;
  71. case TOMOYO_TYPE_PATH_NUMBER_ACL:
  72. {
  73. struct tomoyo_path_number_acl *entry
  74. = container_of(acl, typeof(*entry), head);
  75. tomoyo_put_name_union(&entry->name);
  76. tomoyo_put_number_union(&entry->number);
  77. }
  78. break;
  79. case TOMOYO_TYPE_MKDEV_ACL:
  80. {
  81. struct tomoyo_mkdev_acl *entry
  82. = container_of(acl, typeof(*entry), head);
  83. tomoyo_put_name_union(&entry->name);
  84. tomoyo_put_number_union(&entry->mode);
  85. tomoyo_put_number_union(&entry->major);
  86. tomoyo_put_number_union(&entry->minor);
  87. }
  88. break;
  89. case TOMOYO_TYPE_MOUNT_ACL:
  90. {
  91. struct tomoyo_mount_acl *entry
  92. = container_of(acl, typeof(*entry), head);
  93. tomoyo_put_name_union(&entry->dev_name);
  94. tomoyo_put_name_union(&entry->dir_name);
  95. tomoyo_put_name_union(&entry->fs_type);
  96. tomoyo_put_number_union(&entry->flags);
  97. }
  98. break;
  99. }
  100. }
  101. static bool tomoyo_del_domain(struct list_head *element)
  102. {
  103. struct tomoyo_domain_info *domain =
  104. container_of(element, typeof(*domain), list);
  105. struct tomoyo_acl_info *acl;
  106. struct tomoyo_acl_info *tmp;
  107. /*
  108. * Since we don't protect whole execve() operation using SRCU,
  109. * we need to recheck domain->users at this point.
  110. *
  111. * (1) Reader starts SRCU section upon execve().
  112. * (2) Reader traverses tomoyo_domain_list and finds this domain.
  113. * (3) Writer marks this domain as deleted.
  114. * (4) Garbage collector removes this domain from tomoyo_domain_list
  115. * because this domain is marked as deleted and used by nobody.
  116. * (5) Reader saves reference to this domain into
  117. * "struct linux_binprm"->cred->security .
  118. * (6) Reader finishes SRCU section, although execve() operation has
  119. * not finished yet.
  120. * (7) Garbage collector waits for SRCU synchronization.
  121. * (8) Garbage collector kfree() this domain because this domain is
  122. * used by nobody.
  123. * (9) Reader finishes execve() operation and restores this domain from
  124. * "struct linux_binprm"->cred->security.
  125. *
  126. * By updating domain->users at (5), we can solve this race problem
  127. * by rechecking domain->users at (8).
  128. */
  129. if (atomic_read(&domain->users))
  130. return false;
  131. list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
  132. tomoyo_del_acl(&acl->list);
  133. tomoyo_memory_free(acl);
  134. }
  135. tomoyo_put_name(domain->domainname);
  136. return true;
  137. }
  138. static void tomoyo_del_name(struct list_head *element)
  139. {
  140. const struct tomoyo_name *ptr =
  141. container_of(element, typeof(*ptr), list);
  142. }
  143. static void tomoyo_del_path_group(struct list_head *element)
  144. {
  145. struct tomoyo_path_group *member =
  146. container_of(element, typeof(*member), head.list);
  147. tomoyo_put_name(member->member_name);
  148. }
  149. static void tomoyo_del_group(struct list_head *element)
  150. {
  151. struct tomoyo_group *group =
  152. container_of(element, typeof(*group), list);
  153. tomoyo_put_name(group->group_name);
  154. }
  155. static void tomoyo_del_number_group(struct list_head *element)
  156. {
  157. struct tomoyo_number_group *member =
  158. container_of(element, typeof(*member), head.list);
  159. }
  160. static bool tomoyo_collect_member(struct list_head *member_list, int id)
  161. {
  162. struct tomoyo_acl_head *member;
  163. list_for_each_entry(member, member_list, list) {
  164. if (!member->is_deleted)
  165. continue;
  166. if (!tomoyo_add_to_gc(id, &member->list))
  167. return false;
  168. }
  169. return true;
  170. }
  171. static bool tomoyo_collect_acl(struct tomoyo_domain_info *domain)
  172. {
  173. struct tomoyo_acl_info *acl;
  174. list_for_each_entry(acl, &domain->acl_info_list, list) {
  175. if (!acl->is_deleted)
  176. continue;
  177. if (!tomoyo_add_to_gc(TOMOYO_ID_ACL, &acl->list))
  178. return false;
  179. }
  180. return true;
  181. }
  182. static void tomoyo_collect_entry(void)
  183. {
  184. int i;
  185. if (mutex_lock_interruptible(&tomoyo_policy_lock))
  186. return;
  187. for (i = 0; i < TOMOYO_MAX_POLICY; i++) {
  188. if (!tomoyo_collect_member(&tomoyo_policy_list[i], i))
  189. goto unlock;
  190. }
  191. {
  192. struct tomoyo_domain_info *domain;
  193. list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
  194. if (!tomoyo_collect_acl(domain))
  195. goto unlock;
  196. if (!domain->is_deleted || atomic_read(&domain->users))
  197. continue;
  198. /*
  199. * Nobody is referring this domain. But somebody may
  200. * refer this domain after successful execve().
  201. * We recheck domain->users after SRCU synchronization.
  202. */
  203. if (!tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, &domain->list))
  204. goto unlock;
  205. }
  206. }
  207. for (i = 0; i < TOMOYO_MAX_HASH; i++) {
  208. struct tomoyo_name *ptr;
  209. list_for_each_entry_rcu(ptr, &tomoyo_name_list[i], list) {
  210. if (atomic_read(&ptr->users))
  211. continue;
  212. if (!tomoyo_add_to_gc(TOMOYO_ID_NAME, &ptr->list))
  213. goto unlock;
  214. }
  215. }
  216. for (i = 0; i < TOMOYO_MAX_GROUP; i++) {
  217. struct list_head *list = &tomoyo_group_list[i];
  218. int id;
  219. struct tomoyo_group *group;
  220. switch (i) {
  221. case 0:
  222. id = TOMOYO_ID_PATH_GROUP;
  223. break;
  224. default:
  225. id = TOMOYO_ID_NUMBER_GROUP;
  226. break;
  227. }
  228. list_for_each_entry(group, list, list) {
  229. if (!tomoyo_collect_member(&group->member_list, id))
  230. goto unlock;
  231. if (!list_empty(&group->member_list) ||
  232. atomic_read(&group->users))
  233. continue;
  234. if (!tomoyo_add_to_gc(TOMOYO_ID_GROUP, &group->list))
  235. goto unlock;
  236. }
  237. }
  238. unlock:
  239. mutex_unlock(&tomoyo_policy_lock);
  240. }
  241. static void tomoyo_kfree_entry(void)
  242. {
  243. struct tomoyo_gc *p;
  244. struct tomoyo_gc *tmp;
  245. list_for_each_entry_safe(p, tmp, &tomoyo_gc_queue, list) {
  246. struct list_head *element = p->element;
  247. switch (p->type) {
  248. case TOMOYO_ID_TRANSITION_CONTROL:
  249. tomoyo_del_transition_control(element);
  250. break;
  251. case TOMOYO_ID_AGGREGATOR:
  252. tomoyo_del_aggregator(element);
  253. break;
  254. case TOMOYO_ID_MANAGER:
  255. tomoyo_del_manager(element);
  256. break;
  257. case TOMOYO_ID_NAME:
  258. tomoyo_del_name(element);
  259. break;
  260. case TOMOYO_ID_ACL:
  261. tomoyo_del_acl(element);
  262. break;
  263. case TOMOYO_ID_DOMAIN:
  264. if (!tomoyo_del_domain(element))
  265. continue;
  266. break;
  267. case TOMOYO_ID_PATH_GROUP:
  268. tomoyo_del_path_group(element);
  269. break;
  270. case TOMOYO_ID_GROUP:
  271. tomoyo_del_group(element);
  272. break;
  273. case TOMOYO_ID_NUMBER_GROUP:
  274. tomoyo_del_number_group(element);
  275. break;
  276. }
  277. tomoyo_memory_free(element);
  278. list_del(&p->list);
  279. kfree(p);
  280. }
  281. }
  282. static int tomoyo_gc_thread(void *unused)
  283. {
  284. daemonize("GC for TOMOYO");
  285. if (mutex_trylock(&tomoyo_gc_mutex)) {
  286. int i;
  287. for (i = 0; i < 10; i++) {
  288. tomoyo_collect_entry();
  289. if (list_empty(&tomoyo_gc_queue))
  290. break;
  291. synchronize_srcu(&tomoyo_ss);
  292. tomoyo_kfree_entry();
  293. }
  294. mutex_unlock(&tomoyo_gc_mutex);
  295. }
  296. do_exit(0);
  297. }
  298. void tomoyo_run_gc(void)
  299. {
  300. struct task_struct *task = kthread_create(tomoyo_gc_thread, NULL,
  301. "GC for TOMOYO");
  302. if (!IS_ERR(task))
  303. wake_up_process(task);
  304. }