diff options
Diffstat (limited to 'security/tomoyo/util.c')
-rw-r--r-- | security/tomoyo/util.c | 154 |
1 files changed, 59 insertions, 95 deletions
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c index 7b023f5e1314..592b76a2bce8 100644 --- a/security/tomoyo/util.c +++ b/security/tomoyo/util.c @@ -89,7 +89,7 @@ void tomoyo_print_ulong(char *buffer, const int buffer_len, bool tomoyo_parse_name_union(const char *filename, struct tomoyo_name_union *ptr) { - if (!tomoyo_is_correct_path(filename, 0, 0, 0)) + if (!tomoyo_is_correct_word(filename)) return false; if (filename[0] == '@') { ptr->group = tomoyo_get_path_group(filename + 1); @@ -115,7 +115,7 @@ bool tomoyo_parse_number_union(char *data, struct tomoyo_number_union *num) unsigned long v; memset(num, 0, sizeof(*num)); if (data[0] == '@') { - if (!tomoyo_is_correct_path(data, 0, 0, 0)) + if (!tomoyo_is_correct_word(data)) return false; num->group = tomoyo_get_number_group(data + 1); num->is_group = true; @@ -265,54 +265,29 @@ bool tomoyo_tokenize(char *buffer, char *w[], size_t size) } /** - * tomoyo_is_correct_path - Validate a pathname. + * tomoyo_is_correct_word2 - Validate a string. * - * @filename: The pathname to check. - * @start_type: Should the pathname start with '/'? - * 1 = must / -1 = must not / 0 = don't care - * @pattern_type: Can the pathname contain a wildcard? - * 1 = must / -1 = must not / 0 = don't care - * @end_type: Should the pathname end with '/'? - * 1 = must / -1 = must not / 0 = don't care + * @string: The string to check. May be non-'\0'-terminated. + * @len: Length of @string. * - * Check whether the given filename follows the naming rules. - * Returns true if @filename follows the naming rules, false otherwise. + * Check whether the given string follows the naming rules. + * Returns true if @string follows the naming rules, false otherwise. */ -bool tomoyo_is_correct_path(const char *filename, const s8 start_type, - const s8 pattern_type, const s8 end_type) +static bool tomoyo_is_correct_word2(const char *string, size_t len) { - const char *const start = filename; + const char *const start = string; bool in_repetition = false; - bool contains_pattern = false; unsigned char c; unsigned char d; unsigned char e; - - if (!filename) + if (!len) goto out; - c = *filename; - if (start_type == 1) { /* Must start with '/' */ - if (c != '/') - goto out; - } else if (start_type == -1) { /* Must not start with '/' */ - if (c == '/') - goto out; - } - if (c) - c = *(filename + strlen(filename) - 1); - if (end_type == 1) { /* Must end with '/' */ - if (c != '/') - goto out; - } else if (end_type == -1) { /* Must not end with '/' */ - if (c == '/') - goto out; - } - while (1) { - c = *filename++; - if (!c) - break; + while (len--) { + c = *string++; if (c == '\\') { - c = *filename++; + if (!len--) + goto out; + c = *string++; switch (c) { case '\\': /* "\\" */ continue; @@ -326,21 +301,14 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type, case 'a': /* "\a" */ case 'A': /* "\A" */ case '-': /* "\-" */ - if (pattern_type == -1) - break; /* Must not contain pattern */ - contains_pattern = true; continue; case '{': /* "/\{" */ - if (filename - 3 < start || - *(filename - 3) != '/') + if (string - 3 < start || *(string - 3) != '/') break; - if (pattern_type == -1) - break; /* Must not contain pattern */ - contains_pattern = true; in_repetition = true; continue; case '}': /* "\}/" */ - if (*filename != '/') + if (*string != '/') break; if (!in_repetition) break; @@ -350,11 +318,11 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type, case '1': case '2': case '3': - d = *filename++; - if (d < '0' || d > '7') + if (!len-- || !len--) break; - e = *filename++; - if (e < '0' || e > '7') + d = *string++; + e = *string++; + if (d < '0' || d > '7' || e < '0' || e > '7') break; c = tomoyo_make_byte(c, d, e); if (tomoyo_is_invalid(c)) @@ -367,10 +335,6 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type, goto out; } } - if (pattern_type == 1) { /* Must contain pattern */ - if (!contains_pattern) - goto out; - } if (in_repetition) goto out; return true; @@ -379,58 +343,58 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type, } /** + * tomoyo_is_correct_word - Validate a string. + * + * @string: The string to check. + * + * Check whether the given string follows the naming rules. + * Returns true if @string follows the naming rules, false otherwise. + */ +bool tomoyo_is_correct_word(const char *string) +{ + return tomoyo_is_correct_word2(string, strlen(string)); +} + +/** + * tomoyo_is_correct_path - Validate a pathname. + * + * @filename: The pathname to check. + * + * Check whether the given pathname follows the naming rules. + * Returns true if @filename follows the naming rules, false otherwise. + */ +bool tomoyo_is_correct_path(const char *filename) +{ + return *filename == '/' && tomoyo_is_correct_word(filename); +} + +/** * tomoyo_is_correct_domain - Check whether the given domainname follows the naming rules. * - * @domainname: The domainname to check. + * @domainname: The domainname to check. * * Returns true if @domainname follows the naming rules, false otherwise. */ bool tomoyo_is_correct_domain(const unsigned char *domainname) { - unsigned char c; - unsigned char d; - unsigned char e; - if (!domainname || strncmp(domainname, TOMOYO_ROOT_NAME, TOMOYO_ROOT_NAME_LEN)) goto out; domainname += TOMOYO_ROOT_NAME_LEN; if (!*domainname) return true; - do { - if (*domainname++ != ' ') - goto out; - if (*domainname++ != '/') + if (*domainname++ != ' ') + goto out; + while (1) { + const unsigned char *cp = strchr(domainname, ' '); + if (!cp) + break; + if (*domainname != '/' || + !tomoyo_is_correct_word2(domainname, cp - domainname - 1)) goto out; - while ((c = *domainname) != '\0' && c != ' ') { - domainname++; - if (c == '\\') { - c = *domainname++; - switch ((c)) { - case '\\': /* "\\" */ - continue; - case '0': /* "\ooo" */ - case '1': - case '2': - case '3': - d = *domainname++; - if (d < '0' || d > '7') - break; - e = *domainname++; - if (e < '0' || e > '7') - break; - c = tomoyo_make_byte(c, d, e); - if (tomoyo_is_invalid(c)) - /* pattern is not \000 */ - continue; - } - goto out; - } else if (tomoyo_is_invalid(c)) { - goto out; - } - } - } while (*domainname); - return true; + domainname = cp + 1; + } + return tomoyo_is_correct_path(domainname); out: return false; } |