domain.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. /*
  2. * security/tomoyo/domain.c
  3. *
  4. * Implementation of the Domain-Based Mandatory Access Control.
  5. *
  6. * Copyright (C) 2005-2009 NTT DATA CORPORATION
  7. *
  8. * Version: 2.2.0 2009/04/01
  9. *
  10. */
  11. #include "common.h"
  12. #include "tomoyo.h"
  13. #include "realpath.h"
  14. #include <linux/binfmts.h>
  15. /* Variables definitions.*/
  16. /* The initial domain. */
  17. struct tomoyo_domain_info tomoyo_kernel_domain;
  18. /* The list for "struct tomoyo_domain_info". */
  19. LIST_HEAD(tomoyo_domain_list);
  20. DECLARE_RWSEM(tomoyo_domain_list_lock);
  21. /* Structure for "initialize_domain" and "no_initialize_domain" keyword. */
  22. struct tomoyo_domain_initializer_entry {
  23. struct list_head list;
  24. const struct tomoyo_path_info *domainname; /* This may be NULL */
  25. const struct tomoyo_path_info *program;
  26. bool is_deleted;
  27. bool is_not; /* True if this entry is "no_initialize_domain". */
  28. /* True if the domainname is tomoyo_get_last_name(). */
  29. bool is_last_name;
  30. };
  31. /* Structure for "keep_domain" and "no_keep_domain" keyword. */
  32. struct tomoyo_domain_keeper_entry {
  33. struct list_head list;
  34. const struct tomoyo_path_info *domainname;
  35. const struct tomoyo_path_info *program; /* This may be NULL */
  36. bool is_deleted;
  37. bool is_not; /* True if this entry is "no_keep_domain". */
  38. /* True if the domainname is tomoyo_get_last_name(). */
  39. bool is_last_name;
  40. };
  41. /* Structure for "alias" keyword. */
  42. struct tomoyo_alias_entry {
  43. struct list_head list;
  44. const struct tomoyo_path_info *original_name;
  45. const struct tomoyo_path_info *aliased_name;
  46. bool is_deleted;
  47. };
  48. /**
  49. * tomoyo_set_domain_flag - Set or clear domain's attribute flags.
  50. *
  51. * @domain: Pointer to "struct tomoyo_domain_info".
  52. * @is_delete: True if it is a delete request.
  53. * @flags: Flags to set or clear.
  54. *
  55. * Returns nothing.
  56. */
  57. void tomoyo_set_domain_flag(struct tomoyo_domain_info *domain,
  58. const bool is_delete, const u8 flags)
  59. {
  60. /* We need to serialize because this is bitfield operation. */
  61. static DEFINE_SPINLOCK(lock);
  62. /***** CRITICAL SECTION START *****/
  63. spin_lock(&lock);
  64. if (!is_delete)
  65. domain->flags |= flags;
  66. else
  67. domain->flags &= ~flags;
  68. spin_unlock(&lock);
  69. /***** CRITICAL SECTION END *****/
  70. }
  71. /**
  72. * tomoyo_get_last_name - Get last component of a domainname.
  73. *
  74. * @domain: Pointer to "struct tomoyo_domain_info".
  75. *
  76. * Returns the last component of the domainname.
  77. */
  78. const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain)
  79. {
  80. const char *cp0 = domain->domainname->name;
  81. const char *cp1 = strrchr(cp0, ' ');
  82. if (cp1)
  83. return cp1 + 1;
  84. return cp0;
  85. }
  86. /* The list for "struct tomoyo_domain_initializer_entry". */
  87. static LIST_HEAD(tomoyo_domain_initializer_list);
  88. static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock);
  89. /**
  90. * tomoyo_update_domain_initializer_entry - Update "struct tomoyo_domain_initializer_entry" list.
  91. *
  92. * @domainname: The name of domain. May be NULL.
  93. * @program: The name of program.
  94. * @is_not: True if it is "no_initialize_domain" entry.
  95. * @is_delete: True if it is a delete request.
  96. *
  97. * Returns 0 on success, negative value otherwise.
  98. */
  99. static int tomoyo_update_domain_initializer_entry(const char *domainname,
  100. const char *program,
  101. const bool is_not,
  102. const bool is_delete)
  103. {
  104. struct tomoyo_domain_initializer_entry *new_entry;
  105. struct tomoyo_domain_initializer_entry *ptr;
  106. const struct tomoyo_path_info *saved_program;
  107. const struct tomoyo_path_info *saved_domainname = NULL;
  108. int error = -ENOMEM;
  109. bool is_last_name = false;
  110. if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__))
  111. return -EINVAL; /* No patterns allowed. */
  112. if (domainname) {
  113. if (!tomoyo_is_domain_def(domainname) &&
  114. tomoyo_is_correct_path(domainname, 1, -1, -1, __func__))
  115. is_last_name = true;
  116. else if (!tomoyo_is_correct_domain(domainname, __func__))
  117. return -EINVAL;
  118. saved_domainname = tomoyo_save_name(domainname);
  119. if (!saved_domainname)
  120. return -ENOMEM;
  121. }
  122. saved_program = tomoyo_save_name(program);
  123. if (!saved_program)
  124. return -ENOMEM;
  125. /***** EXCLUSIVE SECTION START *****/
  126. down_write(&tomoyo_domain_initializer_list_lock);
  127. list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) {
  128. if (ptr->is_not != is_not ||
  129. ptr->domainname != saved_domainname ||
  130. ptr->program != saved_program)
  131. continue;
  132. ptr->is_deleted = is_delete;
  133. error = 0;
  134. goto out;
  135. }
  136. if (is_delete) {
  137. error = -ENOENT;
  138. goto out;
  139. }
  140. new_entry = tomoyo_alloc_element(sizeof(*new_entry));
  141. if (!new_entry)
  142. goto out;
  143. new_entry->domainname = saved_domainname;
  144. new_entry->program = saved_program;
  145. new_entry->is_not = is_not;
  146. new_entry->is_last_name = is_last_name;
  147. list_add_tail(&new_entry->list, &tomoyo_domain_initializer_list);
  148. error = 0;
  149. out:
  150. up_write(&tomoyo_domain_initializer_list_lock);
  151. /***** EXCLUSIVE SECTION END *****/
  152. return error;
  153. }
  154. /**
  155. * tomoyo_read_domain_initializer_policy - Read "struct tomoyo_domain_initializer_entry" list.
  156. *
  157. * @head: Pointer to "struct tomoyo_io_buffer".
  158. *
  159. * Returns true on success, false otherwise.
  160. */
  161. bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head)
  162. {
  163. struct list_head *pos;
  164. bool done = true;
  165. down_read(&tomoyo_domain_initializer_list_lock);
  166. list_for_each_cookie(pos, head->read_var2,
  167. &tomoyo_domain_initializer_list) {
  168. const char *no;
  169. const char *from = "";
  170. const char *domain = "";
  171. struct tomoyo_domain_initializer_entry *ptr;
  172. ptr = list_entry(pos, struct tomoyo_domain_initializer_entry,
  173. list);
  174. if (ptr->is_deleted)
  175. continue;
  176. no = ptr->is_not ? "no_" : "";
  177. if (ptr->domainname) {
  178. from = " from ";
  179. domain = ptr->domainname->name;
  180. }
  181. if (!tomoyo_io_printf(head,
  182. "%s" TOMOYO_KEYWORD_INITIALIZE_DOMAIN
  183. "%s%s%s\n", no, ptr->program->name, from,
  184. domain)) {
  185. done = false;
  186. break;
  187. }
  188. }
  189. up_read(&tomoyo_domain_initializer_list_lock);
  190. return done;
  191. }
  192. /**
  193. * tomoyo_write_domain_initializer_policy - Write "struct tomoyo_domain_initializer_entry" list.
  194. *
  195. * @data: String to parse.
  196. * @is_not: True if it is "no_initialize_domain" entry.
  197. * @is_delete: True if it is a delete request.
  198. *
  199. * Returns 0 on success, negative value otherwise.
  200. */
  201. int tomoyo_write_domain_initializer_policy(char *data, const bool is_not,
  202. const bool is_delete)
  203. {
  204. char *cp = strstr(data, " from ");
  205. if (cp) {
  206. *cp = '\0';
  207. return tomoyo_update_domain_initializer_entry(cp + 6, data,
  208. is_not,
  209. is_delete);
  210. }
  211. return tomoyo_update_domain_initializer_entry(NULL, data, is_not,
  212. is_delete);
  213. }
  214. /**
  215. * tomoyo_is_domain_initializer - Check whether the given program causes domainname reinitialization.
  216. *
  217. * @domainname: The name of domain.
  218. * @program: The name of program.
  219. * @last_name: The last component of @domainname.
  220. *
  221. * Returns true if executing @program reinitializes domain transition,
  222. * false otherwise.
  223. */
  224. static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
  225. domainname,
  226. const struct tomoyo_path_info *program,
  227. const struct tomoyo_path_info *
  228. last_name)
  229. {
  230. struct tomoyo_domain_initializer_entry *ptr;
  231. bool flag = false;
  232. down_read(&tomoyo_domain_initializer_list_lock);
  233. list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) {
  234. if (ptr->is_deleted)
  235. continue;
  236. if (ptr->domainname) {
  237. if (!ptr->is_last_name) {
  238. if (ptr->domainname != domainname)
  239. continue;
  240. } else {
  241. if (tomoyo_pathcmp(ptr->domainname, last_name))
  242. continue;
  243. }
  244. }
  245. if (tomoyo_pathcmp(ptr->program, program))
  246. continue;
  247. if (ptr->is_not) {
  248. flag = false;
  249. break;
  250. }
  251. flag = true;
  252. }
  253. up_read(&tomoyo_domain_initializer_list_lock);
  254. return flag;
  255. }
  256. /* The list for "struct tomoyo_domain_keeper_entry". */
  257. static LIST_HEAD(tomoyo_domain_keeper_list);
  258. static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock);
  259. /**
  260. * tomoyo_update_domain_keeper_entry - Update "struct tomoyo_domain_keeper_entry" list.
  261. *
  262. * @domainname: The name of domain.
  263. * @program: The name of program. May be NULL.
  264. * @is_not: True if it is "no_keep_domain" entry.
  265. * @is_delete: True if it is a delete request.
  266. *
  267. * Returns 0 on success, negative value otherwise.
  268. */
  269. static int tomoyo_update_domain_keeper_entry(const char *domainname,
  270. const char *program,
  271. const bool is_not,
  272. const bool is_delete)
  273. {
  274. struct tomoyo_domain_keeper_entry *new_entry;
  275. struct tomoyo_domain_keeper_entry *ptr;
  276. const struct tomoyo_path_info *saved_domainname;
  277. const struct tomoyo_path_info *saved_program = NULL;
  278. int error = -ENOMEM;
  279. bool is_last_name = false;
  280. if (!tomoyo_is_domain_def(domainname) &&
  281. tomoyo_is_correct_path(domainname, 1, -1, -1, __func__))
  282. is_last_name = true;
  283. else if (!tomoyo_is_correct_domain(domainname, __func__))
  284. return -EINVAL;
  285. if (program) {
  286. if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__))
  287. return -EINVAL;
  288. saved_program = tomoyo_save_name(program);
  289. if (!saved_program)
  290. return -ENOMEM;
  291. }
  292. saved_domainname = tomoyo_save_name(domainname);
  293. if (!saved_domainname)
  294. return -ENOMEM;
  295. /***** EXCLUSIVE SECTION START *****/
  296. down_write(&tomoyo_domain_keeper_list_lock);
  297. list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) {
  298. if (ptr->is_not != is_not ||
  299. ptr->domainname != saved_domainname ||
  300. ptr->program != saved_program)
  301. continue;
  302. ptr->is_deleted = is_delete;
  303. error = 0;
  304. goto out;
  305. }
  306. if (is_delete) {
  307. error = -ENOENT;
  308. goto out;
  309. }
  310. new_entry = tomoyo_alloc_element(sizeof(*new_entry));
  311. if (!new_entry)
  312. goto out;
  313. new_entry->domainname = saved_domainname;
  314. new_entry->program = saved_program;
  315. new_entry->is_not = is_not;
  316. new_entry->is_last_name = is_last_name;
  317. list_add_tail(&new_entry->list, &tomoyo_domain_keeper_list);
  318. error = 0;
  319. out:
  320. up_write(&tomoyo_domain_keeper_list_lock);
  321. /***** EXCLUSIVE SECTION END *****/
  322. return error;
  323. }
  324. /**
  325. * tomoyo_write_domain_keeper_policy - Write "struct tomoyo_domain_keeper_entry" list.
  326. *
  327. * @data: String to parse.
  328. * @is_not: True if it is "no_keep_domain" entry.
  329. * @is_delete: True if it is a delete request.
  330. *
  331. */
  332. int tomoyo_write_domain_keeper_policy(char *data, const bool is_not,
  333. const bool is_delete)
  334. {
  335. char *cp = strstr(data, " from ");
  336. if (cp) {
  337. *cp = '\0';
  338. return tomoyo_update_domain_keeper_entry(cp + 6, data, is_not,
  339. is_delete);
  340. }
  341. return tomoyo_update_domain_keeper_entry(data, NULL, is_not, is_delete);
  342. }
  343. /**
  344. * tomoyo_read_domain_keeper_policy - Read "struct tomoyo_domain_keeper_entry" list.
  345. *
  346. * @head: Pointer to "struct tomoyo_io_buffer".
  347. *
  348. * Returns true on success, false otherwise.
  349. */
  350. bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head)
  351. {
  352. struct list_head *pos;
  353. bool done = true;
  354. down_read(&tomoyo_domain_keeper_list_lock);
  355. list_for_each_cookie(pos, head->read_var2,
  356. &tomoyo_domain_keeper_list) {
  357. struct tomoyo_domain_keeper_entry *ptr;
  358. const char *no;
  359. const char *from = "";
  360. const char *program = "";
  361. ptr = list_entry(pos, struct tomoyo_domain_keeper_entry, list);
  362. if (ptr->is_deleted)
  363. continue;
  364. no = ptr->is_not ? "no_" : "";
  365. if (ptr->program) {
  366. from = " from ";
  367. program = ptr->program->name;
  368. }
  369. if (!tomoyo_io_printf(head,
  370. "%s" TOMOYO_KEYWORD_KEEP_DOMAIN
  371. "%s%s%s\n", no, program, from,
  372. ptr->domainname->name)) {
  373. done = false;
  374. break;
  375. }
  376. }
  377. up_read(&tomoyo_domain_keeper_list_lock);
  378. return done;
  379. }
  380. /**
  381. * tomoyo_is_domain_keeper - Check whether the given program causes domain transition suppression.
  382. *
  383. * @domainname: The name of domain.
  384. * @program: The name of program.
  385. * @last_name: The last component of @domainname.
  386. *
  387. * Returns true if executing @program supresses domain transition,
  388. * false otherwise.
  389. */
  390. static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
  391. const struct tomoyo_path_info *program,
  392. const struct tomoyo_path_info *last_name)
  393. {
  394. struct tomoyo_domain_keeper_entry *ptr;
  395. bool flag = false;
  396. down_read(&tomoyo_domain_keeper_list_lock);
  397. list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) {
  398. if (ptr->is_deleted)
  399. continue;
  400. if (!ptr->is_last_name) {
  401. if (ptr->domainname != domainname)
  402. continue;
  403. } else {
  404. if (tomoyo_pathcmp(ptr->domainname, last_name))
  405. continue;
  406. }
  407. if (ptr->program && tomoyo_pathcmp(ptr->program, program))
  408. continue;
  409. if (ptr->is_not) {
  410. flag = false;
  411. break;
  412. }
  413. flag = true;
  414. }
  415. up_read(&tomoyo_domain_keeper_list_lock);
  416. return flag;
  417. }
  418. /* The list for "struct tomoyo_alias_entry". */
  419. static LIST_HEAD(tomoyo_alias_list);
  420. static DECLARE_RWSEM(tomoyo_alias_list_lock);
  421. /**
  422. * tomoyo_update_alias_entry - Update "struct tomoyo_alias_entry" list.
  423. *
  424. * @original_name: The original program's real name.
  425. * @aliased_name: The symbolic program's symbolic link's name.
  426. * @is_delete: True if it is a delete request.
  427. *
  428. * Returns 0 on success, negative value otherwise.
  429. */
  430. static int tomoyo_update_alias_entry(const char *original_name,
  431. const char *aliased_name,
  432. const bool is_delete)
  433. {
  434. struct tomoyo_alias_entry *new_entry;
  435. struct tomoyo_alias_entry *ptr;
  436. const struct tomoyo_path_info *saved_original_name;
  437. const struct tomoyo_path_info *saved_aliased_name;
  438. int error = -ENOMEM;
  439. if (!tomoyo_is_correct_path(original_name, 1, -1, -1, __func__) ||
  440. !tomoyo_is_correct_path(aliased_name, 1, -1, -1, __func__))
  441. return -EINVAL; /* No patterns allowed. */
  442. saved_original_name = tomoyo_save_name(original_name);
  443. saved_aliased_name = tomoyo_save_name(aliased_name);
  444. if (!saved_original_name || !saved_aliased_name)
  445. return -ENOMEM;
  446. /***** EXCLUSIVE SECTION START *****/
  447. down_write(&tomoyo_alias_list_lock);
  448. list_for_each_entry(ptr, &tomoyo_alias_list, list) {
  449. if (ptr->original_name != saved_original_name ||
  450. ptr->aliased_name != saved_aliased_name)
  451. continue;
  452. ptr->is_deleted = is_delete;
  453. error = 0;
  454. goto out;
  455. }
  456. if (is_delete) {
  457. error = -ENOENT;
  458. goto out;
  459. }
  460. new_entry = tomoyo_alloc_element(sizeof(*new_entry));
  461. if (!new_entry)
  462. goto out;
  463. new_entry->original_name = saved_original_name;
  464. new_entry->aliased_name = saved_aliased_name;
  465. list_add_tail(&new_entry->list, &tomoyo_alias_list);
  466. error = 0;
  467. out:
  468. up_write(&tomoyo_alias_list_lock);
  469. /***** EXCLUSIVE SECTION END *****/
  470. return error;
  471. }
  472. /**
  473. * tomoyo_read_alias_policy - Read "struct tomoyo_alias_entry" list.
  474. *
  475. * @head: Pointer to "struct tomoyo_io_buffer".
  476. *
  477. * Returns true on success, false otherwise.
  478. */
  479. bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head)
  480. {
  481. struct list_head *pos;
  482. bool done = true;
  483. down_read(&tomoyo_alias_list_lock);
  484. list_for_each_cookie(pos, head->read_var2, &tomoyo_alias_list) {
  485. struct tomoyo_alias_entry *ptr;
  486. ptr = list_entry(pos, struct tomoyo_alias_entry, list);
  487. if (ptr->is_deleted)
  488. continue;
  489. if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_ALIAS "%s %s\n",
  490. ptr->original_name->name,
  491. ptr->aliased_name->name)) {
  492. done = false;
  493. break;
  494. }
  495. }
  496. up_read(&tomoyo_alias_list_lock);
  497. return done;
  498. }
  499. /**
  500. * tomoyo_write_alias_policy - Write "struct tomoyo_alias_entry" list.
  501. *
  502. * @data: String to parse.
  503. * @is_delete: True if it is a delete request.
  504. *
  505. * Returns 0 on success, negative value otherwise.
  506. */
  507. int tomoyo_write_alias_policy(char *data, const bool is_delete)
  508. {
  509. char *cp = strchr(data, ' ');
  510. if (!cp)
  511. return -EINVAL;
  512. *cp++ = '\0';
  513. return tomoyo_update_alias_entry(data, cp, is_delete);
  514. }
  515. /* Domain create/delete handler. */
  516. /**
  517. * tomoyo_delete_domain - Delete a domain.
  518. *
  519. * @domainname: The name of domain.
  520. *
  521. * Returns 0.
  522. */
  523. int tomoyo_delete_domain(char *domainname)
  524. {
  525. struct tomoyo_domain_info *domain;
  526. struct tomoyo_path_info name;
  527. name.name = domainname;
  528. tomoyo_fill_path_info(&name);
  529. /***** EXCLUSIVE SECTION START *****/
  530. down_write(&tomoyo_domain_list_lock);
  531. /* Is there an active domain? */
  532. list_for_each_entry(domain, &tomoyo_domain_list, list) {
  533. /* Never delete tomoyo_kernel_domain */
  534. if (domain == &tomoyo_kernel_domain)
  535. continue;
  536. if (domain->is_deleted ||
  537. tomoyo_pathcmp(domain->domainname, &name))
  538. continue;
  539. domain->is_deleted = true;
  540. break;
  541. }
  542. up_write(&tomoyo_domain_list_lock);
  543. /***** EXCLUSIVE SECTION END *****/
  544. return 0;
  545. }
  546. /**
  547. * tomoyo_find_or_assign_new_domain - Create a domain.
  548. *
  549. * @domainname: The name of domain.
  550. * @profile: Profile number to assign if the domain was newly created.
  551. *
  552. * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise.
  553. */
  554. struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
  555. domainname,
  556. const u8 profile)
  557. {
  558. struct tomoyo_domain_info *domain = NULL;
  559. const struct tomoyo_path_info *saved_domainname;
  560. /***** EXCLUSIVE SECTION START *****/
  561. down_write(&tomoyo_domain_list_lock);
  562. domain = tomoyo_find_domain(domainname);
  563. if (domain)
  564. goto out;
  565. if (!tomoyo_is_correct_domain(domainname, __func__))
  566. goto out;
  567. saved_domainname = tomoyo_save_name(domainname);
  568. if (!saved_domainname)
  569. goto out;
  570. /* Can I reuse memory of deleted domain? */
  571. list_for_each_entry(domain, &tomoyo_domain_list, list) {
  572. struct task_struct *p;
  573. struct tomoyo_acl_info *ptr;
  574. bool flag;
  575. if (!domain->is_deleted ||
  576. domain->domainname != saved_domainname)
  577. continue;
  578. flag = false;
  579. /***** CRITICAL SECTION START *****/
  580. read_lock(&tasklist_lock);
  581. for_each_process(p) {
  582. if (tomoyo_real_domain(p) != domain)
  583. continue;
  584. flag = true;
  585. break;
  586. }
  587. read_unlock(&tasklist_lock);
  588. /***** CRITICAL SECTION END *****/
  589. if (flag)
  590. continue;
  591. list_for_each_entry(ptr, &domain->acl_info_list, list) {
  592. ptr->type |= TOMOYO_ACL_DELETED;
  593. }
  594. tomoyo_set_domain_flag(domain, true, domain->flags);
  595. domain->profile = profile;
  596. domain->quota_warned = false;
  597. mb(); /* Avoid out-of-order execution. */
  598. domain->is_deleted = false;
  599. goto out;
  600. }
  601. /* No memory reusable. Create using new memory. */
  602. domain = tomoyo_alloc_element(sizeof(*domain));
  603. if (domain) {
  604. INIT_LIST_HEAD(&domain->acl_info_list);
  605. domain->domainname = saved_domainname;
  606. domain->profile = profile;
  607. list_add_tail(&domain->list, &tomoyo_domain_list);
  608. }
  609. out:
  610. up_write(&tomoyo_domain_list_lock);
  611. /***** EXCLUSIVE SECTION END *****/
  612. return domain;
  613. }
  614. /**
  615. * tomoyo_find_next_domain - Find a domain.
  616. *
  617. * @bprm: Pointer to "struct linux_binprm".
  618. * @next_domain: Pointer to pointer to "struct tomoyo_domain_info".
  619. *
  620. * Returns 0 on success, negative value otherwise.
  621. */
  622. int tomoyo_find_next_domain(struct linux_binprm *bprm,
  623. struct tomoyo_domain_info **next_domain)
  624. {
  625. /*
  626. * This function assumes that the size of buffer returned by
  627. * tomoyo_realpath() = TOMOYO_MAX_PATHNAME_LEN.
  628. */
  629. struct tomoyo_page_buffer *tmp = tomoyo_alloc(sizeof(*tmp));
  630. struct tomoyo_domain_info *old_domain = tomoyo_domain();
  631. struct tomoyo_domain_info *domain = NULL;
  632. const char *old_domain_name = old_domain->domainname->name;
  633. const char *original_name = bprm->filename;
  634. char *new_domain_name = NULL;
  635. char *real_program_name = NULL;
  636. char *symlink_program_name = NULL;
  637. const u8 mode = tomoyo_check_flags(old_domain, TOMOYO_MAC_FOR_FILE);
  638. const bool is_enforce = (mode == 3);
  639. int retval = -ENOMEM;
  640. struct tomoyo_path_info r; /* real name */
  641. struct tomoyo_path_info s; /* symlink name */
  642. struct tomoyo_path_info l; /* last name */
  643. static bool initialized;
  644. if (!tmp)
  645. goto out;
  646. if (!initialized) {
  647. /*
  648. * Built-in initializers. This is needed because policies are
  649. * not loaded until starting /sbin/init.
  650. */
  651. tomoyo_update_domain_initializer_entry(NULL, "/sbin/hotplug",
  652. false, false);
  653. tomoyo_update_domain_initializer_entry(NULL, "/sbin/modprobe",
  654. false, false);
  655. initialized = true;
  656. }
  657. /* Get tomoyo_realpath of program. */
  658. retval = -ENOENT;
  659. /* I hope tomoyo_realpath() won't fail with -ENOMEM. */
  660. real_program_name = tomoyo_realpath(original_name);
  661. if (!real_program_name)
  662. goto out;
  663. /* Get tomoyo_realpath of symbolic link. */
  664. symlink_program_name = tomoyo_realpath_nofollow(original_name);
  665. if (!symlink_program_name)
  666. goto out;
  667. r.name = real_program_name;
  668. tomoyo_fill_path_info(&r);
  669. s.name = symlink_program_name;
  670. tomoyo_fill_path_info(&s);
  671. l.name = tomoyo_get_last_name(old_domain);
  672. tomoyo_fill_path_info(&l);
  673. /* Check 'alias' directive. */
  674. if (tomoyo_pathcmp(&r, &s)) {
  675. struct tomoyo_alias_entry *ptr;
  676. /* Is this program allowed to be called via symbolic links? */
  677. down_read(&tomoyo_alias_list_lock);
  678. list_for_each_entry(ptr, &tomoyo_alias_list, list) {
  679. if (ptr->is_deleted ||
  680. tomoyo_pathcmp(&r, ptr->original_name) ||
  681. tomoyo_pathcmp(&s, ptr->aliased_name))
  682. continue;
  683. memset(real_program_name, 0, TOMOYO_MAX_PATHNAME_LEN);
  684. strncpy(real_program_name, ptr->aliased_name->name,
  685. TOMOYO_MAX_PATHNAME_LEN - 1);
  686. tomoyo_fill_path_info(&r);
  687. break;
  688. }
  689. up_read(&tomoyo_alias_list_lock);
  690. }
  691. /* Check execute permission. */
  692. retval = tomoyo_check_exec_perm(old_domain, &r, tmp);
  693. if (retval < 0)
  694. goto out;
  695. new_domain_name = tmp->buffer;
  696. if (tomoyo_is_domain_initializer(old_domain->domainname, &r, &l)) {
  697. /* Transit to the child of tomoyo_kernel_domain domain. */
  698. snprintf(new_domain_name, TOMOYO_MAX_PATHNAME_LEN + 1,
  699. TOMOYO_ROOT_NAME " " "%s", real_program_name);
  700. } else if (old_domain == &tomoyo_kernel_domain &&
  701. !tomoyo_policy_loaded) {
  702. /*
  703. * Needn't to transit from kernel domain before starting
  704. * /sbin/init. But transit from kernel domain if executing
  705. * initializers because they might start before /sbin/init.
  706. */
  707. domain = old_domain;
  708. } else if (tomoyo_is_domain_keeper(old_domain->domainname, &r, &l)) {
  709. /* Keep current domain. */
  710. domain = old_domain;
  711. } else {
  712. /* Normal domain transition. */
  713. snprintf(new_domain_name, TOMOYO_MAX_PATHNAME_LEN + 1,
  714. "%s %s", old_domain_name, real_program_name);
  715. }
  716. if (domain || strlen(new_domain_name) >= TOMOYO_MAX_PATHNAME_LEN)
  717. goto done;
  718. down_read(&tomoyo_domain_list_lock);
  719. domain = tomoyo_find_domain(new_domain_name);
  720. up_read(&tomoyo_domain_list_lock);
  721. if (domain)
  722. goto done;
  723. if (is_enforce)
  724. goto done;
  725. domain = tomoyo_find_or_assign_new_domain(new_domain_name,
  726. old_domain->profile);
  727. done:
  728. if (domain)
  729. goto out;
  730. printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n",
  731. new_domain_name);
  732. if (is_enforce)
  733. retval = -EPERM;
  734. else
  735. tomoyo_set_domain_flag(old_domain, false,
  736. TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED);
  737. out:
  738. tomoyo_free(real_program_name);
  739. tomoyo_free(symlink_program_name);
  740. *next_domain = domain ? domain : old_domain;
  741. tomoyo_free(tmp);
  742. return retval;
  743. }