diff options
author | Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> | 2010-05-17 01:06:58 (GMT) |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-08-02 05:33:35 (GMT) |
commit | 4c3e9e2ded48bcf696a45945ea7d25bb15b873fd (patch) | |
tree | 0be326f0f90b0279ae83594e9244c3739d348df1 /security/tomoyo/common.c | |
parent | babcd37821fba57048b30151969d28303f2a8b6b (diff) | |
download | linux-fsl-qoriq-4c3e9e2ded48bcf696a45945ea7d25bb15b873fd.tar.xz |
TOMOYO: Add numeric values grouping support.
This patch adds numeric values grouping support, which is useful for grouping
numeric values such as file's UID, DAC's mode, ioctl()'s cmd number.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/tomoyo/common.c')
-rw-r--r-- | security/tomoyo/common.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index b5dbdc9..d82c297 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c @@ -119,6 +119,159 @@ static bool tomoyo_print_name_union(struct tomoyo_io_buffer *head, } /** + * tomoyo_parse_ulong - Parse an "unsigned long" value. + * + * @result: Pointer to "unsigned long". + * @str: Pointer to string to parse. + * + * Returns value type on success, 0 otherwise. + * + * The @src is updated to point the first character after the value + * on success. + */ +u8 tomoyo_parse_ulong(unsigned long *result, char **str) +{ + const char *cp = *str; + char *ep; + int base = 10; + if (*cp == '0') { + char c = *(cp + 1); + if (c == 'x' || c == 'X') { + base = 16; + cp += 2; + } else if (c >= '0' && c <= '7') { + base = 8; + cp++; + } + } + *result = simple_strtoul(cp, &ep, base); + if (cp == ep) + return 0; + *str = ep; + switch (base) { + case 16: + return TOMOYO_VALUE_TYPE_HEXADECIMAL; + case 8: + return TOMOYO_VALUE_TYPE_OCTAL; + default: + return TOMOYO_VALUE_TYPE_DECIMAL; + } +} + +/** + * tomoyo_print_ulong - Print an "unsigned long" value. + * + * @buffer: Pointer to buffer. + * @buffer_len: Size of @buffer. + * @value: An "unsigned long" value. + * @type: Type of @value. + * + * Returns nothing. + */ +void tomoyo_print_ulong(char *buffer, const int buffer_len, + const unsigned long value, const u8 type) +{ + if (type == TOMOYO_VALUE_TYPE_DECIMAL) + snprintf(buffer, buffer_len, "%lu", value); + else if (type == TOMOYO_VALUE_TYPE_OCTAL) + snprintf(buffer, buffer_len, "0%lo", value); + else if (type == TOMOYO_VALUE_TYPE_HEXADECIMAL) + snprintf(buffer, buffer_len, "0x%lX", value); + else + snprintf(buffer, buffer_len, "type(%u)", type); +} + +/** + * tomoyo_print_number_union - Print a tomoyo_number_union. + * + * @head: Pointer to "struct tomoyo_io_buffer". + * @ptr: Pointer to "struct tomoyo_number_union". + * + * Returns true on success, false otherwise. + */ +bool tomoyo_print_number_union(struct tomoyo_io_buffer *head, + const struct tomoyo_number_union *ptr) +{ + unsigned long min; + unsigned long max; + u8 min_type; + u8 max_type; + if (!tomoyo_io_printf(head, " ")) + return false; + if (ptr->is_group) + return tomoyo_io_printf(head, "@%s", + ptr->group->group_name->name); + min_type = ptr->min_type; + max_type = ptr->max_type; + min = ptr->values[0]; + max = ptr->values[1]; + switch (min_type) { + case TOMOYO_VALUE_TYPE_HEXADECIMAL: + if (!tomoyo_io_printf(head, "0x%lX", min)) + return false; + break; + case TOMOYO_VALUE_TYPE_OCTAL: + if (!tomoyo_io_printf(head, "0%lo", min)) + return false; + break; + default: + if (!tomoyo_io_printf(head, "%lu", min)) + return false; + break; + } + if (min == max && min_type == max_type) + return true; + switch (max_type) { + case TOMOYO_VALUE_TYPE_HEXADECIMAL: + return tomoyo_io_printf(head, "-0x%lX", max); + case TOMOYO_VALUE_TYPE_OCTAL: + return tomoyo_io_printf(head, "-0%lo", max); + default: + return tomoyo_io_printf(head, "-%lu", max); + } +} + +/** + * tomoyo_parse_number_union - Parse a tomoyo_number_union. + * + * @data: Number or number range or number group. + * @ptr: Pointer to "struct tomoyo_number_union". + * + * Returns true on success, false otherwise. + */ +bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num) +{ + u8 type; + unsigned long v; + memset(num, 0, sizeof(*num)); + if (data[0] == '@') { + if (!tomoyo_is_correct_path(data, 0, 0, 0)) + return false; + num->group = tomoyo_get_number_group(data + 1); + num->is_group = true; + return num->group != NULL; + } + type = tomoyo_parse_ulong(&v, &data); + if (!type) + return false; + num->values[0] = v; + num->min_type = type; + if (!*data) { + num->values[1] = v; + num->max_type = type; + return true; + } + if (*data++ != '-') + return false; + type = tomoyo_parse_ulong(&v, &data); + if (!type || *data) + return false; + num->values[1] = v; + num->max_type = type; + return true; +} + +/** * tomoyo_is_byte_range - Check whether the string isa \ooo style octal value. * * @str: Pointer to the string. @@ -1750,6 +1903,8 @@ static int tomoyo_write_exception_policy(struct tomoyo_io_buffer *head) 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); + if (tomoyo_str_starts(&data, TOMOYO_KEYWORD_NUMBER_GROUP)) + return tomoyo_write_number_group_policy(data, is_delete); return -EINVAL; } @@ -1812,6 +1967,12 @@ static int tomoyo_read_exception_policy(struct tomoyo_io_buffer *head) 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; default: |