diff options
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r-- | security/tomoyo/common.c | 100 |
1 files changed, 87 insertions, 13 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 62e089c50ae8..b5dbdc9ff73c 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -76,6 +76,49 @@ static int tomoyo_write_control(struct file *file, const char __user *buffer, | |||
76 | const int buffer_len); | 76 | const int buffer_len); |
77 | 77 | ||
78 | /** | 78 | /** |
79 | * tomoyo_parse_name_union - Parse a tomoyo_name_union. | ||
80 | * | ||
81 | * @filename: Name or name group. | ||
82 | * @ptr: Pointer to "struct tomoyo_name_union". | ||
83 | * | ||
84 | * Returns true on success, false otherwise. | ||
85 | */ | ||
86 | bool tomoyo_parse_name_union(const char *filename, | ||
87 | struct tomoyo_name_union *ptr) | ||
88 | { | ||
89 | if (!tomoyo_is_correct_path(filename, 0, 0, 0)) | ||
90 | return false; | ||
91 | if (filename[0] == '@') { | ||
92 | ptr->group = tomoyo_get_path_group(filename + 1); | ||
93 | ptr->is_group = true; | ||
94 | return ptr->group != NULL; | ||
95 | } | ||
96 | ptr->filename = tomoyo_get_name(filename); | ||
97 | ptr->is_group = false; | ||
98 | return ptr->filename != NULL; | ||
99 | } | ||
100 | |||
101 | /** | ||
102 | * tomoyo_print_name_union - Print a tomoyo_name_union. | ||
103 | * | ||
104 | * @head: Pointer to "struct tomoyo_io_buffer". | ||
105 | * @ptr: Pointer to "struct tomoyo_name_union". | ||
106 | * | ||
107 | * Returns true on success, false otherwise. | ||
108 | */ | ||
109 | static bool tomoyo_print_name_union(struct tomoyo_io_buffer *head, | ||
110 | const struct tomoyo_name_union *ptr) | ||
111 | { | ||
112 | int pos = head->read_avail; | ||
113 | if (pos && head->read_buf[pos - 1] == ' ') | ||
114 | head->read_avail--; | ||
115 | if (ptr->is_group) | ||
116 | return tomoyo_io_printf(head, " @%s", | ||
117 | ptr->group->group_name->name); | ||
118 | return tomoyo_io_printf(head, " %s", ptr->filename->name); | ||
119 | } | ||
120 | |||
121 | /** | ||
79 | * tomoyo_is_byte_range - Check whether the string isa \ooo style octal value. | 122 | * tomoyo_is_byte_range - Check whether the string isa \ooo style octal value. |
80 | * | 123 | * |
81 | * @str: Pointer to the string. | 124 | * @str: Pointer to the string. |
@@ -172,6 +215,33 @@ static void tomoyo_normalize_line(unsigned char *buffer) | |||
172 | } | 215 | } |
173 | 216 | ||
174 | /** | 217 | /** |
218 | * tomoyo_tokenize - Tokenize string. | ||
219 | * | ||
220 | * @buffer: The line to tokenize. | ||
221 | * @w: Pointer to "char *". | ||
222 | * @size: Sizeof @w . | ||
223 | * | ||
224 | * Returns true on success, false otherwise. | ||
225 | */ | ||
226 | bool tomoyo_tokenize(char *buffer, char *w[], size_t size) | ||
227 | { | ||
228 | int count = size / sizeof(char *); | ||
229 | int i; | ||
230 | for (i = 0; i < count; i++) | ||
231 | w[i] = ""; | ||
232 | for (i = 0; i < count; i++) { | ||
233 | char *cp = strchr(buffer, ' '); | ||
234 | if (cp) | ||
235 | *cp = '\0'; | ||
236 | w[i] = buffer; | ||
237 | if (!cp) | ||
238 | break; | ||
239 | buffer = cp + 1; | ||
240 | } | ||
241 | return i < count || !*buffer; | ||
242 | } | ||
243 | |||
244 | /** | ||
175 | * tomoyo_is_correct_path - Validate a pathname. | 245 | * tomoyo_is_correct_path - Validate a pathname. |
176 | * @filename: The pathname to check. | 246 | * @filename: The pathname to check. |
177 | * @start_type: Should the pathname start with '/'? | 247 | * @start_type: Should the pathname start with '/'? |
@@ -1368,21 +1438,20 @@ static bool tomoyo_print_path_acl(struct tomoyo_io_buffer *head, | |||
1368 | { | 1438 | { |
1369 | int pos; | 1439 | int pos; |
1370 | u8 bit; | 1440 | u8 bit; |
1371 | const char *filename; | ||
1372 | const u32 perm = ptr->perm | (((u32) ptr->perm_high) << 16); | 1441 | const u32 perm = ptr->perm | (((u32) ptr->perm_high) << 16); |
1373 | 1442 | ||
1374 | filename = ptr->filename->name; | ||
1375 | for (bit = head->read_bit; bit < TOMOYO_MAX_PATH_OPERATION; bit++) { | 1443 | for (bit = head->read_bit; bit < TOMOYO_MAX_PATH_OPERATION; bit++) { |
1376 | const char *msg; | ||
1377 | if (!(perm & (1 << bit))) | 1444 | if (!(perm & (1 << bit))) |
1378 | continue; | 1445 | continue; |
1379 | /* Print "read/write" instead of "read" and "write". */ | 1446 | /* Print "read/write" instead of "read" and "write". */ |
1380 | if ((bit == TOMOYO_TYPE_READ || bit == TOMOYO_TYPE_WRITE) | 1447 | if ((bit == TOMOYO_TYPE_READ || bit == TOMOYO_TYPE_WRITE) |
1381 | && (perm & (1 << TOMOYO_TYPE_READ_WRITE))) | 1448 | && (perm & (1 << TOMOYO_TYPE_READ_WRITE))) |
1382 | continue; | 1449 | continue; |
1383 | msg = tomoyo_path2keyword(bit); | ||
1384 | pos = head->read_avail; | 1450 | pos = head->read_avail; |
1385 | if (!tomoyo_io_printf(head, "allow_%s %s\n", msg, filename)) | 1451 | if (!tomoyo_io_printf(head, "allow_%s ", |
1452 | tomoyo_path2keyword(bit)) || | ||
1453 | !tomoyo_print_name_union(head, &ptr->name) || | ||
1454 | !tomoyo_io_printf(head, "\n")) | ||
1386 | goto out; | 1455 | goto out; |
1387 | } | 1456 | } |
1388 | head->read_bit = 0; | 1457 | head->read_bit = 0; |
@@ -1405,21 +1474,18 @@ static bool tomoyo_print_path2_acl(struct tomoyo_io_buffer *head, | |||
1405 | struct tomoyo_path2_acl *ptr) | 1474 | struct tomoyo_path2_acl *ptr) |
1406 | { | 1475 | { |
1407 | int pos; | 1476 | int pos; |
1408 | const char *filename1; | ||
1409 | const char *filename2; | ||
1410 | const u8 perm = ptr->perm; | 1477 | const u8 perm = ptr->perm; |
1411 | u8 bit; | 1478 | u8 bit; |
1412 | 1479 | ||
1413 | filename1 = ptr->filename1->name; | ||
1414 | filename2 = ptr->filename2->name; | ||
1415 | for (bit = head->read_bit; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) { | 1480 | for (bit = head->read_bit; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) { |
1416 | const char *msg; | ||
1417 | if (!(perm & (1 << bit))) | 1481 | if (!(perm & (1 << bit))) |
1418 | continue; | 1482 | continue; |
1419 | msg = tomoyo_path22keyword(bit); | ||
1420 | pos = head->read_avail; | 1483 | pos = head->read_avail; |
1421 | if (!tomoyo_io_printf(head, "allow_%s %s %s\n", msg, | 1484 | if (!tomoyo_io_printf(head, "allow_%s ", |
1422 | filename1, filename2)) | 1485 | tomoyo_path22keyword(bit)) || |
1486 | !tomoyo_print_name_union(head, &ptr->name1) || | ||
1487 | !tomoyo_print_name_union(head, &ptr->name2) || | ||
1488 | !tomoyo_io_printf(head, "\n")) | ||
1423 | goto out; | 1489 | goto out; |
1424 | } | 1490 | } |
1425 | head->read_bit = 0; | 1491 | head->read_bit = 0; |
@@ -1682,6 +1748,8 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) | |||
1682 | return tomoyo_write_pattern_policy(data, is_delete); | 1748 | return tomoyo_write_pattern_policy(data, is_delete); |
1683 | if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DENY_REWRITE)) | 1749 | if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DENY_REWRITE)) |
1684 | return tomoyo_write_no_rewrite_policy(data, is_delete); | 1750 | return tomoyo_write_no_rewrite_policy(data, is_delete); |
1751 | if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_PATH_GROUP)) | ||
1752 | return tomoyo_write_path_group_policy(data, is_delete); | ||
1685 | return -EINVAL; | 1753 | return -EINVAL; |
1686 | } | 1754 | } |
1687 | 1755 | ||
@@ -1738,6 +1806,12 @@ static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head) | |||
1738 | head->read_var2 = NULL; | 1806 | head->read_var2 = NULL; |
1739 | head->read_step = 9; | 1807 | head->read_step = 9; |
1740 | case 9: | 1808 | case 9: |
1809 | if (!tomoyo_read_path_group_policy(head)) | ||
1810 | break; | ||
1811 | head->read_var1 = NULL; | ||
1812 | head->read_var2 = NULL; | ||
1813 | head->read_step = 10; | ||
1814 | case 10: | ||
1741 | head->read_eof = true; | 1815 | head->read_eof = true; |
1742 | break; | 1816 | break; |
1743 | default: | 1817 | default: |