diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index cb1aaf148ad4..044115d49033 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c @@ -1192,6 +1192,194 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) return -EINVAL; } +static void tomoyo_print_number(char *buffer, int buffer_len, + const struct tomoyo_number_union *ptr) +{ + int i; + unsigned long min = ptr->values[0]; + const unsigned long max = ptr->values[1]; + u8 min_type = ptr->min_type; + const u8 max_type = ptr->max_type; + memset(buffer, 0, buffer_len); + buffer_len -= 2; + for (i = 0; i < 2; i++) { + int len; + switch (min_type) { + case TOMOYO_VALUE_TYPE_HEXADECIMAL: + snprintf(buffer, buffer_len, "0x%lX", min); + break; + case TOMOYO_VALUE_TYPE_OCTAL: + snprintf(buffer, buffer_len, "0%lo", min); + break; + default: + snprintf(buffer, buffer_len, "%lu", min); + break; + } + if (min == max && min_type == max_type) + break; + len = strlen(buffer); + buffer[len++] = '-'; + buffer += len; + buffer_len -= len; + min_type = max_type; + min = max; + } +} + +static const char *tomoyo_group_name[TOMOYO_MAX_GROUP] = { + [TOMOYO_PATH_GROUP] = TOMOYO_KEYWORD_PATH_GROUP, + [TOMOYO_NUMBER_GROUP] = TOMOYO_KEYWORD_NUMBER_GROUP +}; + +/** + * tomoyo_read_group - Read "struct tomoyo_path_group"/"struct tomoyo_number_group" list. + * + * @head: Pointer to "struct tomoyo_io_buffer". + * @idx: Index number. + * + * Returns true on success, false otherwise. + * + * Caller holds tomoyo_read_lock(). + */ +static bool tomoyo_read_group(struct tomoyo_io_buffer *head, const int idx) +{ + struct list_head *gpos; + struct list_head *mpos; + const char *w[3] = { "", "", "" }; + w[0] = tomoyo_group_name[idx]; + list_for_each_cookie(gpos, head->read_var1, &tomoyo_group_list[idx]) { + struct tomoyo_group *group = + list_entry(gpos, struct tomoyo_group, list); + w[1] = group->group_name->name; + list_for_each_cookie(mpos, head->read_var2, + &group->member_list) { + char buffer[128]; + struct tomoyo_acl_head *ptr = + list_entry(mpos, struct tomoyo_acl_head, list); + if (ptr->is_deleted) + continue; + if (idx == TOMOYO_PATH_GROUP) { + w[2] = container_of(ptr, + struct tomoyo_path_group, + head)->member_name->name; + } else if (idx == TOMOYO_NUMBER_GROUP) { + tomoyo_print_number(buffer, sizeof(buffer), + &container_of + (ptr, struct + tomoyo_number_group, + head)->number); + w[2] = buffer; + } + if (!tomoyo_io_printf(head, "%s%s %s\n", w[0], w[1], + w[2])) + return false; + } + } + return true; +} + +/** + * tomoyo_read_policy - Read "struct tomoyo_..._entry" list. + * + * @head: Pointer to "struct tomoyo_io_buffer". + * @idx: Index number. + * + * Returns true on success, false otherwise. + * + * Caller holds tomoyo_read_lock(). + */ +static bool tomoyo_read_policy(struct tomoyo_io_buffer *head, const int idx) +{ + struct list_head *pos; + list_for_each_cookie(pos, head->read_var2, &tomoyo_policy_list[idx]) { + const char *w[4] = { "", "", "", "" }; + struct tomoyo_acl_head *acl = container_of(pos, typeof(*acl), + list); + if (acl->is_deleted) + continue; + switch (idx) { + case TOMOYO_ID_DOMAIN_KEEPER: + { + struct tomoyo_domain_keeper_entry *ptr = + container_of(acl, typeof(*ptr), head); + w[0] = ptr->is_not ? + TOMOYO_KEYWORD_NO_KEEP_DOMAIN : + TOMOYO_KEYWORD_KEEP_DOMAIN; + if (ptr->program) { + w[1] = ptr->program->name; + w[2] = " from "; + } + w[3] = ptr->domainname->name; + } + break; + case TOMOYO_ID_DOMAIN_INITIALIZER: + { + struct tomoyo_domain_initializer_entry *ptr = + container_of(acl, typeof(*ptr), head); + w[0] = ptr->is_not ? + TOMOYO_KEYWORD_NO_INITIALIZE_DOMAIN : + TOMOYO_KEYWORD_INITIALIZE_DOMAIN; + w[1] = ptr->program->name; + if (ptr->domainname) { + w[2] = " from "; + w[3] = ptr->domainname->name; + } + } + break; + case TOMOYO_ID_GLOBALLY_READABLE: + { + struct tomoyo_globally_readable_file_entry *ptr + = container_of(acl, typeof(*ptr), head); + w[0] = TOMOYO_KEYWORD_ALLOW_READ; + w[1] = ptr->filename->name; + } + break; + case TOMOYO_ID_ALIAS: + { + struct tomoyo_alias_entry *ptr = + container_of(acl, typeof(*ptr), head); + w[0] = TOMOYO_KEYWORD_ALIAS; + w[1] = ptr->original_name->name; + w[2] = " "; + w[3] = ptr->aliased_name->name; + } + break; + case TOMOYO_ID_AGGREGATOR: + { + struct tomoyo_aggregator_entry *ptr = + container_of(acl, typeof(*ptr), head); + w[0] = TOMOYO_KEYWORD_AGGREGATOR; + w[1] = ptr->original_name->name; + w[2] = " "; + w[3] = ptr->aggregated_name->name; + } + break; + case TOMOYO_ID_PATTERN: + { + struct tomoyo_pattern_entry *ptr = + container_of(acl, typeof(*ptr), head); + w[0] = TOMOYO_KEYWORD_FILE_PATTERN; + w[1] = ptr->pattern->name; + } + break; + case TOMOYO_ID_NO_REWRITE: + { + struct tomoyo_no_rewrite_entry *ptr = + container_of(acl, typeof(*ptr), head); + w[0] = TOMOYO_KEYWORD_DENY_REWRITE; + w[1] = ptr->pattern->name; + } + break; + default: + continue; + } + if (!tomoyo_io_printf(head, "%s%s%s%s\n", w[0], w[1], w[2], + w[3])) + return false; + } + return true; +} + /** * tomoyo_read_exception_policy - Read exception policy. * @@ -1201,66 +1389,19 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) */ static void tomoyo_read_exception_policy(struct tomoyo_io_buffer *head) { - if (!head->read_eof) { - switch (head->read_step) { - case 0: - head->read_var2 = NULL; - head->read_step = 1; - case 1: - if (!tomoyo_read_domain_keeper_policy(head)) - break; - head->read_var2 = NULL; - head->read_step = 2; - case 2: - if (!tomoyo_read_globally_readable_policy(head)) - break; - head->read_var2 = NULL; - head->read_step = 3; - case 3: - head->read_var2 = NULL; - head->read_step = 4; - case 4: - if (!tomoyo_read_domain_initializer_policy(head)) - break; - head->read_var2 = NULL; - head->read_step = 5; - case 5: - if (!tomoyo_read_alias_policy(head)) - break; - head->read_var2 = NULL; - head->read_step = 6; - case 6: - if (!tomoyo_read_aggregator_policy(head)) - break; - head->read_var2 = NULL; - head->read_step = 7; - case 7: - if (!tomoyo_read_file_pattern(head)) - break; - head->read_var2 = NULL; - head->read_step = 8; - case 8: - if (!tomoyo_read_no_rewrite_policy(head)) - break; - 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: - if (!tomoyo_read_number_group_policy(head)) - break; - head->read_var1 = NULL; - head->read_var2 = NULL; - head->read_step = 11; - case 11: - head->read_eof = true; - break; - } - } + if (head->read_eof) + return; + while (head->read_step < TOMOYO_MAX_POLICY && + tomoyo_read_policy(head, head->read_step)) + head->read_step++; + if (head->read_step < TOMOYO_MAX_POLICY) + return; + while (head->read_step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP && + tomoyo_read_group(head, head->read_step - TOMOYO_MAX_POLICY)) + head->read_step++; + if (head->read_step < TOMOYO_MAX_POLICY + TOMOYO_MAX_GROUP) + return; + head->read_eof = true; } /** diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 451dc3c1036a..21eb1e7885b8 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h @@ -794,28 +794,6 @@ bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename, bool tomoyo_print_number_union(struct tomoyo_io_buffer *head, const struct tomoyo_number_union *ptr); bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num); - -/* Read "aggregator" entry in exception policy. */ -bool tomoyo_read_aggregator_policy(struct tomoyo_io_buffer *head); -/* Read "alias" entry in exception policy. */ -bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head); -/* - * Read "initialize_domain" and "no_initialize_domain" entry - * in exception policy. - */ -bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head); -/* Read "keep_domain" and "no_keep_domain" entry in exception policy. */ -bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head); -/* Read "file_pattern" entry in exception policy. */ -bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head); -/* Read "path_group" entry in exception policy. */ -bool tomoyo_read_path_group_policy(struct tomoyo_io_buffer *head); -/* Read "number_group" entry in exception policy. */ -bool tomoyo_read_number_group_policy(struct tomoyo_io_buffer *head); -/* Read "allow_read" entry in exception policy. */ -bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head); -/* Read "deny_rewrite" entry in exception policy. */ -bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head); /* Tokenize a line. */ bool tomoyo_tokenize(char *buffer, char *w[], size_t size); /* Write domain policy violation warning message to console? */ diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index 3575b0e7c7fd..038071a8a3d3 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c @@ -209,45 +209,6 @@ static int tomoyo_update_domain_initializer_entry(const char *domainname, return error; } -/** - * tomoyo_read_domain_initializer_policy - Read "struct tomoyo_domain_initializer_entry" list. - * - * @head: Pointer to "struct tomoyo_io_buffer". - * - * Returns true on success, false otherwise. - * - * Caller holds tomoyo_read_lock(). - */ -bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head) -{ - struct list_head *pos; - bool done = true; - - list_for_each_cookie(pos, head->read_var2, &tomoyo_policy_list - [TOMOYO_ID_DOMAIN_INITIALIZER]) { - const char *no; - const char *from = ""; - const char *domain = ""; - struct tomoyo_domain_initializer_entry *ptr; - ptr = list_entry(pos, struct tomoyo_domain_initializer_entry, - head.list); - if (ptr->head.is_deleted) - continue; - no = ptr->is_not ? "no_" : ""; - if (ptr->domainname) { - from = " from "; - domain = ptr->domainname->name; - } - done = tomoyo_io_printf(head, - "%s" TOMOYO_KEYWORD_INITIALIZE_DOMAIN - "%s%s%s\n", no, ptr->program->name, - from, domain); - if (!done) - break; - } - return done; -} - /** * tomoyo_write_domain_initializer_policy - Write "struct tomoyo_domain_initializer_entry" list. * @@ -398,46 +359,6 @@ int tomoyo_write_domain_keeper_policy(char *data, const bool is_not, return tomoyo_update_domain_keeper_entry(data, NULL, is_not, is_delete); } -/** - * tomoyo_read_domain_keeper_policy - Read "struct tomoyo_domain_keeper_entry" list. - * - * @head: Pointer to "struct tomoyo_io_buffer". - * - * Returns true on success, false otherwise. - * - * Caller holds tomoyo_read_lock(). - */ -bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head) -{ - struct list_head *pos; - bool done = true; - - list_for_each_cookie(pos, head->read_var2, - &tomoyo_policy_list[TOMOYO_ID_DOMAIN_KEEPER]) { - struct tomoyo_domain_keeper_entry *ptr; - const char *no; - const char *from = ""; - const char *program = ""; - - ptr = list_entry(pos, struct tomoyo_domain_keeper_entry, - head.list); - if (ptr->head.is_deleted) - continue; - no = ptr->is_not ? "no_" : ""; - if (ptr->program) { - from = " from "; - program = ptr->program->name; - } - done = tomoyo_io_printf(head, - "%s" TOMOYO_KEYWORD_KEEP_DOMAIN - "%s%s%s\n", no, program, from, - ptr->domainname->name); - if (!done) - break; - } - return done; -} - /** * tomoyo_domain_keeper - Check whether the given program causes domain transition suppression. * @@ -526,37 +447,6 @@ static int tomoyo_update_aggregator_entry(const char *original_name, return error; } -/** - * tomoyo_read_aggregator_policy - Read "struct tomoyo_aggregator_entry" list. - * - * @head: Pointer to "struct tomoyo_io_buffer". - * - * Returns true on success, false otherwise. - * - * Caller holds tomoyo_read_lock(). - */ -bool tomoyo_read_aggregator_policy(struct tomoyo_io_buffer *head) -{ - struct list_head *pos; - bool done = true; - - list_for_each_cookie(pos, head->read_var2, - &tomoyo_policy_list[TOMOYO_ID_AGGREGATOR]) { - struct tomoyo_aggregator_entry *ptr; - - ptr = list_entry(pos, struct tomoyo_aggregator_entry, - head.list); - if (ptr->head.is_deleted) - continue; - done = tomoyo_io_printf(head, TOMOYO_KEYWORD_AGGREGATOR - "%s %s\n", ptr->original_name->name, - ptr->aggregated_name->name); - if (!done) - break; - } - return done; -} - /** * tomoyo_write_aggregator_policy - Write "struct tomoyo_aggregator_entry" list. * @@ -623,36 +513,6 @@ static int tomoyo_update_alias_entry(const char *original_name, return error; } -/** - * tomoyo_read_alias_policy - Read "struct tomoyo_alias_entry" list. - * - * @head: Pointer to "struct tomoyo_io_buffer". - * - * Returns true on success, false otherwise. - * - * Caller holds tomoyo_read_lock(). - */ -bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head) -{ - struct list_head *pos; - bool done = true; - - list_for_each_cookie(pos, head->read_var2, - &tomoyo_policy_list[TOMOYO_ID_ALIAS]) { - struct tomoyo_alias_entry *ptr; - - ptr = list_entry(pos, struct tomoyo_alias_entry, head.list); - if (ptr->head.is_deleted) - continue; - done = tomoyo_io_printf(head, TOMOYO_KEYWORD_ALIAS "%s %s\n", - ptr->original_name->name, - ptr->aliased_name->name); - if (!done) - break; - } - return done; -} - /** * tomoyo_write_alias_policy - Write "struct tomoyo_alias_entry" list. * diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c index df3b203d7d4f..e7687ebdc5f6 100644 --- a/security/tomoyo/file.c +++ b/security/tomoyo/file.c @@ -344,36 +344,6 @@ int tomoyo_write_globally_readable_policy(char *data, const bool is_delete) return tomoyo_update_globally_readable_entry(data, is_delete); } -/** - * tomoyo_read_globally_readable_policy - Read "struct tomoyo_globally_readable_file_entry" list. - * - * @head: Pointer to "struct tomoyo_io_buffer". - * - * Returns true on success, false otherwise. - * - * Caller holds tomoyo_read_lock(). - */ -bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head) -{ - struct list_head *pos; - bool done = true; - - list_for_each_cookie(pos, head->read_var2, - &tomoyo_policy_list[TOMOYO_ID_GLOBALLY_READABLE]) { - struct tomoyo_globally_readable_file_entry *ptr; - ptr = list_entry(pos, - struct tomoyo_globally_readable_file_entry, - head.list); - if (ptr->head.is_deleted) - continue; - done = tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_READ "%s\n", - ptr->filename->name); - if (!done) - break; - } - return done; -} - static bool tomoyo_same_pattern(const struct tomoyo_acl_head *a, const struct tomoyo_acl_head *b) { @@ -457,34 +427,6 @@ int tomoyo_write_pattern_policy(char *data, const bool is_delete) return tomoyo_update_file_pattern_entry(data, is_delete); } -/** - * tomoyo_read_file_pattern - Read "struct tomoyo_pattern_entry" list. - * - * @head: Pointer to "struct tomoyo_io_buffer". - * - * Returns true on success, false otherwise. - * - * Caller holds tomoyo_read_lock(). - */ -bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head) -{ - struct list_head *pos; - bool done = true; - - list_for_each_cookie(pos, head->read_var2, - &tomoyo_policy_list[TOMOYO_ID_PATTERN]) { - struct tomoyo_pattern_entry *ptr; - ptr = list_entry(pos, struct tomoyo_pattern_entry, head.list); - if (ptr->head.is_deleted) - continue; - done = tomoyo_io_printf(head, TOMOYO_KEYWORD_FILE_PATTERN - "%s\n", ptr->pattern->name); - if (!done) - break; - } - return done; -} - static bool tomoyo_same_no_rewrite(const struct tomoyo_acl_head *a, const struct tomoyo_acl_head *b) { @@ -563,35 +505,6 @@ int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete) return tomoyo_update_no_rewrite_entry(data, is_delete); } -/** - * tomoyo_read_no_rewrite_policy - Read "struct tomoyo_no_rewrite_entry" list. - * - * @head: Pointer to "struct tomoyo_io_buffer". - * - * Returns true on success, false otherwise. - * - * Caller holds tomoyo_read_lock(). - */ -bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head) -{ - struct list_head *pos; - bool done = true; - - list_for_each_cookie(pos, head->read_var2, - &tomoyo_policy_list[TOMOYO_ID_NO_REWRITE]) { - struct tomoyo_no_rewrite_entry *ptr; - ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, - head.list); - if (ptr->head.is_deleted) - continue; - done = tomoyo_io_printf(head, TOMOYO_KEYWORD_DENY_REWRITE - "%s\n", ptr->pattern->name); - if (!done) - break; - } - return done; -} - static bool tomoyo_check_path_acl(const struct tomoyo_request_info *r, const struct tomoyo_acl_info *ptr) { diff --git a/security/tomoyo/number_group.c b/security/tomoyo/number_group.c index 99694153b947..5e75f5314bda 100644 --- a/security/tomoyo/number_group.c +++ b/security/tomoyo/number_group.c @@ -96,47 +96,6 @@ int tomoyo_write_number_group_policy(char *data, const bool is_delete) return error; } -/** - * tomoyo_read_number_group_policy - Read "struct tomoyo_number_group" list. - * - * @head: Pointer to "struct tomoyo_io_buffer". - * - * Returns true on success, false otherwise. - * - * Caller holds tomoyo_read_lock(). - */ -bool tomoyo_read_number_group_policy(struct tomoyo_io_buffer *head) -{ - struct list_head *gpos; - struct list_head *mpos; - list_for_each_cookie(gpos, head->read_var1, - &tomoyo_group_list[TOMOYO_NUMBER_GROUP]) { - struct tomoyo_group *group; - const char *name; - group = list_entry(gpos, struct tomoyo_group, list); - name = group->group_name->name; - list_for_each_cookie(mpos, head->read_var2, - &group->member_list) { - int pos; - const struct tomoyo_number_group *member - = list_entry(mpos, - struct tomoyo_number_group, - head.list); - if (member->head.is_deleted) - continue; - pos = head->read_avail; - if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_NUMBER_GROUP - "%s", name) || - !tomoyo_print_number_union(head, &member->number) || - !tomoyo_io_printf(head, "\n")) { - head->read_avail = pos; - return false; - } - } - } - return true; -} - /** * tomoyo_number_matches_group - Check whether the given number matches members of the given number group. * diff --git a/security/tomoyo/path_group.c b/security/tomoyo/path_group.c index 44e8a5b1ca67..2f9f9240bf5a 100644 --- a/security/tomoyo/path_group.c +++ b/security/tomoyo/path_group.c @@ -94,41 +94,6 @@ int tomoyo_write_path_group_policy(char *data, const bool is_delete) return error; } -/** - * tomoyo_read_path_group_policy - Read "struct tomoyo_path_group" list. - * - * @head: Pointer to "struct tomoyo_io_buffer". - * - * Returns true on success, false otherwise. - * - * Caller holds tomoyo_read_lock(). - */ -bool tomoyo_read_path_group_policy(struct tomoyo_io_buffer *head) -{ - struct list_head *gpos; - struct list_head *mpos; - list_for_each_cookie(gpos, head->read_var1, - &tomoyo_group_list[TOMOYO_PATH_GROUP]) { - struct tomoyo_group *group; - group = list_entry(gpos, struct tomoyo_group, list); - list_for_each_cookie(mpos, head->read_var2, - &group->member_list) { - struct tomoyo_path_group *member; - member = list_entry(mpos, - struct tomoyo_path_group, - head.list); - if (member->head.is_deleted) - continue; - if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_PATH_GROUP - "%s %s\n", - group->group_name->name, - member->member_name->name)) - return false; - } - } - return true; -} - /** * tomoyo_path_matches_group - Check whether the given pathname matches members of the given pathname group. *