PageRenderTime 57ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/security/tomoyo/common.c

https://bitbucket.org/wmark/linux-kernel-mark
C | 1940 lines | 1295 code | 95 blank | 550 comment | 401 complexity | e7762daf7d5abbe8976d1a2bfc3511e6 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1. /*
  2. * security/tomoyo/common.c
  3. *
  4. * Common functions for TOMOYO.
  5. *
  6. * Copyright (C) 2005-2009 NTT DATA CORPORATION
  7. *
  8. * Version: 2.2.0 2009/04/01
  9. *
  10. */
  11. #include <linux/uaccess.h>
  12. #include <linux/slab.h>
  13. #include <linux/security.h>
  14. #include <linux/hardirq.h>
  15. #include "common.h"
  16. /* Lock for protecting policy. */
  17. DEFINE_MUTEX(tomoyo_policy_lock);
  18. /* Has loading policy done? */
  19. bool tomoyo_policy_loaded;
  20. /* String table for functionality that takes 4 modes. */
  21. static const char *tomoyo_mode_4[4] = {
  22. "disabled", "learning", "permissive", "enforcing"
  23. };
  24. /* String table for functionality that takes 2 modes. */
  25. static const char *tomoyo_mode_2[4] = {
  26. "disabled", "enabled", "enabled", "enabled"
  27. };
  28. /*
  29. * tomoyo_control_array is a static data which contains
  30. *
  31. * (1) functionality name used by /sys/kernel/security/tomoyo/profile .
  32. * (2) initial values for "struct tomoyo_profile".
  33. * (3) max values for "struct tomoyo_profile".
  34. */
  35. static struct {
  36. const char *keyword;
  37. unsigned int current_value;
  38. const unsigned int max_value;
  39. } tomoyo_control_array[TOMOYO_MAX_CONTROL_INDEX] = {
  40. [TOMOYO_MAC_FOR_FILE] = { "MAC_FOR_FILE", 0, 3 },
  41. [TOMOYO_MAX_ACCEPT_ENTRY] = { "MAX_ACCEPT_ENTRY", 2048, INT_MAX },
  42. [TOMOYO_VERBOSE] = { "TOMOYO_VERBOSE", 1, 1 },
  43. };
  44. /*
  45. * tomoyo_profile is a structure which is used for holding the mode of access
  46. * controls. TOMOYO has 4 modes: disabled, learning, permissive, enforcing.
  47. * An administrator can define up to 256 profiles.
  48. * The ->profile of "struct tomoyo_domain_info" is used for remembering
  49. * the profile's number (0 - 255) assigned to that domain.
  50. */
  51. static struct tomoyo_profile {
  52. unsigned int value[TOMOYO_MAX_CONTROL_INDEX];
  53. const struct tomoyo_path_info *comment;
  54. } *tomoyo_profile_ptr[TOMOYO_MAX_PROFILES];
  55. /* Permit policy management by non-root user? */
  56. static bool tomoyo_manage_by_non_root;
  57. /* Utility functions. */
  58. /* Open operation for /sys/kernel/security/tomoyo/ interface. */
  59. static int tomoyo_open_control(const u8 type, struct file *file);
  60. /* Close /sys/kernel/security/tomoyo/ interface. */
  61. static int tomoyo_close_control(struct file *file);
  62. /* Read operation for /sys/kernel/security/tomoyo/ interface. */
  63. static int tomoyo_read_control(struct file *file, char __user *buffer,
  64. const int buffer_len);
  65. /* Write operation for /sys/kernel/security/tomoyo/ interface. */
  66. static int tomoyo_write_control(struct file *file, const char __user *buffer,
  67. const int buffer_len);
  68. /**
  69. * tomoyo_parse_name_union - Parse a tomoyo_name_union.
  70. *
  71. * @filename: Name or name group.
  72. * @ptr: Pointer to "struct tomoyo_name_union".
  73. *
  74. * Returns true on success, false otherwise.
  75. */
  76. bool tomoyo_parse_name_union(const char *filename,
  77. struct tomoyo_name_union *ptr)
  78. {
  79. if (!tomoyo_is_correct_path(filename, 0, 0, 0))
  80. return false;
  81. if (filename[0] == '@') {
  82. ptr->group = tomoyo_get_path_group(filename + 1);
  83. ptr->is_group = true;
  84. return ptr->group != NULL;
  85. }
  86. ptr->filename = tomoyo_get_name(filename);
  87. ptr->is_group = false;
  88. return ptr->filename != NULL;
  89. }
  90. /**
  91. * tomoyo_print_name_union - Print a tomoyo_name_union.
  92. *
  93. * @head: Pointer to "struct tomoyo_io_buffer".
  94. * @ptr: Pointer to "struct tomoyo_name_union".
  95. *
  96. * Returns true on success, false otherwise.
  97. */
  98. static bool tomoyo_print_name_union(struct tomoyo_io_buffer *head,
  99. const struct tomoyo_name_union *ptr)
  100. {
  101. int pos = head->read_avail;
  102. if (pos && head->read_buf[pos - 1] == ' ')
  103. head->read_avail--;
  104. if (ptr->is_group)
  105. return tomoyo_io_printf(head, " @%s",
  106. ptr->group->group_name->name);
  107. return tomoyo_io_printf(head, " %s", ptr->filename->name);
  108. }
  109. /**
  110. * tomoyo_is_byte_range - Check whether the string isa \ooo style octal value.
  111. *
  112. * @str: Pointer to the string.
  113. *
  114. * Returns true if @str is a \ooo style octal value, false otherwise.
  115. *
  116. * TOMOYO uses \ooo style representation for 0x01 - 0x20 and 0x7F - 0xFF.
  117. * This function verifies that \ooo is in valid range.
  118. */
  119. static inline bool tomoyo_is_byte_range(const char *str)
  120. {
  121. return *str >= '0' && *str++ <= '3' &&
  122. *str >= '0' && *str++ <= '7' &&
  123. *str >= '0' && *str <= '7';
  124. }
  125. /**
  126. * tomoyo_is_alphabet_char - Check whether the character is an alphabet.
  127. *
  128. * @c: The character to check.
  129. *
  130. * Returns true if @c is an alphabet character, false otherwise.
  131. */
  132. static inline bool tomoyo_is_alphabet_char(const char c)
  133. {
  134. return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
  135. }
  136. /**
  137. * tomoyo_make_byte - Make byte value from three octal characters.
  138. *
  139. * @c1: The first character.
  140. * @c2: The second character.
  141. * @c3: The third character.
  142. *
  143. * Returns byte value.
  144. */
  145. static inline u8 tomoyo_make_byte(const u8 c1, const u8 c2, const u8 c3)
  146. {
  147. return ((c1 - '0') << 6) + ((c2 - '0') << 3) + (c3 - '0');
  148. }
  149. /**
  150. * tomoyo_str_starts - Check whether the given string starts with the given keyword.
  151. *
  152. * @src: Pointer to pointer to the string.
  153. * @find: Pointer to the keyword.
  154. *
  155. * Returns true if @src starts with @find, false otherwise.
  156. *
  157. * The @src is updated to point the first character after the @find
  158. * if @src starts with @find.
  159. */
  160. static bool tomoyo_str_starts(char **src, const char *find)
  161. {
  162. const int len = strlen(find);
  163. char *tmp = *src;
  164. if (strncmp(tmp, find, len))
  165. return false;
  166. tmp += len;
  167. *src = tmp;
  168. return true;
  169. }
  170. /**
  171. * tomoyo_normalize_line - Format string.
  172. *
  173. * @buffer: The line to normalize.
  174. *
  175. * Leading and trailing whitespaces are removed.
  176. * Multiple whitespaces are packed into single space.
  177. *
  178. * Returns nothing.
  179. */
  180. static void tomoyo_normalize_line(unsigned char *buffer)
  181. {
  182. unsigned char *sp = buffer;
  183. unsigned char *dp = buffer;
  184. bool first = true;
  185. while (tomoyo_is_invalid(*sp))
  186. sp++;
  187. while (*sp) {
  188. if (!first)
  189. *dp++ = ' ';
  190. first = false;
  191. while (tomoyo_is_valid(*sp))
  192. *dp++ = *sp++;
  193. while (tomoyo_is_invalid(*sp))
  194. sp++;
  195. }
  196. *dp = '\0';
  197. }
  198. /**
  199. * tomoyo_tokenize - Tokenize string.
  200. *
  201. * @buffer: The line to tokenize.
  202. * @w: Pointer to "char *".
  203. * @size: Sizeof @w .
  204. *
  205. * Returns true on success, false otherwise.
  206. */
  207. bool tomoyo_tokenize(char *buffer, char *w[], size_t size)
  208. {
  209. int count = size / sizeof(char *);
  210. int i;
  211. for (i = 0; i < count; i++)
  212. w[i] = "";
  213. for (i = 0; i < count; i++) {
  214. char *cp = strchr(buffer, ' ');
  215. if (cp)
  216. *cp = '\0';
  217. w[i] = buffer;
  218. if (!cp)
  219. break;
  220. buffer = cp + 1;
  221. }
  222. return i < count || !*buffer;
  223. }
  224. /**
  225. * tomoyo_is_correct_path - Validate a pathname.
  226. * @filename: The pathname to check.
  227. * @start_type: Should the pathname start with '/'?
  228. * 1 = must / -1 = must not / 0 = don't care
  229. * @pattern_type: Can the pathname contain a wildcard?
  230. * 1 = must / -1 = must not / 0 = don't care
  231. * @end_type: Should the pathname end with '/'?
  232. * 1 = must / -1 = must not / 0 = don't care
  233. *
  234. * Check whether the given filename follows the naming rules.
  235. * Returns true if @filename follows the naming rules, false otherwise.
  236. */
  237. bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
  238. const s8 pattern_type, const s8 end_type)
  239. {
  240. const char *const start = filename;
  241. bool in_repetition = false;
  242. bool contains_pattern = false;
  243. unsigned char c;
  244. unsigned char d;
  245. unsigned char e;
  246. if (!filename)
  247. goto out;
  248. c = *filename;
  249. if (start_type == 1) { /* Must start with '/' */
  250. if (c != '/')
  251. goto out;
  252. } else if (start_type == -1) { /* Must not start with '/' */
  253. if (c == '/')
  254. goto out;
  255. }
  256. if (c)
  257. c = *(filename + strlen(filename) - 1);
  258. if (end_type == 1) { /* Must end with '/' */
  259. if (c != '/')
  260. goto out;
  261. } else if (end_type == -1) { /* Must not end with '/' */
  262. if (c == '/')
  263. goto out;
  264. }
  265. while (1) {
  266. c = *filename++;
  267. if (!c)
  268. break;
  269. if (c == '\\') {
  270. c = *filename++;
  271. switch (c) {
  272. case '\\': /* "\\" */
  273. continue;
  274. case '$': /* "\$" */
  275. case '+': /* "\+" */
  276. case '?': /* "\?" */
  277. case '*': /* "\*" */
  278. case '@': /* "\@" */
  279. case 'x': /* "\x" */
  280. case 'X': /* "\X" */
  281. case 'a': /* "\a" */
  282. case 'A': /* "\A" */
  283. case '-': /* "\-" */
  284. if (pattern_type == -1)
  285. break; /* Must not contain pattern */
  286. contains_pattern = true;
  287. continue;
  288. case '{': /* "/\{" */
  289. if (filename - 3 < start ||
  290. *(filename - 3) != '/')
  291. break;
  292. if (pattern_type == -1)
  293. break; /* Must not contain pattern */
  294. contains_pattern = true;
  295. in_repetition = true;
  296. continue;
  297. case '}': /* "\}/" */
  298. if (*filename != '/')
  299. break;
  300. if (!in_repetition)
  301. break;
  302. in_repetition = false;
  303. continue;
  304. case '0': /* "\ooo" */
  305. case '1':
  306. case '2':
  307. case '3':
  308. d = *filename++;
  309. if (d < '0' || d > '7')
  310. break;
  311. e = *filename++;
  312. if (e < '0' || e > '7')
  313. break;
  314. c = tomoyo_make_byte(c, d, e);
  315. if (tomoyo_is_invalid(c))
  316. continue; /* pattern is not \000 */
  317. }
  318. goto out;
  319. } else if (in_repetition && c == '/') {
  320. goto out;
  321. } else if (tomoyo_is_invalid(c)) {
  322. goto out;
  323. }
  324. }
  325. if (pattern_type == 1) { /* Must contain pattern */
  326. if (!contains_pattern)
  327. goto out;
  328. }
  329. if (in_repetition)
  330. goto out;
  331. return true;
  332. out:
  333. return false;
  334. }
  335. /**
  336. * tomoyo_is_correct_domain - Check whether the given domainname follows the naming rules.
  337. * @domainname: The domainname to check.
  338. *
  339. * Returns true if @domainname follows the naming rules, false otherwise.
  340. */
  341. bool tomoyo_is_correct_domain(const unsigned char *domainname)
  342. {
  343. unsigned char c;
  344. unsigned char d;
  345. unsigned char e;
  346. if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME,
  347. TOMOYO_ROOT_NAME_LEN))
  348. goto out;
  349. domainname += TOMOYO_ROOT_NAME_LEN;
  350. if (!*domainname)
  351. return true;
  352. do {
  353. if (*domainname++ != ' ')
  354. goto out;
  355. if (*domainname++ != '/')
  356. goto out;
  357. while ((c = *domainname) != '\0' && c != ' ') {
  358. domainname++;
  359. if (c == '\\') {
  360. c = *domainname++;
  361. switch ((c)) {
  362. case '\\': /* "\\" */
  363. continue;
  364. case '0': /* "\ooo" */
  365. case '1':
  366. case '2':
  367. case '3':
  368. d = *domainname++;
  369. if (d < '0' || d > '7')
  370. break;
  371. e = *domainname++;
  372. if (e < '0' || e > '7')
  373. break;
  374. c = tomoyo_make_byte(c, d, e);
  375. if (tomoyo_is_invalid(c))
  376. /* pattern is not \000 */
  377. continue;
  378. }
  379. goto out;
  380. } else if (tomoyo_is_invalid(c)) {
  381. goto out;
  382. }
  383. }
  384. } while (*domainname);
  385. return true;
  386. out:
  387. return false;
  388. }
  389. /**
  390. * tomoyo_is_domain_def - Check whether the given token can be a domainname.
  391. *
  392. * @buffer: The token to check.
  393. *
  394. * Returns true if @buffer possibly be a domainname, false otherwise.
  395. */
  396. bool tomoyo_is_domain_def(const unsigned char *buffer)
  397. {
  398. return !strncmp(buffer, TOMOYO_ROOT_NAME, TOMOYO_ROOT_NAME_LEN);
  399. }
  400. /**
  401. * tomoyo_find_domain - Find a domain by the given name.
  402. *
  403. * @domainname: The domainname to find.
  404. *
  405. * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise.
  406. *
  407. * Caller holds tomoyo_read_lock().
  408. */
  409. struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)
  410. {
  411. struct tomoyo_domain_info *domain;
  412. struct tomoyo_path_info name;
  413. name.name = domainname;
  414. tomoyo_fill_path_info(&name);
  415. list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
  416. if (!domain->is_deleted &&
  417. !tomoyo_pathcmp(&name, domain->domainname))
  418. return domain;
  419. }
  420. return NULL;
  421. }
  422. /**
  423. * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token.
  424. *
  425. * @filename: The string to evaluate.
  426. *
  427. * Returns the initial length without a pattern in @filename.
  428. */
  429. static int tomoyo_const_part_length(const char *filename)
  430. {
  431. char c;
  432. int len = 0;
  433. if (!filename)
  434. return 0;
  435. while ((c = *filename++) != '\0') {
  436. if (c != '\\') {
  437. len++;
  438. continue;
  439. }
  440. c = *filename++;
  441. switch (c) {
  442. case '\\': /* "\\" */
  443. len += 2;
  444. continue;
  445. case '0': /* "\ooo" */
  446. case '1':
  447. case '2':
  448. case '3':
  449. c = *filename++;
  450. if (c < '0' || c > '7')
  451. break;
  452. c = *filename++;
  453. if (c < '0' || c > '7')
  454. break;
  455. len += 4;
  456. continue;
  457. }
  458. break;
  459. }
  460. return len;
  461. }
  462. /**
  463. * tomoyo_fill_path_info - Fill in "struct tomoyo_path_info" members.
  464. *
  465. * @ptr: Pointer to "struct tomoyo_path_info" to fill in.
  466. *
  467. * The caller sets "struct tomoyo_path_info"->name.
  468. */
  469. void tomoyo_fill_path_info(struct tomoyo_path_info *ptr)
  470. {
  471. const char *name = ptr->name;
  472. const int len = strlen(name);
  473. ptr->const_len = tomoyo_const_part_length(name);
  474. ptr->is_dir = len && (name[len - 1] == '/');
  475. ptr->is_patterned = (ptr->const_len < len);
  476. ptr->hash = full_name_hash(name, len);
  477. }
  478. /**
  479. * tomoyo_file_matches_pattern2 - Pattern matching without '/' character
  480. * and "\-" pattern.
  481. *
  482. * @filename: The start of string to check.
  483. * @filename_end: The end of string to check.
  484. * @pattern: The start of pattern to compare.
  485. * @pattern_end: The end of pattern to compare.
  486. *
  487. * Returns true if @filename matches @pattern, false otherwise.
  488. */
  489. static bool tomoyo_file_matches_pattern2(const char *filename,
  490. const char *filename_end,
  491. const char *pattern,
  492. const char *pattern_end)
  493. {
  494. while (filename < filename_end && pattern < pattern_end) {
  495. char c;
  496. if (*pattern != '\\') {
  497. if (*filename++ != *pattern++)
  498. return false;
  499. continue;
  500. }
  501. c = *filename;
  502. pattern++;
  503. switch (*pattern) {
  504. int i;
  505. int j;
  506. case '?':
  507. if (c == '/') {
  508. return false;
  509. } else if (c == '\\') {
  510. if (filename[1] == '\\')
  511. filename++;
  512. else if (tomoyo_is_byte_range(filename + 1))
  513. filename += 3;
  514. else
  515. return false;
  516. }
  517. break;
  518. case '\\':
  519. if (c != '\\')
  520. return false;
  521. if (*++filename != '\\')
  522. return false;
  523. break;
  524. case '+':
  525. if (!isdigit(c))
  526. return false;
  527. break;
  528. case 'x':
  529. if (!isxdigit(c))
  530. return false;
  531. break;
  532. case 'a':
  533. if (!tomoyo_is_alphabet_char(c))
  534. return false;
  535. break;
  536. case '0':
  537. case '1':
  538. case '2':
  539. case '3':
  540. if (c == '\\' && tomoyo_is_byte_range(filename + 1)
  541. && strncmp(filename + 1, pattern, 3) == 0) {
  542. filename += 3;
  543. pattern += 2;
  544. break;
  545. }
  546. return false; /* Not matched. */
  547. case '*':
  548. case '@':
  549. for (i = 0; i <= filename_end - filename; i++) {
  550. if (tomoyo_file_matches_pattern2(
  551. filename + i, filename_end,
  552. pattern + 1, pattern_end))
  553. return true;
  554. c = filename[i];
  555. if (c == '.' && *pattern == '@')
  556. break;
  557. if (c != '\\')
  558. continue;
  559. if (filename[i + 1] == '\\')
  560. i++;
  561. else if (tomoyo_is_byte_range(filename + i + 1))
  562. i += 3;
  563. else
  564. break; /* Bad pattern. */
  565. }
  566. return false; /* Not matched. */
  567. default:
  568. j = 0;
  569. c = *pattern;
  570. if (c == '$') {
  571. while (isdigit(filename[j]))
  572. j++;
  573. } else if (c == 'X') {
  574. while (isxdigit(filename[j]))
  575. j++;
  576. } else if (c == 'A') {
  577. while (tomoyo_is_alphabet_char(filename[j]))
  578. j++;
  579. }
  580. for (i = 1; i <= j; i++) {
  581. if (tomoyo_file_matches_pattern2(
  582. filename + i, filename_end,
  583. pattern + 1, pattern_end))
  584. return true;
  585. }
  586. return false; /* Not matched or bad pattern. */
  587. }
  588. filename++;
  589. pattern++;
  590. }
  591. while (*pattern == '\\' &&
  592. (*(pattern + 1) == '*' || *(pattern + 1) == '@'))
  593. pattern += 2;
  594. return filename == filename_end && pattern == pattern_end;
  595. }
  596. /**
  597. * tomoyo_file_matches_pattern - Pattern matching without without '/' character.
  598. *
  599. * @filename: The start of string to check.
  600. * @filename_end: The end of string to check.
  601. * @pattern: The start of pattern to compare.
  602. * @pattern_end: The end of pattern to compare.
  603. *
  604. * Returns true if @filename matches @pattern, false otherwise.
  605. */
  606. static bool tomoyo_file_matches_pattern(const char *filename,
  607. const char *filename_end,
  608. const char *pattern,
  609. const char *pattern_end)
  610. {
  611. const char *pattern_start = pattern;
  612. bool first = true;
  613. bool result;
  614. while (pattern < pattern_end - 1) {
  615. /* Split at "\-" pattern. */
  616. if (*pattern++ != '\\' || *pattern++ != '-')
  617. continue;
  618. result = tomoyo_file_matches_pattern2(filename,
  619. filename_end,
  620. pattern_start,
  621. pattern - 2);
  622. if (first)
  623. result = !result;
  624. if (result)
  625. return false;
  626. first = false;
  627. pattern_start = pattern;
  628. }
  629. result = tomoyo_file_matches_pattern2(filename, filename_end,
  630. pattern_start, pattern_end);
  631. return first ? result : !result;
  632. }
  633. /**
  634. * tomoyo_path_matches_pattern2 - Do pathname pattern matching.
  635. *
  636. * @f: The start of string to check.
  637. * @p: The start of pattern to compare.
  638. *
  639. * Returns true if @f matches @p, false otherwise.
  640. */
  641. static bool tomoyo_path_matches_pattern2(const char *f, const char *p)
  642. {
  643. const char *f_delimiter;
  644. const char *p_delimiter;
  645. while (*f && *p) {
  646. f_delimiter = strchr(f, '/');
  647. if (!f_delimiter)
  648. f_delimiter = f + strlen(f);
  649. p_delimiter = strchr(p, '/');
  650. if (!p_delimiter)
  651. p_delimiter = p + strlen(p);
  652. if (*p == '\\' && *(p + 1) == '{')
  653. goto recursive;
  654. if (!tomoyo_file_matches_pattern(f, f_delimiter, p,
  655. p_delimiter))
  656. return false;
  657. f = f_delimiter;
  658. if (*f)
  659. f++;
  660. p = p_delimiter;
  661. if (*p)
  662. p++;
  663. }
  664. /* Ignore trailing "\*" and "\@" in @pattern. */
  665. while (*p == '\\' &&
  666. (*(p + 1) == '*' || *(p + 1) == '@'))
  667. p += 2;
  668. return !*f && !*p;
  669. recursive:
  670. /*
  671. * The "\{" pattern is permitted only after '/' character.
  672. * This guarantees that below "*(p - 1)" is safe.
  673. * Also, the "\}" pattern is permitted only before '/' character
  674. * so that "\{" + "\}" pair will not break the "\-" operator.
  675. */
  676. if (*(p - 1) != '/' || p_delimiter <= p + 3 || *p_delimiter != '/' ||
  677. *(p_delimiter - 1) != '}' || *(p_delimiter - 2) != '\\')
  678. return false; /* Bad pattern. */
  679. do {
  680. /* Compare current component with pattern. */
  681. if (!tomoyo_file_matches_pattern(f, f_delimiter, p + 2,
  682. p_delimiter - 2))
  683. break;
  684. /* Proceed to next component. */
  685. f = f_delimiter;
  686. if (!*f)
  687. break;
  688. f++;
  689. /* Continue comparison. */
  690. if (tomoyo_path_matches_pattern2(f, p_delimiter + 1))
  691. return true;
  692. f_delimiter = strchr(f, '/');
  693. } while (f_delimiter);
  694. return false; /* Not matched. */
  695. }
  696. /**
  697. * tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern.
  698. *
  699. * @filename: The filename to check.
  700. * @pattern: The pattern to compare.
  701. *
  702. * Returns true if matches, false otherwise.
  703. *
  704. * The following patterns are available.
  705. * \\ \ itself.
  706. * \ooo Octal representation of a byte.
  707. * \* Zero or more repetitions of characters other than '/'.
  708. * \@ Zero or more repetitions of characters other than '/' or '.'.
  709. * \? 1 byte character other than '/'.
  710. * \$ One or more repetitions of decimal digits.
  711. * \+ 1 decimal digit.
  712. * \X One or more repetitions of hexadecimal digits.
  713. * \x 1 hexadecimal digit.
  714. * \A One or more repetitions of alphabet characters.
  715. * \a 1 alphabet character.
  716. *
  717. * \- Subtraction operator.
  718. *
  719. * /\{dir\}/ '/' + 'One or more repetitions of dir/' (e.g. /dir/ /dir/dir/
  720. * /dir/dir/dir/ ).
  721. */
  722. bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
  723. const struct tomoyo_path_info *pattern)
  724. {
  725. const char *f = filename->name;
  726. const char *p = pattern->name;
  727. const int len = pattern->const_len;
  728. /* If @pattern doesn't contain pattern, I can use strcmp(). */
  729. if (!pattern->is_patterned)
  730. return !tomoyo_pathcmp(filename, pattern);
  731. /* Don't compare directory and non-directory. */
  732. if (filename->is_dir != pattern->is_dir)
  733. return false;
  734. /* Compare the initial length without patterns. */
  735. if (strncmp(f, p, len))
  736. return false;
  737. f += len;
  738. p += len;
  739. return tomoyo_path_matches_pattern2(f, p);
  740. }
  741. /**
  742. * tomoyo_io_printf - Transactional printf() to "struct tomoyo_io_buffer" structure.
  743. *
  744. * @head: Pointer to "struct tomoyo_io_buffer".
  745. * @fmt: The printf()'s format string, followed by parameters.
  746. *
  747. * Returns true if output was written, false otherwise.
  748. *
  749. * The snprintf() will truncate, but tomoyo_io_printf() won't.
  750. */
  751. bool tomoyo_io_printf(struct tomoyo_io_buffer *head, const char *fmt, ...)
  752. {
  753. va_list args;
  754. int len;
  755. int pos = head->read_avail;
  756. int size = head->readbuf_size - pos;
  757. if (size <= 0)
  758. return false;
  759. va_start(args, fmt);
  760. len = vsnprintf(head->read_buf + pos, size, fmt, args);
  761. va_end(args);
  762. if (pos + len >= head->readbuf_size)
  763. return false;
  764. head->read_avail += len;
  765. return true;
  766. }
  767. /**
  768. * tomoyo_get_exe - Get tomoyo_realpath() of current process.
  769. *
  770. * Returns the tomoyo_realpath() of current process on success, NULL otherwise.
  771. *
  772. * This function uses kzalloc(), so the caller must call kfree()
  773. * if this function didn't return NULL.
  774. */
  775. static const char *tomoyo_get_exe(void)
  776. {
  777. struct mm_struct *mm = current->mm;
  778. struct vm_area_struct *vma;
  779. const char *cp = NULL;
  780. if (!mm)
  781. return NULL;
  782. down_read(&mm->mmap_sem);
  783. for (vma = mm->mmap; vma; vma = vma->vm_next) {
  784. if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
  785. cp = tomoyo_realpath_from_path(&vma->vm_file->f_path);
  786. break;
  787. }
  788. }
  789. up_read(&mm->mmap_sem);
  790. return cp;
  791. }
  792. /**
  793. * tomoyo_get_msg - Get warning message.
  794. *
  795. * @is_enforce: Is it enforcing mode?
  796. *
  797. * Returns "ERROR" or "WARNING".
  798. */
  799. const char *tomoyo_get_msg(const bool is_enforce)
  800. {
  801. if (is_enforce)
  802. return "ERROR";
  803. else
  804. return "WARNING";
  805. }
  806. /**
  807. * tomoyo_check_flags - Check mode for specified functionality.
  808. *
  809. * @domain: Pointer to "struct tomoyo_domain_info".
  810. * @index: The functionality to check mode.
  811. *
  812. * TOMOYO checks only process context.
  813. * This code disables TOMOYO's enforcement in case the function is called from
  814. * interrupt context.
  815. */
  816. unsigned int tomoyo_check_flags(const struct tomoyo_domain_info *domain,
  817. const u8 index)
  818. {
  819. const u8 profile = domain->profile;
  820. if (WARN_ON(in_interrupt()))
  821. return 0;
  822. return tomoyo_policy_loaded && index < TOMOYO_MAX_CONTROL_INDEX
  823. #if TOMOYO_MAX_PROFILES != 256
  824. && profile < TOMOYO_MAX_PROFILES
  825. #endif
  826. && tomoyo_profile_ptr[profile] ?
  827. tomoyo_profile_ptr[profile]->value[index] : 0;
  828. }
  829. /**
  830. * tomoyo_verbose_mode - Check whether TOMOYO is verbose mode.
  831. *
  832. * @domain: Pointer to "struct tomoyo_domain_info".
  833. *
  834. * Returns true if domain policy violation warning should be printed to
  835. * console.
  836. */
  837. bool tomoyo_verbose_mode(const struct tomoyo_domain_info *domain)
  838. {
  839. return tomoyo_check_flags(domain, TOMOYO_VERBOSE) != 0;
  840. }
  841. /**
  842. * tomoyo_domain_quota_is_ok - Check for domain's quota.
  843. *
  844. * @domain: Pointer to "struct tomoyo_domain_info".
  845. *
  846. * Returns true if the domain is not exceeded quota, false otherwise.
  847. *
  848. * Caller holds tomoyo_read_lock().
  849. */
  850. bool tomoyo_domain_quota_is_ok(struct tomoyo_domain_info * const domain)
  851. {
  852. unsigned int count = 0;
  853. struct tomoyo_acl_info *ptr;
  854. if (!domain)
  855. return true;
  856. list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
  857. switch (ptr->type) {
  858. struct tomoyo_path_acl *acl;
  859. u32 perm;
  860. u8 i;
  861. case TOMOYO_TYPE_PATH_ACL:
  862. acl = container_of(ptr, struct tomoyo_path_acl, head);
  863. perm = acl->perm | (((u32) acl->perm_high) << 16);
  864. for (i = 0; i < TOMOYO_MAX_PATH_OPERATION; i++)
  865. if (perm & (1 << i))
  866. count++;
  867. if (perm & (1 << TOMOYO_TYPE_READ_WRITE))
  868. count -= 2;
  869. break;
  870. case TOMOYO_TYPE_PATH2_ACL:
  871. perm = container_of(ptr, struct tomoyo_path2_acl, head)
  872. ->perm;
  873. for (i = 0; i < TOMOYO_MAX_PATH2_OPERATION; i++)
  874. if (perm & (1 << i))
  875. count++;
  876. break;
  877. }
  878. }
  879. if (count < tomoyo_check_flags(domain, TOMOYO_MAX_ACCEPT_ENTRY))
  880. return true;
  881. if (!domain->quota_warned) {
  882. domain->quota_warned = true;
  883. printk(KERN_WARNING "TOMOYO-WARNING: "
  884. "Domain '%s' has so many ACLs to hold. "
  885. "Stopped learning mode.\n", domain->domainname->name);
  886. }
  887. return false;
  888. }
  889. /**
  890. * tomoyo_find_or_assign_new_profile - Create a new profile.
  891. *
  892. * @profile: Profile number to create.
  893. *
  894. * Returns pointer to "struct tomoyo_profile" on success, NULL otherwise.
  895. */
  896. static struct tomoyo_profile *tomoyo_find_or_assign_new_profile(const unsigned
  897. int profile)
  898. {
  899. struct tomoyo_profile *ptr = NULL;
  900. int i;
  901. if (profile >= TOMOYO_MAX_PROFILES)
  902. return NULL;
  903. if (mutex_lock_interruptible(&tomoyo_policy_lock))
  904. return NULL;
  905. ptr = tomoyo_profile_ptr[profile];
  906. if (ptr)
  907. goto ok;
  908. ptr = kmalloc(sizeof(*ptr), GFP_NOFS);
  909. if (!tomoyo_memory_ok(ptr)) {
  910. kfree(ptr);
  911. ptr = NULL;
  912. goto ok;
  913. }
  914. for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++)
  915. ptr->value[i] = tomoyo_control_array[i].current_value;
  916. mb(); /* Avoid out-of-order execution. */
  917. tomoyo_profile_ptr[profile] = ptr;
  918. ok:
  919. mutex_unlock(&tomoyo_policy_lock);
  920. return ptr;
  921. }
  922. /**
  923. * tomoyo_write_profile - Write to profile table.
  924. *
  925. * @head: Pointer to "struct tomoyo_io_buffer".
  926. *
  927. * Returns 0 on success, negative value otherwise.
  928. */
  929. static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
  930. {
  931. char *data = head->write_buf;
  932. unsigned int i;
  933. unsigned int value;
  934. char *cp;
  935. struct tomoyo_profile *profile;
  936. unsigned long num;
  937. cp = strchr(data, '-');
  938. if (cp)
  939. *cp = '\0';
  940. if (strict_strtoul(data, 10, &num))
  941. return -EINVAL;
  942. if (cp)
  943. data = cp + 1;
  944. profile = tomoyo_find_or_assign_new_profile(num);
  945. if (!profile)
  946. return -EINVAL;
  947. cp = strchr(data, '=');
  948. if (!cp)
  949. return -EINVAL;
  950. *cp = '\0';
  951. if (!strcmp(data, "COMMENT")) {
  952. const struct tomoyo_path_info *old_comment = profile->comment;
  953. profile->comment = tomoyo_get_name(cp + 1);
  954. tomoyo_put_name(old_comment);
  955. return 0;
  956. }
  957. for (i = 0; i < TOMOYO_MAX_CONTROL_INDEX; i++) {
  958. if (strcmp(data, tomoyo_control_array[i].keyword))
  959. continue;
  960. if (sscanf(cp + 1, "%u", &value) != 1) {
  961. int j;
  962. const char **modes;
  963. switch (i) {
  964. case TOMOYO_VERBOSE:
  965. modes = tomoyo_mode_2;
  966. break;
  967. default:
  968. modes = tomoyo_mode_4;
  969. break;
  970. }
  971. for (j = 0; j < 4; j++) {
  972. if (strcmp(cp + 1, modes[j]))
  973. continue;
  974. value = j;
  975. break;
  976. }
  977. if (j == 4)
  978. return -EINVAL;
  979. } else if (value > tomoyo_control_array[i].max_value) {
  980. value = tomoyo_control_array[i].max_value;
  981. }
  982. profile->value[i] = value;
  983. return 0;
  984. }
  985. return -EINVAL;
  986. }
  987. /**
  988. * tomoyo_read_profile - Read from profile table.
  989. *
  990. * @head: Pointer to "struct tomoyo_io_buffer".
  991. *
  992. * Returns 0.
  993. */
  994. static int tomoyo_read_profile(struct tomoyo_io_buffer *head)
  995. {
  996. static const int total = TOMOYO_MAX_CONTROL_INDEX + 1;
  997. int step;
  998. if (head->read_eof)
  999. return 0;
  1000. for (step = head->read_step; step < TOMOYO_MAX_PROFILES * total;
  1001. step++) {
  1002. const u8 index = step / total;
  1003. u8 type = step % total;
  1004. const struct tomoyo_profile *profile
  1005. = tomoyo_profile_ptr[index];
  1006. head->read_step = step;
  1007. if (!profile)
  1008. continue;
  1009. if (!type) { /* Print profile' comment tag. */
  1010. if (!tomoyo_io_printf(head, "%u-COMMENT=%s\n",
  1011. index, profile->comment ?
  1012. profile->comment->name : ""))
  1013. break;
  1014. continue;
  1015. }
  1016. type--;
  1017. if (type < TOMOYO_MAX_CONTROL_INDEX) {
  1018. const unsigned int value = profile->value[type];
  1019. const char **modes = NULL;
  1020. const char *keyword
  1021. = tomoyo_control_array[type].keyword;
  1022. switch (tomoyo_control_array[type].max_value) {
  1023. case 3:
  1024. modes = tomoyo_mode_4;
  1025. break;
  1026. case 1:
  1027. modes = tomoyo_mode_2;
  1028. break;
  1029. }
  1030. if (modes) {
  1031. if (!tomoyo_io_printf(head, "%u-%s=%s\n", index,
  1032. keyword, modes[value]))
  1033. break;
  1034. } else {
  1035. if (!tomoyo_io_printf(head, "%u-%s=%u\n", index,
  1036. keyword, value))
  1037. break;
  1038. }
  1039. }
  1040. }
  1041. if (step == TOMOYO_MAX_PROFILES * total)
  1042. head->read_eof = true;
  1043. return 0;
  1044. }
  1045. /*
  1046. * tomoyo_policy_manager_list is used for holding list of domainnames or
  1047. * programs which are permitted to modify configuration via
  1048. * /sys/kernel/security/tomoyo/ interface.
  1049. *
  1050. * An entry is added by
  1051. *
  1052. * # echo '<kernel> /sbin/mingetty /bin/login /bin/bash' > \
  1053. * /sys/kernel/security/tomoyo/manager
  1054. * (if you want to specify by a domainname)
  1055. *
  1056. * or
  1057. *
  1058. * # echo '/usr/lib/ccs/editpolicy' > /sys/kernel/security/tomoyo/manager
  1059. * (if you want to specify by a program's location)
  1060. *
  1061. * and is deleted by
  1062. *
  1063. * # echo 'delete <kernel> /sbin/mingetty /bin/login /bin/bash' > \
  1064. * /sys/kernel/security/tomoyo/manager
  1065. *
  1066. * or
  1067. *
  1068. * # echo 'delete /usr/lib/ccs/editpolicy' > \
  1069. * /sys/kernel/security/tomoyo/manager
  1070. *
  1071. * and all entries are retrieved by
  1072. *
  1073. * # cat /sys/kernel/security/tomoyo/manager
  1074. */
  1075. LIST_HEAD(tomoyo_policy_manager_list);
  1076. /**
  1077. * tomoyo_update_manager_entry - Add a manager entry.
  1078. *
  1079. * @manager: The path to manager or the domainnamme.
  1080. * @is_delete: True if it is a delete request.
  1081. *
  1082. * Returns 0 on success, negative value otherwise.
  1083. *
  1084. * Caller holds tomoyo_read_lock().
  1085. */
  1086. static int tomoyo_update_manager_entry(const char *manager,
  1087. const bool is_delete)
  1088. {
  1089. struct tomoyo_policy_manager_entry *ptr;
  1090. struct tomoyo_policy_manager_entry e = { };
  1091. int error = is_delete ? -ENOENT : -ENOMEM;
  1092. if (tomoyo_is_domain_def(manager)) {
  1093. if (!tomoyo_is_correct_domain(manager))
  1094. return -EINVAL;
  1095. e.is_domain = true;
  1096. } else {
  1097. if (!tomoyo_is_correct_path(manager, 1, -1, -1))
  1098. return -EINVAL;
  1099. }
  1100. e.manager = tomoyo_get_name(manager);
  1101. if (!e.manager)
  1102. return -ENOMEM;
  1103. if (mutex_lock_interruptible(&tomoyo_policy_lock))
  1104. goto out;
  1105. list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
  1106. if (ptr->manager != e.manager)
  1107. continue;
  1108. ptr->is_deleted = is_delete;
  1109. error = 0;
  1110. break;
  1111. }
  1112. if (!is_delete && error) {
  1113. struct tomoyo_policy_manager_entry *entry =
  1114. tomoyo_commit_ok(&e, sizeof(e));
  1115. if (entry) {
  1116. list_add_tail_rcu(&entry->list,
  1117. &tomoyo_policy_manager_list);
  1118. error = 0;
  1119. }
  1120. }
  1121. mutex_unlock(&tomoyo_policy_lock);
  1122. out:
  1123. tomoyo_put_name(e.manager);
  1124. return error;
  1125. }
  1126. /**
  1127. * tomoyo_write_manager_policy - Write manager policy.
  1128. *
  1129. * @head: Pointer to "struct tomoyo_io_buffer".
  1130. *
  1131. * Returns 0 on success, negative value otherwise.
  1132. *
  1133. * Caller holds tomoyo_read_lock().
  1134. */
  1135. static int tomoyo_write_manager_policy(struct tomoyo_io_buffer *head)
  1136. {
  1137. char *data = head->write_buf;
  1138. bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE);
  1139. if (!strcmp(data, "manage_by_non_root")) {
  1140. tomoyo_manage_by_non_root = !is_delete;
  1141. return 0;
  1142. }
  1143. return tomoyo_update_manager_entry(data, is_delete);
  1144. }
  1145. /**
  1146. * tomoyo_read_manager_policy - Read manager policy.
  1147. *
  1148. * @head: Pointer to "struct tomoyo_io_buffer".
  1149. *
  1150. * Returns 0.
  1151. *
  1152. * Caller holds tomoyo_read_lock().
  1153. */
  1154. static int tomoyo_read_manager_policy(struct tomoyo_io_buffer *head)
  1155. {
  1156. struct list_head *pos;
  1157. bool done = true;
  1158. if (head->read_eof)
  1159. return 0;
  1160. list_for_each_cookie(pos, head->read_var2,
  1161. &tomoyo_policy_manager_list) {
  1162. struct tomoyo_policy_manager_entry *ptr;
  1163. ptr = list_entry(pos, struct tomoyo_policy_manager_entry,
  1164. list);
  1165. if (ptr->is_deleted)
  1166. continue;
  1167. done = tomoyo_io_printf(head, "%s\n", ptr->manager->name);
  1168. if (!done)
  1169. break;
  1170. }
  1171. head->read_eof = done;
  1172. return 0;
  1173. }
  1174. /**
  1175. * tomoyo_is_policy_manager - Check whether the current process is a policy manager.
  1176. *
  1177. * Returns true if the current process is permitted to modify policy
  1178. * via /sys/kernel/security/tomoyo/ interface.
  1179. *
  1180. * Caller holds tomoyo_read_lock().
  1181. */
  1182. static bool tomoyo_is_policy_manager(void)
  1183. {
  1184. struct tomoyo_policy_manager_entry *ptr;
  1185. const char *exe;
  1186. const struct task_struct *task = current;
  1187. const struct tomoyo_path_info *domainname = tomoyo_domain()->domainname;
  1188. bool found = false;
  1189. if (!tomoyo_policy_loaded)
  1190. return true;
  1191. if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid))
  1192. return false;
  1193. list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
  1194. if (!ptr->is_deleted && ptr->is_domain
  1195. && !tomoyo_pathcmp(domainname, ptr->manager)) {
  1196. found = true;
  1197. break;
  1198. }
  1199. }
  1200. if (found)
  1201. return true;
  1202. exe = tomoyo_get_exe();
  1203. if (!exe)
  1204. return false;
  1205. list_for_each_entry_rcu(ptr, &tomoyo_policy_manager_list, list) {
  1206. if (!ptr->is_deleted && !ptr->is_domain
  1207. && !strcmp(exe, ptr->manager->name)) {
  1208. found = true;
  1209. break;
  1210. }
  1211. }
  1212. if (!found) { /* Reduce error messages. */
  1213. static pid_t last_pid;
  1214. const pid_t pid = current->pid;
  1215. if (last_pid != pid) {
  1216. printk(KERN_WARNING "%s ( %s ) is not permitted to "
  1217. "update policies.\n", domainname->name, exe);
  1218. last_pid = pid;
  1219. }
  1220. }
  1221. kfree(exe);
  1222. return found;
  1223. }
  1224. /**
  1225. * tomoyo_is_select_one - Parse select command.
  1226. *
  1227. * @head: Pointer to "struct tomoyo_io_buffer".
  1228. * @data: String to parse.
  1229. *
  1230. * Returns true on success, false otherwise.
  1231. *
  1232. * Caller holds tomoyo_read_lock().
  1233. */
  1234. static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head,
  1235. const char *data)
  1236. {
  1237. unsigned int pid;
  1238. struct tomoyo_domain_info *domain = NULL;
  1239. if (sscanf(data, "pid=%u", &pid) == 1) {
  1240. struct task_struct *p;
  1241. rcu_read_lock();
  1242. read_lock(&tasklist_lock);
  1243. p = find_task_by_vpid(pid);
  1244. if (p)
  1245. domain = tomoyo_real_domain(p);
  1246. read_unlock(&tasklist_lock);
  1247. rcu_read_unlock();
  1248. } else if (!strncmp(data, "domain=", 7)) {
  1249. if (tomoyo_is_domain_def(data + 7))
  1250. domain = tomoyo_find_domain(data + 7);
  1251. } else
  1252. return false;
  1253. head->write_var1 = domain;
  1254. /* Accessing read_buf is safe because head->io_sem is held. */
  1255. if (!head->read_buf)
  1256. return true; /* Do nothing if open(O_WRONLY). */
  1257. head->read_avail = 0;
  1258. tomoyo_io_printf(head, "# select %s\n", data);
  1259. head->read_single_domain = true;
  1260. head->read_eof = !domain;
  1261. if (domain) {
  1262. struct tomoyo_domain_info *d;
  1263. head->read_var1 = NULL;
  1264. list_for_each_entry_rcu(d, &tomoyo_domain_list, list) {
  1265. if (d == domain)
  1266. break;
  1267. head->read_var1 = &d->list;
  1268. }
  1269. head->read_var2 = NULL;
  1270. head->read_bit = 0;
  1271. head->read_step = 0;
  1272. if (domain->is_deleted)
  1273. tomoyo_io_printf(head, "# This is a deleted domain.\n");
  1274. }
  1275. return true;
  1276. }
  1277. /**
  1278. * tomoyo_delete_domain - Delete a domain.
  1279. *
  1280. * @domainname: The name of domain.
  1281. *
  1282. * Returns 0.
  1283. *
  1284. * Caller holds tomoyo_read_lock().
  1285. */
  1286. static int tomoyo_delete_domain(char *domainname)
  1287. {
  1288. struct tomoyo_domain_info *domain;
  1289. struct tomoyo_path_info name;
  1290. name.name = domainname;
  1291. tomoyo_fill_path_info(&name);
  1292. if (mutex_lock_interruptible(&tomoyo_policy_lock))
  1293. return 0;
  1294. /* Is there an active domain? */
  1295. list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
  1296. /* Never delete tomoyo_kernel_domain */
  1297. if (domain == &tomoyo_kernel_domain)
  1298. continue;
  1299. if (domain->is_deleted ||
  1300. tomoyo_pathcmp(domain->domainname, &name))
  1301. continue;
  1302. domain->is_deleted = true;
  1303. break;
  1304. }
  1305. mutex_unlock(&tomoyo_policy_lock);
  1306. return 0;
  1307. }
  1308. /**
  1309. * tomoyo_write_domain_policy - Write domain policy.
  1310. *
  1311. * @head: Pointer to "struct tomoyo_io_buffer".
  1312. *
  1313. * Returns 0 on success, negative value otherwise.
  1314. *
  1315. * Caller holds tomoyo_read_lock().
  1316. */
  1317. static int tomoyo_write_domain_policy(struct tomoyo_io_buffer *head)
  1318. {
  1319. char *data = head->write_buf;
  1320. struct tomoyo_domain_info *domain = head->write_var1;
  1321. bool is_delete = false;
  1322. bool is_select = false;
  1323. unsigned int profile;
  1324. if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE))
  1325. is_delete = true;
  1326. else if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_SELECT))
  1327. is_select = true;
  1328. if (is_select && tomoyo_is_select_one(head, data))
  1329. return 0;
  1330. /* Don't allow updating policies by non manager programs. */
  1331. if (!tomoyo_is_policy_manager())
  1332. return -EPERM;
  1333. if (tomoyo_is_domain_def(data)) {
  1334. domain = NULL;
  1335. if (is_delete)
  1336. tomoyo_delete_domain(data);
  1337. else if (is_select)
  1338. domain = tomoyo_find_domain(data);
  1339. else
  1340. domain = tomoyo_find_or_assign_new_domain(data, 0);
  1341. head->write_var1 = domain;
  1342. return 0;
  1343. }
  1344. if (!domain)
  1345. return -EINVAL;
  1346. if (sscanf(data, TOMOYO_KEYWORD_USE_PROFILE "%u", &profile) == 1
  1347. && profile < TOMOYO_MAX_PROFILES) {
  1348. if (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded)
  1349. domain->profile = (u8) profile;
  1350. return 0;
  1351. }
  1352. if (!strcmp(data, TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ)) {
  1353. domain->ignore_global_allow_read = !is_delete;
  1354. return 0;
  1355. }
  1356. return tomoyo_write_file_policy(data, domain, is_delete);
  1357. }
  1358. /**
  1359. * tomoyo_print_path_acl - Print a single path ACL entry.
  1360. *
  1361. * @head: Pointer to "struct tomoyo_io_buffer".
  1362. * @ptr: Pointer to "struct tomoyo_path_acl".
  1363. *
  1364. * Returns true on success, false otherwise.
  1365. */
  1366. static bool tomoyo_print_path_acl(struct tomoyo_io_buffer *head,
  1367. struct tomoyo_path_acl *ptr)
  1368. {
  1369. int pos;
  1370. u8 bit;
  1371. const u32 perm = ptr->perm | (((u32) ptr->perm_high) << 16);
  1372. for (bit = head->read_bit; bit < TOMOYO_MAX_PATH_OPERATION; bit++) {
  1373. if (!(perm & (1 << bit)))
  1374. continue;
  1375. /* Print "read/write" instead of "read" and "write". */
  1376. if ((bit == TOMOYO_TYPE_READ || bit == TOMOYO_TYPE_WRITE)
  1377. && (perm & (1 << TOMOYO_TYPE_READ_WRITE)))
  1378. continue;
  1379. pos = head->read_avail;
  1380. if (!tomoyo_io_printf(head, "allow_%s ",
  1381. tomoyo_path2keyword(bit)) ||
  1382. !tomoyo_print_name_union(head, &ptr->name) ||
  1383. !tomoyo_io_printf(head, "\n"))
  1384. goto out;
  1385. }
  1386. head->read_bit = 0;
  1387. return true;
  1388. out:
  1389. head->read_bit = bit;
  1390. head->read_avail = pos;
  1391. return false;
  1392. }
  1393. /**
  1394. * tomoyo_print_path2_acl - Print a double path ACL entry.
  1395. *
  1396. * @head: Pointer to "struct tomoyo_io_buffer".
  1397. * @ptr: Pointer to "struct tomoyo_path2_acl".
  1398. *
  1399. * Returns true on success, false otherwise.
  1400. */
  1401. static bool tomoyo_print_path2_acl(struct tomoyo_io_buffer *head,
  1402. struct tomoyo_path2_acl *ptr)
  1403. {
  1404. int pos;
  1405. const u8 perm = ptr->perm;
  1406. u8 bit;
  1407. for (bit = head->read_bit; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) {
  1408. if (!(perm & (1 << bit)))
  1409. continue;
  1410. pos = head->read_avail;
  1411. if (!tomoyo_io_printf(head, "allow_%s ",
  1412. tomoyo_path22keyword(bit)) ||
  1413. !tomoyo_print_name_union(head, &ptr->name1) ||
  1414. !tomoyo_print_name_union(head, &ptr->name2) ||
  1415. !tomoyo_io_printf(head, "\n"))
  1416. goto out;
  1417. }
  1418. head->read_bit = 0;
  1419. return true;
  1420. out:
  1421. head->read_bit = bit;
  1422. head->read_avail = pos;
  1423. return false;
  1424. }
  1425. /**
  1426. * tomoyo_print_entry - Print an ACL entry.
  1427. *
  1428. * @head: Pointer to "struct tomoyo_io_buffer".
  1429. * @ptr: Pointer to an ACL entry.
  1430. *
  1431. * Returns true on success, false otherwise.
  1432. */
  1433. static bool tomoyo_print_entry(struct tomoyo_io_buffer *head,
  1434. struct tomoyo_acl_info *ptr)
  1435. {
  1436. const u8 acl_type = ptr->type;
  1437. if (acl_type == TOMOYO_TYPE_PATH_ACL) {
  1438. struct tomoyo_path_acl *acl
  1439. = container_of(ptr, struct tomoyo_path_acl, head);
  1440. return tomoyo_print_path_acl(head, acl);
  1441. }
  1442. if (acl_type == TOMOYO_TYPE_PATH2_ACL) {
  1443. struct tomoyo_path2_acl *acl
  1444. = container_of(ptr, struct tomoyo_path2_acl, head);
  1445. return tomoyo_print_path2_acl(head, acl);
  1446. }
  1447. BUG(); /* This must not happen. */
  1448. return false;
  1449. }
  1450. /**
  1451. * tomoyo_read_domain_policy - Read domain policy.
  1452. *
  1453. * @head: Pointer to "struct tomoyo_io_buffer".
  1454. *
  1455. * Returns 0.
  1456. *
  1457. * Caller holds tomoyo_read_lock().
  1458. */
  1459. static int tomoyo_read_domain_policy(struct tomoyo_io_buffer *head)
  1460. {
  1461. struct list_head *dpos;
  1462. struct list_head *apos;
  1463. bool done = true;
  1464. if (head->read_eof)
  1465. return 0;
  1466. if (head->read_step == 0)
  1467. head->read_step = 1;
  1468. list_for_each_cookie(dpos, head->read_var1, &tomoyo_domain_list) {
  1469. struct tomoyo_domain_info *domain;
  1470. const char *quota_exceeded = "";
  1471. const char *transition_failed = "";
  1472. const char *ignore_global_allow_read = "";
  1473. domain = list_entry(dpos, struct tomoyo_domain_info, list);
  1474. if (head->read_step != 1)
  1475. goto acl_loop;
  1476. if (domain->is_deleted && !head->read_single_domain)
  1477. continue;
  1478. /* Print domainname and flags. */
  1479. if (domain->quota_warned)
  1480. quota_exceeded = "quota_exceeded\n";
  1481. if (domain->transition_failed)
  1482. transition_failed = "transition_failed\n";
  1483. if (domain->ignore_global_allow_read)
  1484. ignore_global_allow_read
  1485. = TOMOYO_KEYWORD_IGNORE_GLOBAL_ALLOW_READ "\n";
  1486. done = tomoyo_io_printf(head, "%s\n" TOMOYO_KEYWORD_USE_PROFILE
  1487. "%u\n%s%s%s\n",
  1488. domain->domainname->name,
  1489. domain->profile, quota_exceeded,
  1490. transition_failed,
  1491. ignore_global_allow_read);
  1492. if (!done)
  1493. break;
  1494. head->read_step = 2;
  1495. acl_loop:
  1496. if (head->read_step == 3)
  1497. goto tail_mark;
  1498. /* Print ACL entries in the domain. */
  1499. list_for_each_cookie(apos, head->read_var2,
  1500. &domain->acl_info_list) {
  1501. struct tomoyo_acl_info *ptr
  1502. = list_entry(apos, struct tomoyo_acl_info,
  1503. list);
  1504. done = tomoyo_print_entry(head, ptr);
  1505. if (!done)
  1506. break;
  1507. }
  1508. if (!done)
  1509. break;
  1510. head->read_step = 3;
  1511. tail_mark:
  1512. done = tomoyo_io_printf(head, "\n");
  1513. if (!done)
  1514. break;
  1515. head->read_step = 1;
  1516. if (head->read_single_domain)
  1517. break;
  1518. }
  1519. head->read_eof = done;
  1520. return 0;
  1521. }
  1522. /**
  1523. * tomoyo_write_domain_profile - Assign profile for specified domain.
  1524. *
  1525. * @head: Pointer to "struct tomoyo_io_buffer".
  1526. *
  1527. * Returns 0 on success, -EINVAL otherwise.
  1528. *
  1529. * This is equivalent to doing
  1530. *
  1531. * ( echo "select " $domainname; echo "use_profile " $profile ) |
  1532. * /usr/lib/ccs/loadpolicy -d
  1533. *
  1534. * Caller holds tomoyo_read_lock().
  1535. */
  1536. static int tomoyo_write_domain_profile(struct tomoyo_io_buffer *head)
  1537. {
  1538. char *data = head->write_buf;
  1539. char *cp = strchr(data, ' ');
  1540. struct tomoyo_domain_info *domain;
  1541. unsigned long profile;
  1542. if (!cp)
  1543. return -EINVAL;
  1544. *cp = '\0';
  1545. domain = tomoyo_find_domain(cp + 1);
  1546. if (strict_strtoul(data, 10, &profile))
  1547. return -EINVAL;
  1548. if (domain && profile < TOMOYO_MAX_PROFILES
  1549. && (tomoyo_profile_ptr[profile] || !tomoyo_policy_loaded))
  1550. domain->profile = (u8) profile;
  1551. return 0;
  1552. }
  1553. /**
  1554. * tomoyo_read_domain_profile - Read only domainname and profile.
  1555. *
  1556. * @head: Pointer to "struct tomoyo_io_buffer".
  1557. *
  1558. * Returns list of profile number and domainname pairs.
  1559. *
  1560. * This is equivalent to doing
  1561. *
  1562. * grep -A 1 '^<kernel>' /sys/kernel/security/tomoyo/domain_policy |
  1563. * awk ' { if ( domainname == "" ) { if ( $1 == "<kernel>" )
  1564. * domainname = $0; } else if ( $1 == "use_profile" ) {
  1565. * print $2 " " domainname; domainname = ""; } } ; '
  1566. *
  1567. * Caller holds tomoyo_read_lock().
  1568. */
  1569. static int tomoyo_read_domain_profile(struct tomoyo_io_buffer *head)
  1570. {
  1571. struct list_head *pos;
  1572. bool done = true;
  1573. if (head->read_eof)
  1574. return 0;
  1575. list_for_each_cookie(pos, head->read_var1, &tomoyo_domain_list) {
  1576. struct tomoyo_domain_info *domain;
  1577. domain = list_entry(pos, struct tomoyo_domain_info, list);
  1578. if (domain->is_deleted)
  1579. continue;
  1580. done = tomoyo_io_printf(head, "%u %s\n", domain->profile,
  1581. domain->domainname->name);
  1582. if (!done)
  1583. break;
  1584. }
  1585. head->read_eof = done;
  1586. return 0;
  1587. }
  1588. /**
  1589. * tomoyo_write_pid: Specify PID to obtain domainname.
  1590. *
  1591. * @head: Pointer to "struct tomoyo_io_buffer".
  1592. *
  1593. * Returns 0.
  1594. */
  1595. static int tomoyo_write_pid(struct tomoyo_io_buffer *head)
  1596. {
  1597. unsigned long pid;
  1598. /* No error check. */
  1599. strict_strtoul(head->write_buf, 10, &pid);
  1600. head->read_step = (int) pid;
  1601. head->read_eof = false;
  1602. return 0;
  1603. }
  1604. /**
  1605. * tomoyo_read_pid - Get domainname of the specified PID.
  1606. *
  1607. * @head: Pointer to "struct tomoyo_io_buffer".
  1608. *
  1609. * Returns the domainname which the specified PID is in on success,
  1610. * empty string otherwise.
  1611. * The PID is specified by tomoyo_write_pid() so that the user can obtain
  1612. * using read()/write() interface rather than sysctl() interface.
  1613. */
  1614. static int tomoyo_read_pid(struct tomoyo_io_buffer *head)
  1615. {
  1616. if (head->read_avail == 0 && !head->read_eof) {
  1617. const int pid = head->read_step;
  1618. struct task_struct *p;
  1619. struct tomoyo_domain_info *domain = NULL;
  1620. rcu_read_lock();
  1621. read_lock(&tasklist_lock);
  1622. p = find_task_by_vpid(pid);
  1623. if (p)
  1624. domain = tomoyo_real_domain(p);
  1625. read_unlock(&tasklist_lock);
  1626. rcu_read_unlock();
  1627. if (domain)
  1628. tomoyo_io_printf(head, "%d %u %s", pid, domain->profile,
  1629. domain->domainname->name);
  1630. head->read_eof = true;
  1631. }
  1632. return 0;
  1633. }
  1634. /**
  1635. * tomoyo_write_exception_policy - Write exception policy.
  1636. *
  1637. * @head: Pointer to "struct tomoyo_io_buffer".
  1638. *
  1639. * Returns 0 on success, negative value otherwise.
  1640. *
  1641. * Caller holds tomoyo_read_lock().
  1642. */
  1643. static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head)
  1644. {
  1645. char *data = head->write_buf;
  1646. bool is_delete = tomoyo_str_starts(&data, TOMOYO_KEYWORD_DELETE);
  1647. if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_KEEP_DOMAIN))
  1648. return tomoyo_write_domain_keeper_policy(data, false,
  1649. is_delete);
  1650. if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_KEEP_DOMAIN))
  1651. return tomoyo_write_domain_keeper_policy(data, true, is_delete);
  1652. if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_INITIALIZE_DOMAIN))
  1653. return tomoyo_write_domain_initializer_policy(data, false,
  1654. is_delete);
  1655. if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN))
  1656. return tomoyo_write_domain_initializer_policy(data, true,
  1657. is_delete);
  1658. if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALIAS))
  1659. return tomoyo_write_alias_policy(data, is_delete);
  1660. if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_ALLOW_READ))
  1661. return tomoyo_write_globally_readable_policy(data, is_delete);
  1662. if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_FILE_PATTERN))
  1663. return tomoyo_write_pattern_policy(data, is_delete);
  1664. if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DENY_REWRITE))
  1665. return tomoyo_write_no_rewrite_policy(data, is_delete);
  1666. if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_PATH_GROUP))
  1667. return tomoyo_write_path_group_policy(data, is_delete);
  1668. return -EINVAL;
  1669. }
  1670. /**
  1671. * tomoyo_read_exception_policy - Read exception policy.
  1672. *
  1673. * @head: Pointer to "struct tomoyo_io_buffer".
  1674. *
  1675. * Returns 0 on success, -EINVAL otherwise.
  1676. *
  1677. * Caller holds tomoyo_read_lock().
  1678. */
  1679. static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head)
  1680. {
  1681. if (!head->read_eof) {
  1682. switch (head->read_step) {
  1683. case 0:
  1684. head->read_var2 = NULL;
  1685. head->read_step = 1;
  1686. case 1:
  1687. if (!tomoyo_read_domain_keeper_policy(head))
  1688. break;
  1689. head->read_var2 = NULL;
  1690. head->read_step = 2;
  1691. case 2:
  1692. if (!tomoyo_read_globally_readable_policy(head))
  1693. break;
  1694. head->read_var2 = NULL;
  1695. head->read_step = 3;
  1696. case 3:
  1697. head->read_var2 = NULL;
  1698. head->read_step = 4;
  1699. case 4:
  1700. if (!tomoyo_read_domain_initializer_policy(head))
  1701. break;
  1702. head->read_var2 = NULL;
  1703. head->read_step = 5;
  1704. case 5:
  1705. if (!tomoyo_read_alias_policy(head))
  1706. break;
  1707. head->read_var2 = NULL;
  1708. head->read_step = 6;
  1709. case 6:
  1710. head->read_var2 = NULL;
  1711. head->read_step = 7;
  1712. case 7:
  1713. if (!tomoyo_read_file_pattern(head))
  1714. break;
  1715. head->read_var2 = NULL;
  1716. head->read_step = 8;
  1717. case 8:
  1718. if (!tomoyo_read_no_rewrite_policy(head))
  1719. break;
  1720. head->read_var2 = NULL;
  1721. head->read_step = 9;
  1722. case 9:
  1723. if (!tomoyo_read_path_group_policy(head))
  1724. break;
  1725. head->read_var1 = NULL;
  1726. head->read_var2 = NULL;
  1727. head->read_step = 10;
  1728. case 10:
  1729. head->read_eof = true;
  1730. break;
  1731. default:
  1732. return -EINVAL;
  1733. }
  1734. }
  1735. return 0;
  1736. }
  1737. /* path to policy loader */
  1738. static const char *tomoyo_loader = "/sbin/tomoyo-init";
  1739. /**
  1740. * tomoyo_policy_loader_exists - Check whether /sbin/tomoyo-init exists.
  1741. *
  1742. * Returns true if /sbin/tomoyo-init exists, false otherwise.
  1743. */
  1744. static bool tomoyo_policy_loader_exists(void)
  1745. {
  1746. /*
  1747. * Don't activate MAC if the policy loader doesn't exist.
  1748. * If the initrd includes /sbin/init but real-root-dev has not
  1749. * mounted on / yet, activating MAC will block the system since
  1750. * policies are not loaded yet.
  1751. * Thus, let do_execve() call this function everytime.
  1752. */
  1753. struct path path;
  1754. if (kern_path(tomoyo_loader, LOOKUP_FOLLOW, &path)) {
  1755. printk(KERN_INFO "Not activating Mandatory Access Control now "
  1756. "since %s doesn't exist.\n", tomoyo_loader);
  1757. return false;
  1758. }
  1759. path_put(&path);
  1760. return true;
  1761. }
  1762. /**
  1763. * tomoyo_load_policy - Run external policy loader to load policy.
  1764. *
  1765. * @filename: The program about to start.
  1766. *
  1767. * This function checks whether @filename is /sbin/init , and if so
  1768. * invoke /sbin/tomoyo-init and wait for the termination of /sbin/tomoyo-init
  1769. * and then continues invocation of /sbin/init.
  1770. * /sbin/tomoyo-init reads policy files in /etc/tomoyo/ directory and
  1771. * writes to /sys/kernel/security/tomoyo/ interfaces.
  1772. *
  1773. * Returns nothing.
  1774. */
  1775. void tomoyo_load_policy(const char *filename)
  1776. {
  1777. char *argv[2];
  1778. char *envp[3];
  1779. if (tomoyo_policy_loaded)
  1780. return;
  1781. /*
  1782. * Check filename is /sbin/init or /sbin/tomoyo-start.
  1783. * /sbin/tomoyo-start is a dummy filename in case where /sbin/init can't
  1784. * be passed.
  1785. * You can create /sbin/tomoyo-start by
  1786. * "ln -s /bin/true /sbin/tomoyo-start".
  1787. */
  1788. if (strcmp(filename, "/sbin/init") &&
  1789. strcmp(filename, "/sbin/tomoyo-start"))
  1790. return;
  1791. if (!tomoyo_policy_loader_exists())
  1792. return;
  1793. printk(KERN_INFO "Calling %s to load policy. Please wait.\n",
  1794. tomoyo_loader);
  1795. argv[0] = (char *) tomoyo_loader;
  1796. argv[1] = NULL;
  1797. envp[0] = "HOME=/";
  1798. envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
  1799. envp[2] = NULL;
  1800. call_usermodehelper(argv[0], argv, envp, 1);
  1801. printk(KERN_INFO "TOMOYO: 2.2.0 2009/04/01\n");
  1802. printk(KERN_INFO "Mandatory Access Control activated.\n");
  1803. tomoyo_policy_loaded = true;
  1804. { /* Check all profiles currently assigned to domains are defined. */
  1805. struct tomoyo_domain_info *domain;
  1806. list_for_each_entry_rcu(domain, &tomoyo_domain_list, list) {
  1807. const u8 profile = domain->profile;
  1808. if (tomoyo_profile_ptr[profile])
  1809. continue;
  1810. panic("Profile %u (used by '%s') not defined.\n",
  1811. profile, domain->domainname->name);
  1812. }
  1813. }
  1814. }
  1815. /**
  1816. * tomoyo_read_version: Get version.
  1817. *
  1818. * @head: Pointer to "struct tomoyo_io_buffer".
  1819. *
  1820. * Returns version information.
  1821. */
  1822. static int tomoyo_read_version(struct tomoyo_io_buffer *head)
  1823. {
  1824. if (!head->read_eof) {
  1825. tomoyo_io_printf(head, "2.2.0");
  1826. head->read_eof = true;
  1827. }
  1828. return 0;
  1829. }
  1830. /**
  1831. * tomoyo_read_self_domain - Get the current process's domainname.
  1832. *
  1833. * @head: Pointer to "struct tomoyo_io_buffer".
  1834. *
  1835. * Returns the current process's domainname.
  1836. */
  1837. static int tomoyo_read_self_domain(struct tomoyo_io_buffer *head)
  1838. {
  1839. if (!head->read_eof) {
  1840. /*
  1841. * tomoyo_domain()->domainname != NULL
  1842. * because every process belongs to a domain and
  1843. * the domain's name cannot be NULL.
  1844. */
  1845. tomoyo_io_printf(head, "%s", tomoyo_domai