/** * tomoyo_read_token - Read a word from a line. * * @param: Pointer to "struct tomoyo_acl_param". * * Returns a word on success, "" otherwise. * * To allow the caller to skip NULL check, this function returns "" rather than * NULL if there is no more words to read.
*/ char *tomoyo_read_token(struct tomoyo_acl_param *param)
{ char *pos = param->data; char *del = strchr(pos, ' ');
if (del)
*del++ = '\0'; else
del = pos + strlen(pos);
param->data = del; return pos;
}
/** * tomoyo_parse_ulong - Parse an "unsigned long" value. * * @result: Pointer to "unsigned long". * @str: Pointer to string to parse. * * Returns one of values in "enum tomoyo_value_type". * * The @src is updated to point the first character after the value * on success.
*/
u8 tomoyo_parse_ulong(unsignedlong *result, char **str)
{ constchar *cp = *str; char *ep; int base = 10;
if (*cp == '0') { char c = *(cp + 1);
if (c == 'x' || c == 'X') {
base = 16;
cp += 2;
} elseif (c >= '0' && c <= '7') {
base = 8;
cp++;
}
}
*result = simple_strtoul(cp, &ep, base); if (cp == ep) return TOMOYO_VALUE_TYPE_INVALID;
*str = ep; switch (base) { case 16: return TOMOYO_VALUE_TYPE_HEXADECIMAL; case 8: return TOMOYO_VALUE_TYPE_OCTAL; default: return TOMOYO_VALUE_TYPE_DECIMAL;
}
}
memset(ptr, 0, sizeof(*ptr)); if (param->data[0] == '@') {
param->data++;
ptr->group = tomoyo_get_group(param, TOMOYO_NUMBER_GROUP); return ptr->group != NULL;
}
data = tomoyo_read_token(param);
type = tomoyo_parse_ulong(&v, &data); if (type == TOMOYO_VALUE_TYPE_INVALID) returnfalse;
ptr->values[0] = v;
ptr->value_type[0] = type; if (!*data) {
ptr->values[1] = v;
ptr->value_type[1] = type; returntrue;
} if (*data++ != '-') returnfalse;
type = tomoyo_parse_ulong(&v, &data); if (type == TOMOYO_VALUE_TYPE_INVALID || *data || ptr->values[0] > v) returnfalse;
ptr->values[1] = v;
ptr->value_type[1] = type; returntrue;
}
/** * tomoyo_byte_range - Check whether the string is a \ooo style octal value. * * @str: Pointer to the string. * * Returns true if @str is a \ooo style octal value, false otherwise. * * TOMOYO uses \ooo style representation for 0x01 - 0x20 and 0x7F - 0xFF. * This function verifies that \ooo is in valid range.
*/ staticinlinebool tomoyo_byte_range(constchar *str)
{ return *str >= '0' && *str++ <= '3' &&
*str >= '0' && *str++ <= '7' &&
*str >= '0' && *str <= '7';
}
/** * tomoyo_alphabet_char - Check whether the character is an alphabet. * * @c: The character to check. * * Returns true if @c is an alphabet character, false otherwise.
*/ staticinlinebool tomoyo_alphabet_char(constchar c)
{ return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}
/** * tomoyo_make_byte - Make byte value from three octal characters. * * @c1: The first character. * @c2: The second character. * @c3: The third character. * * Returns byte value.
*/ staticinline u8 tomoyo_make_byte(const u8 c1, const u8 c2, const u8 c3)
{ return ((c1 - '0') << 6) + ((c2 - '0') << 3) + (c3 - '0');
}
/** * tomoyo_valid - Check whether the character is a valid char. * * @c: The character to check. * * Returns true if @c is a valid character, false otherwise.
*/ staticinlinebool tomoyo_valid(constunsignedchar c)
{ return c > ' ' && c < 127;
}
/** * tomoyo_invalid - Check whether the character is an invalid char. * * @c: The character to check. * * Returns true if @c is an invalid character, false otherwise.
*/ staticinlinebool tomoyo_invalid(constunsignedchar c)
{ return c && (c <= ' ' || c >= 127);
}
/** * tomoyo_str_starts - Check whether the given string starts with the given keyword. * * @src: Pointer to pointer to the string. * @find: Pointer to the keyword. * * Returns true if @src starts with @find, false otherwise. * * The @src is updated to point the first character after the @find * if @src starts with @find.
*/ bool tomoyo_str_starts(char **src, constchar *find)
{ constint len = strlen(find); char *tmp = *src;
/** * tomoyo_normalize_line - Format string. * * @buffer: The line to normalize. * * Leading and trailing whitespaces are removed. * Multiple whitespaces are packed into single space. * * Returns nothing.
*/ void tomoyo_normalize_line(unsignedchar *buffer)
{ unsignedchar *sp = buffer; unsignedchar *dp = buffer; bool first = true;
while (tomoyo_invalid(*sp))
sp++; while (*sp) { if (!first)
*dp++ = ' ';
first = false; while (tomoyo_valid(*sp))
*dp++ = *sp++; while (tomoyo_invalid(*sp))
sp++;
}
*dp = '\0';
}
/** * tomoyo_correct_word2 - Validate a string. * * @string: The string to check. Maybe non-'\0'-terminated. * @len: Length of @string. * * Check whether the given string follows the naming rules. * Returns true if @string follows the naming rules, false otherwise.
*/ staticbool tomoyo_correct_word2(constchar *string, size_t len)
{
u8 recursion = 20; constchar *const start = string; bool in_repetition = false;
if (!len) goto out; while (len--) { unsignedchar c = *string++;
if (c == '\\') { if (!len--) goto out;
c = *string++; if (c >= '0' && c <= '3') { unsignedchar d; unsignedchar e;
/** * tomoyo_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_correct_path(constchar *filename)
{ return tomoyo_correct_path2(filename, strlen(filename));
}
/** * tomoyo_correct_domain - Check whether the given domainname follows the naming rules. * * @domainname: The domainname to check. * * Returns true if @domainname follows the naming rules, false otherwise.
*/ bool tomoyo_correct_domain(constunsignedchar *domainname)
{ if (!domainname || !tomoyo_domain_def(domainname)) returnfalse;
domainname = strchr(domainname, ' '); if (!domainname++) returntrue; while (1) { constunsignedchar *cp = strchr(domainname, ' ');
if (!cp) break; if (!tomoyo_correct_path2(domainname, cp - domainname)) returnfalse;
domainname = cp + 1;
} return tomoyo_correct_path(domainname);
}
/** * tomoyo_domain_def - Check whether the given token can be a domainname. * * @buffer: The token to check. * * Returns true if @buffer possibly be a domainname, false otherwise.
*/ bool tomoyo_domain_def(constunsignedchar *buffer)
{ constunsignedchar *cp; int len;
if (*buffer != '<') returnfalse;
cp = strchr(buffer, ' '); if (!cp)
len = strlen(buffer); else
len = cp - buffer; if (buffer[len - 1] != '>' ||
!tomoyo_correct_word2(buffer + 1, len - 2)) returnfalse; returntrue;
}
/** * tomoyo_find_domain - Find a domain by the given name. * * @domainname: The domainname to find. * * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise. * * Caller holds tomoyo_read_lock().
*/ struct tomoyo_domain_info *tomoyo_find_domain(constchar *domainname)
{ struct tomoyo_domain_info *domain; struct tomoyo_path_info name;
/** * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token. * * @filename: The string to evaluate. * * Returns the initial length without a pattern in @filename.
*/ staticint tomoyo_const_part_length(constchar *filename)
{ char c; int len = 0;
if (!filename) return 0; while ((c = *filename++) != '\0') { if (c != '\\') {
len++; continue;
}
c = *filename++; switch (c) { case'\\': /* "\\" */
len += 2; continue; case'0': /* "\ooo" */ case'1': case'2': case'3':
c = *filename++; if (c < '0' || c > '7') break;
c = *filename++; if (c < '0' || c > '7') break;
len += 4; continue;
} break;
} return len;
}
/** * tomoyo_fill_path_info - Fill in "struct tomoyo_path_info" members. * * @ptr: Pointer to "struct tomoyo_path_info" to fill in. * * The caller sets "struct tomoyo_path_info"->name.
*/ void tomoyo_fill_path_info(struct tomoyo_path_info *ptr)
{ constchar *name = ptr->name; constint len = strlen(name);
/** * tomoyo_file_matches_pattern2 - Pattern matching without '/' character and "\-" pattern. * * @filename: The start of string to check. * @filename_end: The end of string to check. * @pattern: The start of pattern to compare. * @pattern_end: The end of pattern to compare. * * Returns true if @filename matches @pattern, false otherwise.
*/ staticbool tomoyo_file_matches_pattern2(constchar *filename, constchar *filename_end, constchar *pattern, constchar *pattern_end)
{ while (filename < filename_end && pattern < pattern_end) { char c; int i; int j;
if (*pattern != '\\') { if (*filename++ != *pattern++) returnfalse; continue;
}
c = *filename;
pattern++; switch (*pattern) { case'?': if (c == '/') { returnfalse;
} elseif (c == '\\') { if (filename[1] == '\\')
filename++; elseif (tomoyo_byte_range(filename + 1))
filename += 3; else returnfalse;
} break; case'\\': if (c != '\\') returnfalse; if (*++filename != '\\') returnfalse; break; case'+': if (!isdigit(c)) returnfalse; break; case'x': if (!isxdigit(c)) returnfalse; break; case'a': if (!tomoyo_alphabet_char(c)) returnfalse; break; case'0': case'1': case'2': case'3': if (c == '\\' && tomoyo_byte_range(filename + 1)
&& strncmp(filename + 1, pattern, 3) == 0) {
filename += 3;
pattern += 2; break;
} returnfalse; /* Not matched. */ case'*': case'@': for (i = 0; i <= filename_end - filename; i++) { if (tomoyo_file_matches_pattern2(
filename + i, filename_end,
pattern + 1, pattern_end)) returntrue;
c = filename[i]; if (c == '.' && *pattern == '@') break; if (c != '\\') continue; if (filename[i + 1] == '\\')
i++; elseif (tomoyo_byte_range(filename + i + 1))
i += 3; else break; /* Bad pattern. */
} returnfalse; /* Not matched. */ default:
j = 0;
c = *pattern; if (c == '$') { while (isdigit(filename[j]))
j++;
} elseif (c == 'X') { while (isxdigit(filename[j]))
j++;
} elseif (c == 'A') { while (tomoyo_alphabet_char(filename[j]))
j++;
} for (i = 1; i <= j; i++) { if (tomoyo_file_matches_pattern2(
filename + i, filename_end,
pattern + 1, pattern_end)) returntrue;
} returnfalse; /* Not matched or bad pattern. */
}
filename++;
pattern++;
} while (*pattern == '\\' &&
(*(pattern + 1) == '*' || *(pattern + 1) == '@'))
pattern += 2; return filename == filename_end && pattern == pattern_end;
}
/** * tomoyo_file_matches_pattern - Pattern matching without '/' character. * * @filename: The start of string to check. * @filename_end: The end of string to check. * @pattern: The start of pattern to compare. * @pattern_end: The end of pattern to compare. * * Returns true if @filename matches @pattern, false otherwise.
*/ staticbool tomoyo_file_matches_pattern(constchar *filename, constchar *filename_end, constchar *pattern, constchar *pattern_end)
{ constchar *pattern_start = pattern; bool first = true; bool result;
while (pattern < pattern_end - 1) { /* Split at "\-" pattern. */ if (*pattern++ != '\\' || *pattern++ != '-') continue;
result = tomoyo_file_matches_pattern2(filename,
filename_end,
pattern_start,
pattern - 2); if (first)
result = !result; if (result) returnfalse;
first = false;
pattern_start = pattern;
}
result = tomoyo_file_matches_pattern2(filename, filename_end,
pattern_start, pattern_end); return first ? result : !result;
}
/** * tomoyo_path_matches_pattern2 - Do pathname pattern matching. * * @f: The start of string to check. * @p: The start of pattern to compare. * * Returns true if @f matches @p, false otherwise.
*/ staticbool tomoyo_path_matches_pattern2(constchar *f, constchar *p)
{ constchar *f_delimiter; constchar *p_delimiter;
while (*f && *p) {
f_delimiter = strchr(f, '/'); if (!f_delimiter)
f_delimiter = f + strlen(f);
p_delimiter = strchr(p, '/'); if (!p_delimiter)
p_delimiter = p + strlen(p); if (*p == '\\' && *(p + 1) == '{') goto recursive; if (!tomoyo_file_matches_pattern(f, f_delimiter, p,
p_delimiter)) returnfalse;
f = f_delimiter; if (*f)
f++;
p = p_delimiter; if (*p)
p++;
} /* Ignore trailing "\*" and "\@" in @pattern. */ while (*p == '\\' &&
(*(p + 1) == '*' || *(p + 1) == '@'))
p += 2; return !*f && !*p;
recursive: /* * The "\{" pattern is permitted only after '/' character. * This guarantees that below "*(p - 1)" is safe. * Also, the "\}" pattern is permitted only before '/' character * so that "\{" + "\}" pair will not break the "\-" operator.
*/ if (*(p - 1) != '/' || p_delimiter <= p + 3 || *p_delimiter != '/' ||
*(p_delimiter - 1) != '}' || *(p_delimiter - 2) != '\\') returnfalse; /* Bad pattern. */ do { /* Compare current component with pattern. */ if (!tomoyo_file_matches_pattern(f, f_delimiter, p + 2,
p_delimiter - 2)) break; /* Proceed to next component. */
f = f_delimiter; if (!*f) break;
f++; /* Continue comparison. */ if (tomoyo_path_matches_pattern2(f, p_delimiter + 1)) returntrue;
f_delimiter = strchr(f, '/');
} while (f_delimiter); returnfalse; /* Not matched. */
}
/** * tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern. * * @filename: The filename to check. * @pattern: The pattern to compare. * * Returns true if matches, false otherwise. * * The following patterns are available. * \\ \ itself. * \ooo Octal representation of a byte. * \* Zero or more repetitions of characters other than '/'. * \@ Zero or more repetitions of characters other than '/' or '.'. * \? 1 byte character other than '/'. * \$ One or more repetitions of decimal digits. * \+ 1 decimal digit. * \X One or more repetitions of hexadecimal digits. * \x 1 hexadecimal digit. * \A One or more repetitions of alphabet characters. * \a 1 alphabet character. * * \- Subtraction operator. * * /\{dir\}/ '/' + 'One or more repetitions of dir/' (e.g. /dir/ /dir/dir/ * /dir/dir/dir/ ).
*/ bool tomoyo_path_matches_pattern(conststruct tomoyo_path_info *filename, conststruct tomoyo_path_info *pattern)
{ constchar *f = filename->name; constchar *p = pattern->name; constint len = pattern->const_len;
/* If @pattern doesn't contain pattern, I can use strcmp(). */ if (!pattern->is_patterned) return !tomoyo_pathcmp(filename, pattern); /* Don't compare directory and non-directory. */ if (filename->is_dir != pattern->is_dir) returnfalse; /* Compare the initial length without patterns. */ if (strncmp(f, p, len)) returnfalse;
f += len;
p += len; return tomoyo_path_matches_pattern2(f, p);
}
/** * tomoyo_get_exe - Get tomoyo_realpath() of current process. * * Returns the tomoyo_realpath() of current process on success, NULL otherwise. * * This function uses kzalloc(), so the caller must call kfree() * if this function didn't return NULL.
*/ constchar *tomoyo_get_exe(void)
{ struct file *exe_file; constchar *cp; struct mm_struct *mm = current->mm;
if (!mm) return NULL;
exe_file = get_mm_exe_file(mm); if (!exe_file) return NULL;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.