domain.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. /*
  2. * security/tomoyo/domain.c
  3. *
  4. * Domain transition functions for TOMOYO.
  5. *
  6. * Copyright (C) 2005-2010 NTT DATA CORPORATION
  7. */
  8. #include "common.h"
  9. #include <linux/binfmts.h>
  10. #include <linux/slab.h>
  11. /* Variables definitions.*/
  12. /* The initial domain. */
  13. struct tomoyo_domain_info tomoyo_kernel_domain;
  14. /**
  15. * tomoyo_update_policy - Update an entry for exception policy.
  16. *
  17. * @new_entry: Pointer to "struct tomoyo_acl_info".
  18. * @size: Size of @new_entry in bytes.
  19. * @is_delete: True if it is a delete request.
  20. * @list: Pointer to "struct list_head".
  21. * @check_duplicate: Callback function to find duplicated entry.
  22. *
  23. * Returns 0 on success, negative value otherwise.
  24. *
  25. * Caller holds tomoyo_read_lock().
  26. */
  27. int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
  28. bool is_delete, struct list_head *list,
  29. bool (*check_duplicate) (const struct tomoyo_acl_head
  30. *,
  31. const struct tomoyo_acl_head
  32. *))
  33. {
  34. int error = is_delete ? -ENOENT : -ENOMEM;
  35. struct tomoyo_acl_head *entry;
  36. if (mutex_lock_interruptible(&tomoyo_policy_lock))
  37. return -ENOMEM;
  38. list_for_each_entry_rcu(entry, list, list) {
  39. if (!check_duplicate(entry, new_entry))
  40. continue;
  41. entry->is_deleted = is_delete;
  42. error = 0;
  43. break;
  44. }
  45. if (error && !is_delete) {
  46. entry = tomoyo_commit_ok(new_entry, size);
  47. if (entry) {
  48. list_add_tail_rcu(&entry->list, list);
  49. error = 0;
  50. }
  51. }
  52. mutex_unlock(&tomoyo_policy_lock);
  53. return error;
  54. }
  55. /**
  56. * tomoyo_update_domain - Update an entry for domain policy.
  57. *
  58. * @new_entry: Pointer to "struct tomoyo_acl_info".
  59. * @size: Size of @new_entry in bytes.
  60. * @is_delete: True if it is a delete request.
  61. * @domain: Pointer to "struct tomoyo_domain_info".
  62. * @check_duplicate: Callback function to find duplicated entry.
  63. * @merge_duplicate: Callback function to merge duplicated entry.
  64. *
  65. * Returns 0 on success, negative value otherwise.
  66. *
  67. * Caller holds tomoyo_read_lock().
  68. */
  69. int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
  70. bool is_delete, struct tomoyo_domain_info *domain,
  71. bool (*check_duplicate) (const struct tomoyo_acl_info
  72. *,
  73. const struct tomoyo_acl_info
  74. *),
  75. bool (*merge_duplicate) (struct tomoyo_acl_info *,
  76. struct tomoyo_acl_info *,
  77. const bool))
  78. {
  79. int error = is_delete ? -ENOENT : -ENOMEM;
  80. struct tomoyo_acl_info *entry;
  81. if (mutex_lock_interruptible(&tomoyo_policy_lock))
  82. return error;
  83. list_for_each_entry_rcu(entry, &domain->acl_info_list, list) {
  84. if (!check_duplicate(entry, new_entry))
  85. continue;
  86. if (merge_duplicate)
  87. entry->is_deleted = merge_duplicate(entry, new_entry,
  88. is_delete);
  89. else
  90. entry->is_deleted = is_delete;
  91. error = 0;
  92. break;
  93. }
  94. if (error && !is_delete) {
  95. entry = tomoyo_commit_ok(new_entry, size);
  96. if (entry) {
  97. list_add_tail_rcu(&entry->list, &domain->acl_info_list);
  98. error = 0;
  99. }
  100. }
  101. mutex_unlock(&tomoyo_policy_lock);
  102. return error;
  103. }
  104. void tomoyo_check_acl(struct tomoyo_request_info *r,
  105. bool (*check_entry) (const struct tomoyo_request_info *,
  106. const struct tomoyo_acl_info *))
  107. {
  108. const struct tomoyo_domain_info *domain = r->domain;
  109. struct tomoyo_acl_info *ptr;
  110. list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
  111. if (ptr->is_deleted || ptr->type != r->param_type)
  112. continue;
  113. if (check_entry(r, ptr)) {
  114. r->granted = true;
  115. return;
  116. }
  117. }
  118. r->granted = false;
  119. }
  120. /* The list for "struct tomoyo_domain_info". */
  121. LIST_HEAD(tomoyo_domain_list);
  122. struct list_head tomoyo_policy_list[TOMOYO_MAX_POLICY];
  123. struct list_head tomoyo_group_list[TOMOYO_MAX_GROUP];
  124. /**
  125. * tomoyo_get_last_name - Get last component of a domainname.
  126. *
  127. * @domain: Pointer to "struct tomoyo_domain_info".
  128. *
  129. * Returns the last component of the domainname.
  130. */
  131. const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain)
  132. {
  133. const char *cp0 = domain->domainname->name;
  134. const char *cp1 = strrchr(cp0, ' ');
  135. if (cp1)
  136. return cp1 + 1;
  137. return cp0;
  138. }
  139. static bool tomoyo_same_domain_initializer_entry(const struct tomoyo_acl_head *
  140. a,
  141. const struct tomoyo_acl_head *
  142. b)
  143. {
  144. const struct tomoyo_domain_initializer_entry *p1 =
  145. container_of(a, typeof(*p1), head);
  146. const struct tomoyo_domain_initializer_entry *p2 =
  147. container_of(b, typeof(*p2), head);
  148. return p1->is_not == p2->is_not && p1->is_last_name == p2->is_last_name
  149. && p1->domainname == p2->domainname
  150. && p1->program == p2->program;
  151. }
  152. /**
  153. * tomoyo_update_domain_initializer_entry - Update "struct tomoyo_domain_initializer_entry" list.
  154. *
  155. * @domainname: The name of domain. May be NULL.
  156. * @program: The name of program.
  157. * @is_not: True if it is "no_initialize_domain" entry.
  158. * @is_delete: True if it is a delete request.
  159. *
  160. * Returns 0 on success, negative value otherwise.
  161. *
  162. * Caller holds tomoyo_read_lock().
  163. */
  164. static int tomoyo_update_domain_initializer_entry(const char *domainname,
  165. const char *program,
  166. const bool is_not,
  167. const bool is_delete)
  168. {
  169. struct tomoyo_domain_initializer_entry e = { .is_not = is_not };
  170. int error = is_delete ? -ENOENT : -ENOMEM;
  171. if (!tomoyo_correct_path(program))
  172. return -EINVAL;
  173. if (domainname) {
  174. if (!tomoyo_domain_def(domainname) &&
  175. tomoyo_correct_path(domainname))
  176. e.is_last_name = true;
  177. else if (!tomoyo_correct_domain(domainname))
  178. return -EINVAL;
  179. e.domainname = tomoyo_get_name(domainname);
  180. if (!e.domainname)
  181. goto out;
  182. }
  183. e.program = tomoyo_get_name(program);
  184. if (!e.program)
  185. goto out;
  186. error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
  187. &tomoyo_policy_list
  188. [TOMOYO_ID_DOMAIN_INITIALIZER],
  189. tomoyo_same_domain_initializer_entry);
  190. out:
  191. tomoyo_put_name(e.domainname);
  192. tomoyo_put_name(e.program);
  193. return error;
  194. }
  195. /**
  196. * tomoyo_write_domain_initializer_policy - Write "struct tomoyo_domain_initializer_entry" list.
  197. *
  198. * @data: String to parse.
  199. * @is_not: True if it is "no_initialize_domain" entry.
  200. * @is_delete: True if it is a delete request.
  201. *
  202. * Returns 0 on success, negative value otherwise.
  203. *
  204. * Caller holds tomoyo_read_lock().
  205. */
  206. int tomoyo_write_domain_initializer_policy(char *data, const bool is_not,
  207. const bool is_delete)
  208. {
  209. char *cp = strstr(data, " from ");
  210. if (cp) {
  211. *cp = '\0';
  212. return tomoyo_update_domain_initializer_entry(cp + 6, data,
  213. is_not,
  214. is_delete);
  215. }
  216. return tomoyo_update_domain_initializer_entry(NULL, data, is_not,
  217. is_delete);
  218. }
  219. /**
  220. * tomoyo_domain_initializer - Check whether the given program causes domainname reinitialization.
  221. *
  222. * @domainname: The name of domain.
  223. * @program: The name of program.
  224. * @last_name: The last component of @domainname.
  225. *
  226. * Returns true if executing @program reinitializes domain transition,
  227. * false otherwise.
  228. *
  229. * Caller holds tomoyo_read_lock().
  230. */
  231. static bool tomoyo_domain_initializer(const struct tomoyo_path_info *
  232. domainname,
  233. const struct tomoyo_path_info *program,
  234. const struct tomoyo_path_info *
  235. last_name)
  236. {
  237. struct tomoyo_domain_initializer_entry *ptr;
  238. bool flag = false;
  239. list_for_each_entry_rcu(ptr, &tomoyo_policy_list
  240. [TOMOYO_ID_DOMAIN_INITIALIZER], head.list) {
  241. if (ptr->head.is_deleted)
  242. continue;
  243. if (ptr->domainname) {
  244. if (!ptr->is_last_name) {
  245. if (ptr->domainname != domainname)
  246. continue;
  247. } else {
  248. if (tomoyo_pathcmp(ptr->domainname, last_name))
  249. continue;
  250. }
  251. }
  252. if (tomoyo_pathcmp(ptr->program, program))
  253. continue;
  254. if (ptr->is_not) {
  255. flag = false;
  256. break;
  257. }
  258. flag = true;
  259. }
  260. return flag;
  261. }
  262. static bool tomoyo_same_domain_keeper_entry(const struct tomoyo_acl_head *a,
  263. const struct tomoyo_acl_head *b)
  264. {
  265. const struct tomoyo_domain_keeper_entry *p1 =
  266. container_of(a, typeof(*p1), head);
  267. const struct tomoyo_domain_keeper_entry *p2 =
  268. container_of(b, typeof(*p2), head);
  269. return p1->is_not == p2->is_not && p1->is_last_name == p2->is_last_name
  270. && p1->domainname == p2->domainname
  271. && p1->program == p2->program;
  272. }
  273. /**
  274. * tomoyo_update_domain_keeper_entry - Update "struct tomoyo_domain_keeper_entry" list.
  275. *
  276. * @domainname: The name of domain.
  277. * @program: The name of program. May be NULL.
  278. * @is_not: True if it is "no_keep_domain" entry.
  279. * @is_delete: True if it is a delete request.
  280. *
  281. * Returns 0 on success, negative value otherwise.
  282. *
  283. * Caller holds tomoyo_read_lock().
  284. */
  285. static int tomoyo_update_domain_keeper_entry(const char *domainname,
  286. const char *program,
  287. const bool is_not,
  288. const bool is_delete)
  289. {
  290. struct tomoyo_domain_keeper_entry e = { .is_not = is_not };
  291. int error = is_delete ? -ENOENT : -ENOMEM;
  292. if (!tomoyo_domain_def(domainname) &&
  293. tomoyo_correct_path(domainname))
  294. e.is_last_name = true;
  295. else if (!tomoyo_correct_domain(domainname))
  296. return -EINVAL;
  297. if (program) {
  298. if (!tomoyo_correct_path(program))
  299. return -EINVAL;
  300. e.program = tomoyo_get_name(program);
  301. if (!e.program)
  302. goto out;
  303. }
  304. e.domainname = tomoyo_get_name(domainname);
  305. if (!e.domainname)
  306. goto out;
  307. error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
  308. &tomoyo_policy_list
  309. [TOMOYO_ID_DOMAIN_KEEPER],
  310. tomoyo_same_domain_keeper_entry);
  311. out:
  312. tomoyo_put_name(e.domainname);
  313. tomoyo_put_name(e.program);
  314. return error;
  315. }
  316. /**
  317. * tomoyo_write_domain_keeper_policy - Write "struct tomoyo_domain_keeper_entry" list.
  318. *
  319. * @data: String to parse.
  320. * @is_not: True if it is "no_keep_domain" entry.
  321. * @is_delete: True if it is a delete request.
  322. *
  323. * Caller holds tomoyo_read_lock().
  324. */
  325. int tomoyo_write_domain_keeper_policy(char *data, const bool is_not,
  326. const bool is_delete)
  327. {
  328. char *cp = strstr(data, " from ");
  329. if (cp) {
  330. *cp = '\0';
  331. return tomoyo_update_domain_keeper_entry(cp + 6, data, is_not,
  332. is_delete);
  333. }
  334. return tomoyo_update_domain_keeper_entry(data, NULL, is_not, is_delete);
  335. }
  336. /**
  337. * tomoyo_domain_keeper - Check whether the given program causes domain transition suppression.
  338. *
  339. * @domainname: The name of domain.
  340. * @program: The name of program.
  341. * @last_name: The last component of @domainname.
  342. *
  343. * Returns true if executing @program supresses domain transition,
  344. * false otherwise.
  345. *
  346. * Caller holds tomoyo_read_lock().
  347. */
  348. static bool tomoyo_domain_keeper(const struct tomoyo_path_info *domainname,
  349. const struct tomoyo_path_info *program,
  350. const struct tomoyo_path_info *last_name)
  351. {
  352. struct tomoyo_domain_keeper_entry *ptr;
  353. bool flag = false;
  354. list_for_each_entry_rcu(ptr,
  355. &tomoyo_policy_list[TOMOYO_ID_DOMAIN_KEEPER],
  356. head.list) {
  357. if (ptr->head.is_deleted)
  358. continue;
  359. if (!ptr->is_last_name) {
  360. if (ptr->domainname != domainname)
  361. continue;
  362. } else {
  363. if (tomoyo_pathcmp(ptr->domainname, last_name))
  364. continue;
  365. }
  366. if (ptr->program && tomoyo_pathcmp(ptr->program, program))
  367. continue;
  368. if (ptr->is_not) {
  369. flag = false;
  370. break;
  371. }
  372. flag = true;
  373. }
  374. return flag;
  375. }
  376. static bool tomoyo_same_aggregator_entry(const struct tomoyo_acl_head *a,
  377. const struct tomoyo_acl_head *b)
  378. {
  379. const struct tomoyo_aggregator_entry *p1 = container_of(a, typeof(*p1),
  380. head);
  381. const struct tomoyo_aggregator_entry *p2 = container_of(b, typeof(*p2),
  382. head);
  383. return p1->original_name == p2->original_name &&
  384. p1->aggregated_name == p2->aggregated_name;
  385. }
  386. /**
  387. * tomoyo_update_aggregator_entry - Update "struct tomoyo_aggregator_entry" list.
  388. *
  389. * @original_name: The original program's name.
  390. * @aggregated_name: The program name to use.
  391. * @is_delete: True if it is a delete request.
  392. *
  393. * Returns 0 on success, negative value otherwise.
  394. *
  395. * Caller holds tomoyo_read_lock().
  396. */
  397. static int tomoyo_update_aggregator_entry(const char *original_name,
  398. const char *aggregated_name,
  399. const bool is_delete)
  400. {
  401. struct tomoyo_aggregator_entry e = { };
  402. int error = is_delete ? -ENOENT : -ENOMEM;
  403. if (!tomoyo_correct_path(original_name) ||
  404. !tomoyo_correct_path(aggregated_name))
  405. return -EINVAL;
  406. e.original_name = tomoyo_get_name(original_name);
  407. e.aggregated_name = tomoyo_get_name(aggregated_name);
  408. if (!e.original_name || !e.aggregated_name ||
  409. e.aggregated_name->is_patterned) /* No patterns allowed. */
  410. goto out;
  411. error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
  412. &tomoyo_policy_list[TOMOYO_ID_AGGREGATOR],
  413. tomoyo_same_aggregator_entry);
  414. out:
  415. tomoyo_put_name(e.original_name);
  416. tomoyo_put_name(e.aggregated_name);
  417. return error;
  418. }
  419. /**
  420. * tomoyo_write_aggregator_policy - Write "struct tomoyo_aggregator_entry" list.
  421. *
  422. * @data: String to parse.
  423. * @is_delete: True if it is a delete request.
  424. *
  425. * Returns 0 on success, negative value otherwise.
  426. *
  427. * Caller holds tomoyo_read_lock().
  428. */
  429. int tomoyo_write_aggregator_policy(char *data, const bool is_delete)
  430. {
  431. char *cp = strchr(data, ' ');
  432. if (!cp)
  433. return -EINVAL;
  434. *cp++ = '\0';
  435. return tomoyo_update_aggregator_entry(data, cp, is_delete);
  436. }
  437. /**
  438. * tomoyo_find_or_assign_new_domain - Create a domain.
  439. *
  440. * @domainname: The name of domain.
  441. * @profile: Profile number to assign if the domain was newly created.
  442. *
  443. * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise.
  444. *
  445. * Caller holds tomoyo_read_lock().
  446. */
  447. struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
  448. domainname,
  449. const u8 profile)
  450. {
  451. struct tomoyo_domain_info *entry;
  452. struct tomoyo_domain_info *domain = NULL;
  453. const struct tomoyo_path_info *saved_domainname;
  454. bool found = false;
  455. if (!tomoyo_correct_domain(domainname))
  456. return NULL;
  457. saved_domainname = tomoyo_get_name(domainname);
  458. if (!saved_domainname)
  459. return NULL;
  460. entry = kzalloc(sizeof(*entry), GFP_NOFS);
  461. if (mutex_lock_interruptible(&tomoyo_policy_lock))
  462. goto out;
  463. list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
  464. if (domain->is_deleted ||
  465. tomoyo_pathcmp(saved_domainname, domain->domainname))
  466. continue;
  467. found = true;
  468. break;
  469. }
  470. if (!found && tomoyo_memory_ok(entry)) {
  471. INIT_LIST_HEAD(&entry->acl_info_list);
  472. entry->domainname = saved_domainname;
  473. saved_domainname = NULL;
  474. entry->profile = profile;
  475. list_add_tail_rcu(&entry->list, &tomoyo_domain_list);
  476. domain = entry;
  477. entry = NULL;
  478. found = true;
  479. }
  480. mutex_unlock(&tomoyo_policy_lock);
  481. out:
  482. tomoyo_put_name(saved_domainname);
  483. kfree(entry);
  484. return found ? domain : NULL;
  485. }
  486. /**
  487. * tomoyo_find_next_domain - Find a domain.
  488. *
  489. * @bprm: Pointer to "struct linux_binprm".
  490. *
  491. * Returns 0 on success, negative value otherwise.
  492. *
  493. * Caller holds tomoyo_read_lock().
  494. */
  495. int tomoyo_find_next_domain(struct linux_binprm *bprm)
  496. {
  497. struct tomoyo_request_info r;
  498. char *tmp = kzalloc(TOMOYO_EXEC_TMPSIZE, GFP_NOFS);
  499. struct tomoyo_domain_info *old_domain = tomoyo_domain();
  500. struct tomoyo_domain_info *domain = NULL;
  501. const char *old_domain_name = old_domain->domainname->name;
  502. const char *original_name = bprm->filename;
  503. u8 mode;
  504. bool is_enforce;
  505. int retval = -ENOMEM;
  506. bool need_kfree = false;
  507. struct tomoyo_path_info rn = { }; /* real name */
  508. struct tomoyo_path_info ln; /* last name */
  509. ln.name = tomoyo_get_last_name(old_domain);
  510. tomoyo_fill_path_info(&ln);
  511. mode = tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_EXECUTE);
  512. is_enforce = (mode == TOMOYO_CONFIG_ENFORCING);
  513. if (!tmp)
  514. goto out;
  515. retry:
  516. if (need_kfree) {
  517. kfree(rn.name);
  518. need_kfree = false;
  519. }
  520. /* Get symlink's pathname of program. */
  521. retval = -ENOENT;
  522. rn.name = tomoyo_realpath_nofollow(original_name);
  523. if (!rn.name)
  524. goto out;
  525. tomoyo_fill_path_info(&rn);
  526. need_kfree = true;
  527. /* Check 'aggregator' directive. */
  528. {
  529. struct tomoyo_aggregator_entry *ptr;
  530. list_for_each_entry_rcu(ptr, &tomoyo_policy_list
  531. [TOMOYO_ID_AGGREGATOR], head.list) {
  532. if (ptr->head.is_deleted ||
  533. !tomoyo_path_matches_pattern(&rn,
  534. ptr->original_name))
  535. continue;
  536. kfree(rn.name);
  537. need_kfree = false;
  538. /* This is OK because it is read only. */
  539. rn = *ptr->aggregated_name;
  540. break;
  541. }
  542. }
  543. /* Check execute permission. */
  544. retval = tomoyo_path_permission(&r, TOMOYO_TYPE_EXECUTE, &rn);
  545. if (retval == TOMOYO_RETRY_REQUEST)
  546. goto retry;
  547. if (retval < 0)
  548. goto out;
  549. if (tomoyo_domain_initializer(old_domain->domainname, &rn, &ln)) {
  550. /* Transit to the child of tomoyo_kernel_domain domain. */
  551. snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1,
  552. TOMOYO_ROOT_NAME " " "%s", rn.name);
  553. } else if (old_domain == &tomoyo_kernel_domain &&
  554. !tomoyo_policy_loaded) {
  555. /*
  556. * Needn't to transit from kernel domain before starting
  557. * /sbin/init. But transit from kernel domain if executing
  558. * initializers because they might start before /sbin/init.
  559. */
  560. domain = old_domain;
  561. } else if (tomoyo_domain_keeper(old_domain->domainname, &rn, &ln)) {
  562. /* Keep current domain. */
  563. domain = old_domain;
  564. } else {
  565. /* Normal domain transition. */
  566. snprintf(tmp, TOMOYO_EXEC_TMPSIZE - 1,
  567. "%s %s", old_domain_name, rn.name);
  568. }
  569. if (domain || strlen(tmp) >= TOMOYO_EXEC_TMPSIZE - 10)
  570. goto done;
  571. domain = tomoyo_find_domain(tmp);
  572. if (domain)
  573. goto done;
  574. if (is_enforce) {
  575. int error = tomoyo_supervisor(&r, "# wants to create domain\n"
  576. "%s\n", tmp);
  577. if (error == TOMOYO_RETRY_REQUEST)
  578. goto retry;
  579. if (error < 0)
  580. goto done;
  581. }
  582. domain = tomoyo_find_or_assign_new_domain(tmp, old_domain->profile);
  583. done:
  584. if (domain)
  585. goto out;
  586. printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n", tmp);
  587. if (is_enforce)
  588. retval = -EPERM;
  589. else
  590. old_domain->transition_failed = true;
  591. out:
  592. if (!domain)
  593. domain = old_domain;
  594. /* Update reference count on "struct tomoyo_domain_info". */
  595. atomic_inc(&domain->users);
  596. bprm->cred->security = domain;
  597. if (need_kfree)
  598. kfree(rn.name);
  599. kfree(tmp);
  600. return retval;
  601. }