/security/tomoyo/gc.c

https://bitbucket.org/abioy/linux · C · 371 lines · 315 code · 20 blank · 36 comment · 34 complexity · 7a7d559238904b8877173c0d2297a903 MD5 · raw file

  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. enum tomoyo_gc_id {
  13. TOMOYO_ID_DOMAIN_INITIALIZER,
  14. TOMOYO_ID_DOMAIN_KEEPER,
  15. TOMOYO_ID_ALIAS,
  16. TOMOYO_ID_GLOBALLY_READABLE,
  17. TOMOYO_ID_PATTERN,
  18. TOMOYO_ID_NO_REWRITE,
  19. TOMOYO_ID_MANAGER,
  20. TOMOYO_ID_NAME,
  21. TOMOYO_ID_ACL,
  22. TOMOYO_ID_DOMAIN
  23. };
  24. struct tomoyo_gc_entry {
  25. struct list_head list;
  26. int type;
  27. void *element;
  28. };
  29. static LIST_HEAD(tomoyo_gc_queue);
  30. static DEFINE_MUTEX(tomoyo_gc_mutex);
  31. /* Caller holds tomoyo_policy_lock mutex. */
  32. static bool tomoyo_add_to_gc(const int type, void *element)
  33. {
  34. struct tomoyo_gc_entry *entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
  35. if (!entry)
  36. return false;
  37. entry->type = type;
  38. entry->element = element;
  39. list_add(&entry->list, &tomoyo_gc_queue);
  40. return true;
  41. }
  42. static void tomoyo_del_allow_read
  43. (struct tomoyo_globally_readable_file_entry *ptr)
  44. {
  45. tomoyo_put_name(ptr->filename);
  46. }
  47. static void tomoyo_del_file_pattern(struct tomoyo_pattern_entry *ptr)
  48. {
  49. tomoyo_put_name(ptr->pattern);
  50. }
  51. static void tomoyo_del_no_rewrite(struct tomoyo_no_rewrite_entry *ptr)
  52. {
  53. tomoyo_put_name(ptr->pattern);
  54. }
  55. static void tomoyo_del_domain_initializer
  56. (struct tomoyo_domain_initializer_entry *ptr)
  57. {
  58. tomoyo_put_name(ptr->domainname);
  59. tomoyo_put_name(ptr->program);
  60. }
  61. static void tomoyo_del_domain_keeper(struct tomoyo_domain_keeper_entry *ptr)
  62. {
  63. tomoyo_put_name(ptr->domainname);
  64. tomoyo_put_name(ptr->program);
  65. }
  66. static void tomoyo_del_alias(struct tomoyo_alias_entry *ptr)
  67. {
  68. tomoyo_put_name(ptr->original_name);
  69. tomoyo_put_name(ptr->aliased_name);
  70. }
  71. static void tomoyo_del_manager(struct tomoyo_policy_manager_entry *ptr)
  72. {
  73. tomoyo_put_name(ptr->manager);
  74. }
  75. static void tomoyo_del_acl(struct tomoyo_acl_info *acl)
  76. {
  77. switch (acl->type) {
  78. case TOMOYO_TYPE_PATH_ACL:
  79. {
  80. struct tomoyo_path_acl *entry
  81. = container_of(acl, typeof(*entry), head);
  82. tomoyo_put_name(entry->filename);
  83. }
  84. break;
  85. case TOMOYO_TYPE_PATH2_ACL:
  86. {
  87. struct tomoyo_path2_acl *entry
  88. = container_of(acl, typeof(*entry), head);
  89. tomoyo_put_name(entry->filename1);
  90. tomoyo_put_name(entry->filename2);
  91. }
  92. break;
  93. default:
  94. printk(KERN_WARNING "Unknown type\n");
  95. break;
  96. }
  97. }
  98. static bool tomoyo_del_domain(struct tomoyo_domain_info *domain)
  99. {
  100. struct tomoyo_acl_info *acl;
  101. struct tomoyo_acl_info *tmp;
  102. /*
  103. * Since we don't protect whole execve() operation using SRCU,
  104. * we need to recheck domain->users at this point.
  105. *
  106. * (1) Reader starts SRCU section upon execve().
  107. * (2) Reader traverses tomoyo_domain_list and finds this domain.
  108. * (3) Writer marks this domain as deleted.
  109. * (4) Garbage collector removes this domain from tomoyo_domain_list
  110. * because this domain is marked as deleted and used by nobody.
  111. * (5) Reader saves reference to this domain into
  112. * "struct linux_binprm"->cred->security .
  113. * (6) Reader finishes SRCU section, although execve() operation has
  114. * not finished yet.
  115. * (7) Garbage collector waits for SRCU synchronization.
  116. * (8) Garbage collector kfree() this domain because this domain is
  117. * used by nobody.
  118. * (9) Reader finishes execve() operation and restores this domain from
  119. * "struct linux_binprm"->cred->security.
  120. *
  121. * By updating domain->users at (5), we can solve this race problem
  122. * by rechecking domain->users at (8).
  123. */
  124. if (atomic_read(&domain->users))
  125. return false;
  126. list_for_each_entry_safe(acl, tmp, &domain->acl_info_list, list) {
  127. tomoyo_del_acl(acl);
  128. tomoyo_memory_free(acl);
  129. }
  130. tomoyo_put_name(domain->domainname);
  131. return true;
  132. }
  133. static void tomoyo_del_name(const struct tomoyo_name_entry *ptr)
  134. {
  135. }
  136. static void tomoyo_collect_entry(void)
  137. {
  138. mutex_lock(&tomoyo_policy_lock);
  139. {
  140. struct tomoyo_globally_readable_file_entry *ptr;
  141. list_for_each_entry_rcu(ptr, &tomoyo_globally_readable_list,
  142. list) {
  143. if (!ptr->is_deleted)
  144. continue;
  145. if (tomoyo_add_to_gc(TOMOYO_ID_GLOBALLY_READABLE, ptr))
  146. list_del_rcu(&ptr->list);
  147. else
  148. break;
  149. }
  150. }
  151. {
  152. struct tomoyo_pattern_entry *ptr;
  153. list_for_each_entry_rcu(ptr, &tomoyo_pattern_list, list) {
  154. if (!ptr->is_deleted)
  155. continue;
  156. if (tomoyo_add_to_gc(TOMOYO_ID_PATTERN, ptr))
  157. list_del_rcu(&ptr->list);
  158. else
  159. break;
  160. }
  161. }
  162. {
  163. struct tomoyo_no_rewrite_entry *ptr;
  164. list_for_each_entry_rcu(ptr, &tomoyo_no_rewrite_list, list) {
  165. if (!ptr->is_deleted)
  166. continue;
  167. if (tomoyo_add_to_gc(TOMOYO_ID_NO_REWRITE, ptr))
  168. list_del_rcu(&ptr->list);
  169. else
  170. break;
  171. }
  172. }
  173. {
  174. struct tomoyo_domain_initializer_entry *ptr;
  175. list_for_each_entry_rcu(ptr, &tomoyo_domain_initializer_list,
  176. list) {
  177. if (!ptr->is_deleted)
  178. continue;
  179. if (tomoyo_add_to_gc(TOMOYO_ID_DOMAIN_INITIALIZER, ptr))
  180. list_del_rcu(&ptr->list);
  181. else
  182. break;
  183. }
  184. }
  185. {
  186. struct tomoyo_domain_keeper_entry *ptr;
  187. list_for_each_entry_rcu(ptr, &tomoyo_domain_keeper_list, list) {
  188. if (!ptr->is_deleted)
  189. continue;
  190. if (tomoyo_add_to_gc(TOMOYO_ID_DOMAIN_KEEPER, ptr))
  191. list_del_rcu(&ptr->list);
  192. else
  193. break;
  194. }
  195. }
  196. {
  197. struct tomoyo_alias_entry *ptr;
  198. list_for_each_entry_rcu(ptr, &tomoyo_alias_list, list) {
  199. if (!ptr->is_deleted)
  200. continue;
  201. if (tomoyo_add_to_gc(TOMOYO_ID_ALIAS, ptr))
  202. list_del_rcu(&ptr->list);
  203. else
  204. break;
  205. }
  206. }
  207. {
  208. struct tomoyo_policy_manager_entry *ptr;
  209. list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list,
  210. list) {
  211. if (!ptr->is_deleted)
  212. continue;
  213. if (tomoyo_add_to_gc(TOMOYO_ID_MANAGER, ptr))
  214. list_del_rcu(&ptr->list);
  215. else
  216. break;
  217. }
  218. }
  219. {
  220. struct tomoyo_domain_info *domain;
  221. list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
  222. struct tomoyo_acl_info *acl;
  223. list_for_each_entry_rcu(acl, &domain->acl_info_list,
  224. list) {
  225. switch (acl->type) {
  226. case TOMOYO_TYPE_PATH_ACL:
  227. if (container_of(acl,
  228. struct tomoyo_path_acl,
  229. head)->perm ||
  230. container_of(acl,
  231. struct tomoyo_path_acl,
  232. head)->perm_high)
  233. continue;
  234. break;
  235. case TOMOYO_TYPE_PATH2_ACL:
  236. if (container_of(acl,
  237. struct tomoyo_path2_acl,
  238. head)->perm)
  239. continue;
  240. break;
  241. default:
  242. continue;
  243. }
  244. if (tomoyo_add_to_gc(TOMOYO_ID_ACL, acl))
  245. list_del_rcu(&acl->list);
  246. else
  247. break;
  248. }
  249. if (!domain->is_deleted || atomic_read(&domain->users))
  250. continue;
  251. /*
  252. * Nobody is referring this domain. But somebody may
  253. * refer this domain after successful execve().
  254. * We recheck domain->users after SRCU synchronization.
  255. */
  256. if (tomoyo_add_to_gc(TOMOYO_ID_DOMAIN, domain))
  257. list_del_rcu(&domain->list);
  258. else
  259. break;
  260. }
  261. }
  262. mutex_unlock(&tomoyo_policy_lock);
  263. mutex_lock(&tomoyo_name_list_lock);
  264. {
  265. int i;
  266. for (i = 0; i < TOMOYO_MAX_HASH; i++) {
  267. struct tomoyo_name_entry *ptr;
  268. list_for_each_entry_rcu(ptr, &tomoyo_name_list[i],
  269. list) {
  270. if (atomic_read(&ptr->users))
  271. continue;
  272. if (tomoyo_add_to_gc(TOMOYO_ID_NAME, ptr))
  273. list_del_rcu(&ptr->list);
  274. else {
  275. i = TOMOYO_MAX_HASH;
  276. break;
  277. }
  278. }
  279. }
  280. }
  281. mutex_unlock(&tomoyo_name_list_lock);
  282. }
  283. static void tomoyo_kfree_entry(void)
  284. {
  285. struct tomoyo_gc_entry *p;
  286. struct tomoyo_gc_entry *tmp;
  287. list_for_each_entry_safe(p, tmp, &tomoyo_gc_queue, list) {
  288. switch (p->type) {
  289. case TOMOYO_ID_DOMAIN_INITIALIZER:
  290. tomoyo_del_domain_initializer(p->element);
  291. break;
  292. case TOMOYO_ID_DOMAIN_KEEPER:
  293. tomoyo_del_domain_keeper(p->element);
  294. break;
  295. case TOMOYO_ID_ALIAS:
  296. tomoyo_del_alias(p->element);
  297. break;
  298. case TOMOYO_ID_GLOBALLY_READABLE:
  299. tomoyo_del_allow_read(p->element);
  300. break;
  301. case TOMOYO_ID_PATTERN:
  302. tomoyo_del_file_pattern(p->element);
  303. break;
  304. case TOMOYO_ID_NO_REWRITE:
  305. tomoyo_del_no_rewrite(p->element);
  306. break;
  307. case TOMOYO_ID_MANAGER:
  308. tomoyo_del_manager(p->element);
  309. break;
  310. case TOMOYO_ID_NAME:
  311. tomoyo_del_name(p->element);
  312. break;
  313. case TOMOYO_ID_ACL:
  314. tomoyo_del_acl(p->element);
  315. break;
  316. case TOMOYO_ID_DOMAIN:
  317. if (!tomoyo_del_domain(p->element))
  318. continue;
  319. break;
  320. default:
  321. printk(KERN_WARNING "Unknown type\n");
  322. break;
  323. }
  324. tomoyo_memory_free(p->element);
  325. list_del(&p->list);
  326. kfree(p);
  327. }
  328. }
  329. static int tomoyo_gc_thread(void *unused)
  330. {
  331. daemonize("GC for TOMOYO");
  332. if (mutex_trylock(&tomoyo_gc_mutex)) {
  333. int i;
  334. for (i = 0; i < 10; i++) {
  335. tomoyo_collect_entry();
  336. if (list_empty(&tomoyo_gc_queue))
  337. break;
  338. synchronize_srcu(&tomoyo_ss);
  339. tomoyo_kfree_entry();
  340. }
  341. mutex_unlock(&tomoyo_gc_mutex);
  342. }
  343. do_exit(0);
  344. }
  345. void tomoyo_run_gc(void)
  346. {
  347. struct task_struct *task = kthread_create(tomoyo_gc_thread, NULL,
  348. "GC for TOMOYO");
  349. if (!IS_ERR(task))
  350. wake_up_process(task);
  351. }