From 7762fbfffdbce8191f5236d5053b290035d3d749 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Mon, 10 May 2010 17:30:26 +0900 Subject: TOMOYO: Add pathname grouping support. This patch adds pathname grouping support, which is useful for grouping pathnames that cannot be represented using /\{dir\}/ pattern. Signed-off-by: Tetsuo Handa Signed-off-by: James Morris --- security/tomoyo/common.c | 100 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 87 insertions(+), 13 deletions(-) (limited to 'security/tomoyo/common.c') 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 @@ -75,6 +75,49 @@ static int tomoyo_read_control(struct file *file, char __user *buffer, static int tomoyo_write_control(struct file *file, const char __user *buffer, const int buffer_len); +/** + * tomoyo_parse_name_union - Parse a tomoyo_name_union. + * + * @filename: Name or name group. + * @ptr: Pointer to "struct tomoyo_name_union". + * + * Returns true on success, false otherwise. + */ +bool tomoyo_parse_name_union(const char *filename, + struct tomoyo_name_union *ptr) +{ + if (!tomoyo_is_correct_path(filename, 0, 0, 0)) + return false; + if (filename[0] == '@') { + ptr->group = tomoyo_get_path_group(filename + 1); + ptr->is_group = true; + return ptr->group != NULL; + } + ptr->filename = tomoyo_get_name(filename); + ptr->is_group = false; + return ptr->filename != NULL; +} + +/** + * tomoyo_print_name_union - Print a tomoyo_name_union. + * + * @head: Pointer to "struct tomoyo_io_buffer". + * @ptr: Pointer to "struct tomoyo_name_union". + * + * Returns true on success, false otherwise. + */ +static bool tomoyo_print_name_union(struct tomoyo_io_buffer *head, + const struct tomoyo_name_union *ptr) +{ + int pos = head->read_avail; + if (pos && head->read_buf[pos - 1] == ' ') + head->read_avail--; + if (ptr->is_group) + return tomoyo_io_printf(head, " @%s", + ptr->group->group_name->name); + return tomoyo_io_printf(head, " %s", ptr->filename->name); +} + /** * tomoyo_is_byte_range - Check whether the string isa \ooo style octal value. * @@ -171,6 +214,33 @@ static void tomoyo_normalize_line(unsigned char *buffer) *dp = '\0'; } +/** + * tomoyo_tokenize - Tokenize string. + * + * @buffer: The line to tokenize. + * @w: Pointer to "char *". + * @size: Sizeof @w . + * + * Returns true on success, false otherwise. + */ +bool tomoyo_tokenize(char *buffer, char *w[], size_t size) +{ + int count = size / sizeof(char *); + int i; + for (i = 0; i < count; i++) + w[i] = ""; + for (i = 0; i < count; i++) { + char *cp = strchr(buffer, ' '); + if (cp) + *cp = '\0'; + w[i] = buffer; + if (!cp) + break; + buffer = cp + 1; + } + return i < count || !*buffer; +} + /** * tomoyo_is_correct_path - Validate a pathname. * @filename: The pathname to check. @@ -1368,21 +1438,20 @@ static bool tomoyo_print_path_acl(struct tomoyo_io_buffer *head, { int pos; u8 bit; - const char *filename; const u32 perm = ptr->perm | (((u32) ptr->perm_high) << 16); - filename = ptr->filename->name; for (bit = head->read_bit; bit < TOMOYO_MAX_PATH_OPERATION; bit++) { - const char *msg; if (!(perm & (1 << bit))) continue; /* Print "read/write" instead of "read" and "write". */ if ((bit == TOMOYO_TYPE_READ || bit == TOMOYO_TYPE_WRITE) && (perm & (1 << TOMOYO_TYPE_READ_WRITE))) continue; - msg = tomoyo_path2keyword(bit); pos = head->read_avail; - if (!tomoyo_io_printf(head, "allow_%s %s\n", msg, filename)) + if (!tomoyo_io_printf(head, "allow_%s ", + tomoyo_path2keyword(bit)) || + !tomoyo_print_name_union(head, &ptr->name) || + !tomoyo_io_printf(head, "\n")) goto out; } head->read_bit = 0; @@ -1405,21 +1474,18 @@ static bool tomoyo_print_path2_acl(struct tomoyo_io_buffer *head, struct tomoyo_path2_acl *ptr) { int pos; - const char *filename1; - const char *filename2; const u8 perm = ptr->perm; u8 bit; - filename1 = ptr->filename1->name; - filename2 = ptr->filename2->name; for (bit = head->read_bit; bit < TOMOYO_MAX_PATH2_OPERATION; bit++) { - const char *msg; if (!(perm & (1 << bit))) continue; - msg = tomoyo_path22keyword(bit); pos = head->read_avail; - if (!tomoyo_io_printf(head, "allow_%s %s %s\n", msg, - filename1, filename2)) + if (!tomoyo_io_printf(head, "allow_%s ", + tomoyo_path22keyword(bit)) || + !tomoyo_print_name_union(head, &ptr->name1) || + !tomoyo_print_name_union(head, &ptr->name2) || + !tomoyo_io_printf(head, "\n")) goto out; } head->read_bit = 0; @@ -1682,6 +1748,8 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) return tomoyo_write_pattern_policy(data, is_delete); if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_DENY_REWRITE)) return tomoyo_write_no_rewrite_policy(data, is_delete); + if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_PATH_GROUP)) + return tomoyo_write_path_group_policy(data, is_delete); return -EINVAL; } @@ -1738,6 +1806,12 @@ static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head) head->read_var2 = NULL; head->read_step = 9; case 9: + if (!tomoyo_read_path_group_policy(head)) + break; + head->read_var1 = NULL; + head->read_var2 = NULL; + head->read_step = 10; + case 10: head->read_eof = true; break; default: -- cgit v1.2.2