summaryrefslogtreecommitdiff
path: root/security/tomoyo/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/tomoyo/util.c')
-rw-r--r--security/tomoyo/util.c154
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;
}