Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * security/tomoyo/util.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (C) 2005-2011  NTT DATA CORPORATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) /* Lock for protecting policy. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) DEFINE_MUTEX(tomoyo_policy_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) /* Has /sbin/init started? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) bool tomoyo_policy_loaded;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20)  * Mapping table from "enum tomoyo_mac_index" to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21)  * "enum tomoyo_mac_category_index".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 	/* CONFIG::file group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 	[TOMOYO_MAC_FILE_EXECUTE]    = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) 	[TOMOYO_MAC_FILE_OPEN]       = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 	[TOMOYO_MAC_FILE_CREATE]     = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 	[TOMOYO_MAC_FILE_UNLINK]     = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 	[TOMOYO_MAC_FILE_GETATTR]    = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 	[TOMOYO_MAC_FILE_MKDIR]      = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 	[TOMOYO_MAC_FILE_RMDIR]      = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 	[TOMOYO_MAC_FILE_MKFIFO]     = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 	[TOMOYO_MAC_FILE_MKSOCK]     = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 	[TOMOYO_MAC_FILE_TRUNCATE]   = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 	[TOMOYO_MAC_FILE_SYMLINK]    = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 	[TOMOYO_MAC_FILE_MKBLOCK]    = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	[TOMOYO_MAC_FILE_MKCHAR]     = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	[TOMOYO_MAC_FILE_LINK]       = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	[TOMOYO_MAC_FILE_RENAME]     = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	[TOMOYO_MAC_FILE_CHMOD]      = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	[TOMOYO_MAC_FILE_CHOWN]      = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	[TOMOYO_MAC_FILE_CHGRP]      = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	[TOMOYO_MAC_FILE_IOCTL]      = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	[TOMOYO_MAC_FILE_CHROOT]     = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	[TOMOYO_MAC_FILE_MOUNT]      = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	[TOMOYO_MAC_FILE_UMOUNT]     = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	[TOMOYO_MAC_FILE_PIVOT_ROOT] = TOMOYO_MAC_CATEGORY_FILE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 	/* CONFIG::network group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	[TOMOYO_MAC_NETWORK_INET_STREAM_BIND]       =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	TOMOYO_MAC_CATEGORY_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	[TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN]     =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	TOMOYO_MAC_CATEGORY_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	[TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT]    =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	TOMOYO_MAC_CATEGORY_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	[TOMOYO_MAC_NETWORK_INET_DGRAM_BIND]        =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	TOMOYO_MAC_CATEGORY_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	[TOMOYO_MAC_NETWORK_INET_DGRAM_SEND]        =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	TOMOYO_MAC_CATEGORY_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	[TOMOYO_MAC_NETWORK_INET_RAW_BIND]          =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	TOMOYO_MAC_CATEGORY_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	[TOMOYO_MAC_NETWORK_INET_RAW_SEND]          =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	TOMOYO_MAC_CATEGORY_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	[TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND]       =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	TOMOYO_MAC_CATEGORY_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	[TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN]     =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	TOMOYO_MAC_CATEGORY_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 	[TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT]    =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	TOMOYO_MAC_CATEGORY_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	[TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND]        =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	TOMOYO_MAC_CATEGORY_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	[TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND]        =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	TOMOYO_MAC_CATEGORY_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	[TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND]    =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 	TOMOYO_MAC_CATEGORY_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	[TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN]  =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	TOMOYO_MAC_CATEGORY_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	[TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	TOMOYO_MAC_CATEGORY_NETWORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	/* CONFIG::misc group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	[TOMOYO_MAC_ENVIRON]         = TOMOYO_MAC_CATEGORY_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84)  * tomoyo_convert_time - Convert time_t to YYYY/MM/DD hh/mm/ss.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86)  * @time:  Seconds since 1970/01/01 00:00:00.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87)  * @stamp: Pointer to "struct tomoyo_time".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89)  * Returns nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) void tomoyo_convert_time(time64_t time64, struct tomoyo_time *stamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	struct tm tm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	time64_to_tm(time64, 0, &tm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	stamp->sec = tm.tm_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	stamp->min = tm.tm_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	stamp->hour = tm.tm_hour;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	stamp->day = tm.tm_mday;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	stamp->month = tm.tm_mon + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	stamp->year = tm.tm_year + 1900;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105)  * tomoyo_permstr - Find permission keywords.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)  * @string: String representation for permissions in foo/bar/buz format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108)  * @keyword: Keyword to find from @string/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110)  * Returns true if @keyword was found in @string, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112)  * This function assumes that strncmp(w1, w2, strlen(w1)) != 0 if w1 != w2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) bool tomoyo_permstr(const char *string, const char *keyword)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	const char *cp = strstr(string, keyword);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	if (cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 		return cp == string || *(cp - 1) == '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124)  * tomoyo_read_token - Read a word from a line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126)  * @param: Pointer to "struct tomoyo_acl_param".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128)  * Returns a word on success, "" otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130)  * To allow the caller to skip NULL check, this function returns "" rather than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131)  * NULL if there is no more words to read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) char *tomoyo_read_token(struct tomoyo_acl_param *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	char *pos = param->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	char *del = strchr(pos, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	if (del)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 		*del++ = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 		del = pos + strlen(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	param->data = del;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) static bool tomoyo_correct_path2(const char *filename, const size_t len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149)  * tomoyo_get_domainname - Read a domainname from a line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151)  * @param: Pointer to "struct tomoyo_acl_param".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153)  * Returns a domainname on success, NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) const struct tomoyo_path_info *tomoyo_get_domainname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) (struct tomoyo_acl_param *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	char *start = param->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	char *pos = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	while (*pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		if (*pos++ != ' ' ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 		    tomoyo_correct_path2(pos, strchrnul(pos, ' ') - pos))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 		*(pos - 1) = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	param->data = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	if (tomoyo_correct_domain(start))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 		return tomoyo_get_name(start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175)  * tomoyo_parse_ulong - Parse an "unsigned long" value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177)  * @result: Pointer to "unsigned long".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178)  * @str:    Pointer to string to parse.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180)  * Returns one of values in "enum tomoyo_value_type".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182)  * The @src is updated to point the first character after the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183)  * on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) u8 tomoyo_parse_ulong(unsigned long *result, char **str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	const char *cp = *str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	char *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	int base = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	if (*cp == '0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		char c = *(cp + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		if (c == 'x' || c == 'X') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 			base = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 			cp += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		} else if (c >= '0' && c <= '7') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 			base = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 			cp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	*result = simple_strtoul(cp, &ep, base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	if (cp == ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 		return TOMOYO_VALUE_TYPE_INVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	*str = ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	switch (base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 		return TOMOYO_VALUE_TYPE_HEXADECIMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		return TOMOYO_VALUE_TYPE_OCTAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 		return TOMOYO_VALUE_TYPE_DECIMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217)  * tomoyo_print_ulong - Print an "unsigned long" value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219)  * @buffer:     Pointer to buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220)  * @buffer_len: Size of @buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221)  * @value:      An "unsigned long" value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222)  * @type:       Type of @value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224)  * Returns nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) void tomoyo_print_ulong(char *buffer, const int buffer_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 			const unsigned long value, const u8 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	if (type == TOMOYO_VALUE_TYPE_DECIMAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		snprintf(buffer, buffer_len, "%lu", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	else if (type == TOMOYO_VALUE_TYPE_OCTAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		snprintf(buffer, buffer_len, "0%lo", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	else if (type == TOMOYO_VALUE_TYPE_HEXADECIMAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		snprintf(buffer, buffer_len, "0x%lX", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		snprintf(buffer, buffer_len, "type(%u)", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240)  * tomoyo_parse_name_union - Parse a tomoyo_name_union.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242)  * @param: Pointer to "struct tomoyo_acl_param".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243)  * @ptr:   Pointer to "struct tomoyo_name_union".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245)  * Returns true on success, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) bool tomoyo_parse_name_union(struct tomoyo_acl_param *param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 			     struct tomoyo_name_union *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	char *filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	if (param->data[0] == '@') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		param->data++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		ptr->group = tomoyo_get_group(param, TOMOYO_PATH_GROUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		return ptr->group != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	filename = tomoyo_read_token(param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	if (!tomoyo_correct_word(filename))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	ptr->filename = tomoyo_get_name(filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	return ptr->filename != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265)  * tomoyo_parse_number_union - Parse a tomoyo_number_union.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267)  * @param: Pointer to "struct tomoyo_acl_param".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268)  * @ptr:   Pointer to "struct tomoyo_number_union".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270)  * Returns true on success, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) bool tomoyo_parse_number_union(struct tomoyo_acl_param *param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 			       struct tomoyo_number_union *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	unsigned long v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	memset(ptr, 0, sizeof(*ptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	if (param->data[0] == '@') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		param->data++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 		ptr->group = tomoyo_get_group(param, TOMOYO_NUMBER_GROUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 		return ptr->group != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	data = tomoyo_read_token(param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	type = tomoyo_parse_ulong(&v, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	if (type == TOMOYO_VALUE_TYPE_INVALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	ptr->values[0] = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	ptr->value_type[0] = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	if (!*data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		ptr->values[1] = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 		ptr->value_type[1] = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	if (*data++ != '-')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	type = tomoyo_parse_ulong(&v, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	if (type == TOMOYO_VALUE_TYPE_INVALID || *data || ptr->values[0] > v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	ptr->values[1] = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	ptr->value_type[1] = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307)  * tomoyo_byte_range - Check whether the string is a \ooo style octal value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309)  * @str: Pointer to the string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311)  * Returns true if @str is a \ooo style octal value, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313)  * TOMOYO uses \ooo style representation for 0x01 - 0x20 and 0x7F - 0xFF.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314)  * This function verifies that \ooo is in valid range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) static inline bool tomoyo_byte_range(const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	return *str >= '0' && *str++ <= '3' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		*str >= '0' && *str++ <= '7' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		*str >= '0' && *str <= '7';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324)  * tomoyo_alphabet_char - Check whether the character is an alphabet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326)  * @c: The character to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328)  * Returns true if @c is an alphabet character, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) static inline bool tomoyo_alphabet_char(const char c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336)  * tomoyo_make_byte - Make byte value from three octal characters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338)  * @c1: The first character.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339)  * @c2: The second character.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340)  * @c3: The third character.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342)  * Returns byte value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) static inline u8 tomoyo_make_byte(const u8 c1, const u8 c2, const u8 c3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	return ((c1 - '0') << 6) + ((c2 - '0') << 3) + (c3 - '0');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350)  * tomoyo_valid - Check whether the character is a valid char.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352)  * @c: The character to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354)  * Returns true if @c is a valid character, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) static inline bool tomoyo_valid(const unsigned char c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	return c > ' ' && c < 127;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362)  * tomoyo_invalid - Check whether the character is an invalid char.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364)  * @c: The character to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366)  * Returns true if @c is an invalid character, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) static inline bool tomoyo_invalid(const unsigned char c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	return c && (c <= ' ' || c >= 127);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374)  * tomoyo_str_starts - Check whether the given string starts with the given keyword.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376)  * @src:  Pointer to pointer to the string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377)  * @find: Pointer to the keyword.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379)  * Returns true if @src starts with @find, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381)  * The @src is updated to point the first character after the @find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382)  * if @src starts with @find.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) bool tomoyo_str_starts(char **src, const char *find)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	const int len = strlen(find);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	char *tmp = *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	if (strncmp(tmp, find, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	tmp += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	*src = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397)  * tomoyo_normalize_line - Format string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399)  * @buffer: The line to normalize.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401)  * Leading and trailing whitespaces are removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402)  * Multiple whitespaces are packed into single space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404)  * Returns nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) void tomoyo_normalize_line(unsigned char *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	unsigned char *sp = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	unsigned char *dp = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	bool first = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	while (tomoyo_invalid(*sp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 		sp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	while (*sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		if (!first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 			*dp++ = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 		first = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		while (tomoyo_valid(*sp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 			*dp++ = *sp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		while (tomoyo_invalid(*sp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 			sp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	*dp = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427)  * tomoyo_correct_word2 - Validate a string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429)  * @string: The string to check. Maybe non-'\0'-terminated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430)  * @len:    Length of @string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432)  * Check whether the given string follows the naming rules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433)  * Returns true if @string follows the naming rules, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) static bool tomoyo_correct_word2(const char *string, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	const char *const start = string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	bool in_repetition = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	unsigned char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	unsigned char d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	unsigned char e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	while (len--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		c = *string++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		if (c == '\\') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 			if (!len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 			c = *string++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 			switch (c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 			case '\\':  /* "\\" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 			case '$':   /* "\$" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 			case '+':   /* "\+" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 			case '?':   /* "\?" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 			case '*':   /* "\*" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 			case '@':   /* "\@" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 			case 'x':   /* "\x" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 			case 'X':   /* "\X" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 			case 'a':   /* "\a" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 			case 'A':   /* "\A" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 			case '-':   /* "\-" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 			case '{':   /* "/\{" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 				if (string - 3 < start || *(string - 3) != '/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 				in_repetition = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 			case '}':   /* "\}/" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 				if (*string != '/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 				if (!in_repetition)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 				in_repetition = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 			case '0':   /* "\ooo" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 			case '1':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 			case '2':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 			case '3':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 				if (!len-- || !len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 				d = *string++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 				e = *string++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 				if (d < '0' || d > '7' || e < '0' || e > '7')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 				c = tomoyo_make_byte(c, d, e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 				if (c <= ' ' || c >= 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		} else if (in_repetition && c == '/') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 		} else if (c <= ' ' || c >= 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	if (in_repetition)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506)  * tomoyo_correct_word - Validate a string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508)  * @string: The string to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510)  * Check whether the given string follows the naming rules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511)  * Returns true if @string follows the naming rules, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) bool tomoyo_correct_word(const char *string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	return tomoyo_correct_word2(string, strlen(string));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519)  * tomoyo_correct_path2 - Check whether the given pathname follows the naming rules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521)  * @filename: The pathname to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522)  * @len:      Length of @filename.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524)  * Returns true if @filename follows the naming rules, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) static bool tomoyo_correct_path2(const char *filename, const size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	const char *cp1 = memchr(filename, '/', len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	const char *cp2 = memchr(filename, '.', len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	return cp1 && (!cp2 || (cp1 < cp2)) && tomoyo_correct_word2(filename, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535)  * tomoyo_correct_path - Validate a pathname.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537)  * @filename: The pathname to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539)  * Check whether the given pathname follows the naming rules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540)  * Returns true if @filename follows the naming rules, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) bool tomoyo_correct_path(const char *filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	return tomoyo_correct_path2(filename, strlen(filename));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548)  * tomoyo_correct_domain - Check whether the given domainname follows the naming rules.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550)  * @domainname: The domainname to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552)  * Returns true if @domainname follows the naming rules, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) bool tomoyo_correct_domain(const unsigned char *domainname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	if (!domainname || !tomoyo_domain_def(domainname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	domainname = strchr(domainname, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	if (!domainname++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		const unsigned char *cp = strchr(domainname, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		if (!cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		if (!tomoyo_correct_path2(domainname, cp - domainname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 		domainname = cp + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	return tomoyo_correct_path(domainname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574)  * tomoyo_domain_def - Check whether the given token can be a domainname.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576)  * @buffer: The token to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578)  * Returns true if @buffer possibly be a domainname, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) bool tomoyo_domain_def(const unsigned char *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	const unsigned char *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	if (*buffer != '<')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	cp = strchr(buffer, ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	if (!cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		len = strlen(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		len = cp - buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	if (buffer[len - 1] != '>' ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	    !tomoyo_correct_word2(buffer + 1, len - 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599)  * tomoyo_find_domain - Find a domain by the given name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601)  * @domainname: The domainname to find.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603)  * Returns pointer to "struct tomoyo_domain_info" if found, NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605)  * Caller holds tomoyo_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	struct tomoyo_domain_info *domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	struct tomoyo_path_info name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	name.name = domainname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	tomoyo_fill_path_info(&name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	list_for_each_entry_rcu(domain, &tomoyo_domain_list, list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 				srcu_read_lock_held(&tomoyo_ss)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		if (!domain->is_deleted &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		    !tomoyo_pathcmp(&name, domain->domainname))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 			return domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624)  * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626)  * @filename: The string to evaluate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628)  * Returns the initial length without a pattern in @filename.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) static int tomoyo_const_part_length(const char *filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	int len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	if (!filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	while ((c = *filename++) != '\0') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 		if (c != '\\') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 			len++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		c = *filename++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		switch (c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		case '\\':  /* "\\" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 			len += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 		case '0':   /* "\ooo" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		case '1':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		case '2':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		case '3':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 			c = *filename++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 			if (c < '0' || c > '7')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 			c = *filename++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 			if (c < '0' || c > '7')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 			len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666)  * tomoyo_fill_path_info - Fill in "struct tomoyo_path_info" members.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668)  * @ptr: Pointer to "struct tomoyo_path_info" to fill in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670)  * The caller sets "struct tomoyo_path_info"->name.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) void tomoyo_fill_path_info(struct tomoyo_path_info *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	const char *name = ptr->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	const int len = strlen(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	ptr->const_len = tomoyo_const_part_length(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	ptr->is_dir = len && (name[len - 1] == '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	ptr->is_patterned = (ptr->const_len < len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	ptr->hash = full_name_hash(NULL, name, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684)  * tomoyo_file_matches_pattern2 - Pattern matching without '/' character and "\-" pattern.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686)  * @filename:     The start of string to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687)  * @filename_end: The end of string to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688)  * @pattern:      The start of pattern to compare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689)  * @pattern_end:  The end of pattern to compare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691)  * Returns true if @filename matches @pattern, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) static bool tomoyo_file_matches_pattern2(const char *filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 					 const char *filename_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 					 const char *pattern,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 					 const char *pattern_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	while (filename < filename_end && pattern < pattern_end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		if (*pattern != '\\') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 			if (*filename++ != *pattern++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 				return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		c = *filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 		pattern++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 		switch (*pattern) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		case '?':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 			if (c == '/') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 				return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 			} else if (c == '\\') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 				if (filename[1] == '\\')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 					filename++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 				else if (tomoyo_byte_range(filename + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 					filename += 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 					return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		case '\\':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 			if (c != '\\')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 				return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 			if (*++filename != '\\')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 				return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 		case '+':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 			if (!isdigit(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 				return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		case 'x':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 			if (!isxdigit(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 				return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 		case 'a':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 			if (!tomoyo_alphabet_char(c))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 				return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		case '0':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		case '1':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		case '2':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		case '3':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 			if (c == '\\' && tomoyo_byte_range(filename + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 			    && strncmp(filename + 1, pattern, 3) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 				filename += 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 				pattern += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 			return false; /* Not matched. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		case '*':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		case '@':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 			for (i = 0; i <= filename_end - filename; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 				if (tomoyo_file_matches_pattern2(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 						    filename + i, filename_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 						    pattern + 1, pattern_end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 					return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 				c = filename[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 				if (c == '.' && *pattern == '@')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 				if (c != '\\')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 				if (filename[i + 1] == '\\')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 					i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 				else if (tomoyo_byte_range(filename + i + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 					i += 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 					break; /* Bad pattern. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 			return false; /* Not matched. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 			j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 			c = *pattern;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 			if (c == '$') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 				while (isdigit(filename[j]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 					j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 			} else if (c == 'X') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 				while (isxdigit(filename[j]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 					j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 			} else if (c == 'A') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 				while (tomoyo_alphabet_char(filename[j]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 					j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 			for (i = 1; i <= j; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 				if (tomoyo_file_matches_pattern2(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 						    filename + i, filename_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 						    pattern + 1, pattern_end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 					return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 			return false; /* Not matched or bad pattern. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		filename++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		pattern++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	while (*pattern == '\\' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	       (*(pattern + 1) == '*' || *(pattern + 1) == '@'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		pattern += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	return filename == filename_end && pattern == pattern_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803)  * tomoyo_file_matches_pattern - Pattern matching without '/' character.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805)  * @filename:     The start of string to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806)  * @filename_end: The end of string to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807)  * @pattern:      The start of pattern to compare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808)  * @pattern_end:  The end of pattern to compare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810)  * Returns true if @filename matches @pattern, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) static bool tomoyo_file_matches_pattern(const char *filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 					const char *filename_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 					const char *pattern,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 					const char *pattern_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	const char *pattern_start = pattern;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	bool first = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	bool result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	while (pattern < pattern_end - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		/* Split at "\-" pattern. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		if (*pattern++ != '\\' || *pattern++ != '-')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		result = tomoyo_file_matches_pattern2(filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 						      filename_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 						      pattern_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 						      pattern - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		if (first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 			result = !result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		first = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		pattern_start = pattern;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	result = tomoyo_file_matches_pattern2(filename, filename_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 					      pattern_start, pattern_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	return first ? result : !result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842)  * tomoyo_path_matches_pattern2 - Do pathname pattern matching.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844)  * @f: The start of string to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845)  * @p: The start of pattern to compare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847)  * Returns true if @f matches @p, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) static bool tomoyo_path_matches_pattern2(const char *f, const char *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	const char *f_delimiter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	const char *p_delimiter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	while (*f && *p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		f_delimiter = strchr(f, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 		if (!f_delimiter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 			f_delimiter = f + strlen(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		p_delimiter = strchr(p, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 		if (!p_delimiter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 			p_delimiter = p + strlen(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		if (*p == '\\' && *(p + 1) == '{')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 			goto recursive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		if (!tomoyo_file_matches_pattern(f, f_delimiter, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 						 p_delimiter))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 		f = f_delimiter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		if (*f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 			f++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		p = p_delimiter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		if (*p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 			p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	/* Ignore trailing "\*" and "\@" in @pattern. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	while (*p == '\\' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	       (*(p + 1) == '*' || *(p + 1) == '@'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		p += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	return !*f && !*p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878)  recursive:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	 * The "\{" pattern is permitted only after '/' character.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	 * This guarantees that below "*(p - 1)" is safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	 * Also, the "\}" pattern is permitted only before '/' character
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	 * so that "\{" + "\}" pair will not break the "\-" operator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	if (*(p - 1) != '/' || p_delimiter <= p + 3 || *p_delimiter != '/' ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	    *(p_delimiter - 1) != '}' || *(p_delimiter - 2) != '\\')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		return false; /* Bad pattern. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		/* Compare current component with pattern. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		if (!tomoyo_file_matches_pattern(f, f_delimiter, p + 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 						 p_delimiter - 2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		/* Proceed to next component. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		f = f_delimiter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		if (!*f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		f++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		/* Continue comparison. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		if (tomoyo_path_matches_pattern2(f, p_delimiter + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		f_delimiter = strchr(f, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	} while (f_delimiter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	return false; /* Not matched. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907)  * tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909)  * @filename: The filename to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910)  * @pattern:  The pattern to compare.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912)  * Returns true if matches, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914)  * The following patterns are available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915)  *   \\     \ itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916)  *   \ooo   Octal representation of a byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917)  *   \*     Zero or more repetitions of characters other than '/'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918)  *   \@     Zero or more repetitions of characters other than '/' or '.'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919)  *   \?     1 byte character other than '/'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920)  *   \$     One or more repetitions of decimal digits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921)  *   \+     1 decimal digit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922)  *   \X     One or more repetitions of hexadecimal digits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923)  *   \x     1 hexadecimal digit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924)  *   \A     One or more repetitions of alphabet characters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925)  *   \a     1 alphabet character.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927)  *   \-     Subtraction operator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929)  *   /\{dir\}/   '/' + 'One or more repetitions of dir/' (e.g. /dir/ /dir/dir/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930)  *               /dir/dir/dir/ ).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 				 const struct tomoyo_path_info *pattern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	const char *f = filename->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	const char *p = pattern->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	const int len = pattern->const_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	/* If @pattern doesn't contain pattern, I can use strcmp(). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	if (!pattern->is_patterned)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		return !tomoyo_pathcmp(filename, pattern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	/* Don't compare directory and non-directory. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	if (filename->is_dir != pattern->is_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	/* Compare the initial length without patterns. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	if (strncmp(f, p, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	f += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	p += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	return tomoyo_path_matches_pattern2(f, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954)  * tomoyo_get_exe - Get tomoyo_realpath() of current process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956)  * Returns the tomoyo_realpath() of current process on success, NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958)  * This function uses kzalloc(), so the caller must call kfree()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959)  * if this function didn't return NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) const char *tomoyo_get_exe(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	struct file *exe_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	const char *cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	struct mm_struct *mm = current->mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	if (!mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	exe_file = get_mm_exe_file(mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	if (!exe_file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	cp = tomoyo_realpath_from_path(&exe_file->f_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	fput(exe_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	return cp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979)  * tomoyo_get_mode - Get MAC mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981)  * @ns:      Pointer to "struct tomoyo_policy_namespace".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982)  * @profile: Profile number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983)  * @index:   Index number of functionality.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985)  * Returns mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) int tomoyo_get_mode(const struct tomoyo_policy_namespace *ns, const u8 profile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		    const u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	u8 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	struct tomoyo_profile *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	if (!tomoyo_policy_loaded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		return TOMOYO_CONFIG_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	p = tomoyo_profile(ns, profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	mode = p->config[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	if (mode == TOMOYO_CONFIG_USE_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		mode = p->config[tomoyo_index2category[index]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 				 + TOMOYO_MAX_MAC_INDEX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	if (mode == TOMOYO_CONFIG_USE_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 		mode = p->default_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	return mode & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)  * tomoyo_init_request_info - Initialize "struct tomoyo_request_info" members.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)  * @r:      Pointer to "struct tomoyo_request_info" to initialize.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)  * @domain: Pointer to "struct tomoyo_domain_info". NULL for tomoyo_domain().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)  * @index:  Index number of functionality.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)  * Returns mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) int tomoyo_init_request_info(struct tomoyo_request_info *r,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 			     struct tomoyo_domain_info *domain, const u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	u8 profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	memset(r, 0, sizeof(*r));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	if (!domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		domain = tomoyo_domain();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	r->domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	profile = domain->profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	r->profile = profile;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	r->type = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	r->mode = tomoyo_get_mode(domain->ns, profile, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	return r->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)  * tomoyo_domain_quota_is_ok - Check for domain's quota.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)  * @r: Pointer to "struct tomoyo_request_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)  * Returns true if the domain is not exceeded quota, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)  * Caller holds tomoyo_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) bool tomoyo_domain_quota_is_ok(struct tomoyo_request_info *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	unsigned int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	struct tomoyo_domain_info *domain = r->domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	struct tomoyo_acl_info *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	if (r->mode != TOMOYO_CONFIG_LEARNING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	if (!domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	if (READ_ONCE(domain->flags[TOMOYO_DIF_QUOTA_WARNED]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	list_for_each_entry_rcu(ptr, &domain->acl_info_list, list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 				srcu_read_lock_held(&tomoyo_ss)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		u16 perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 		if (ptr->is_deleted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		 * Reading perm bitmap might race with tomoyo_merge_*() because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		 * caller does not hold tomoyo_policy_lock mutex. But exceeding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		 * max_learning_entry parameter by a few entries does not harm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		switch (ptr->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		case TOMOYO_TYPE_PATH_ACL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 			perm = data_race(container_of(ptr, struct tomoyo_path_acl, head)->perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 		case TOMOYO_TYPE_PATH2_ACL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 			perm = data_race(container_of(ptr, struct tomoyo_path2_acl, head)->perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		case TOMOYO_TYPE_PATH_NUMBER_ACL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 			perm = data_race(container_of(ptr, struct tomoyo_path_number_acl, head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 				  ->perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		case TOMOYO_TYPE_MKDEV_ACL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 			perm = data_race(container_of(ptr, struct tomoyo_mkdev_acl, head)->perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		case TOMOYO_TYPE_INET_ACL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 			perm = data_race(container_of(ptr, struct tomoyo_inet_acl, head)->perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		case TOMOYO_TYPE_UNIX_ACL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 			perm = data_race(container_of(ptr, struct tomoyo_unix_acl, head)->perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		case TOMOYO_TYPE_MANUAL_TASK_ACL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 			perm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 			perm = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		count += hweight16(perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	if (count < tomoyo_profile(domain->ns, domain->profile)->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	    pref[TOMOYO_PREF_MAX_LEARNING_ENTRY])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	WRITE_ONCE(domain->flags[TOMOYO_DIF_QUOTA_WARNED], true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	/* r->granted = false; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	tomoyo_write_log(r, "%s", tomoyo_dif[TOMOYO_DIF_QUOTA_WARNED]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) #ifndef CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	pr_warn("WARNING: Domain '%s' has too many ACLs to hold. Stopped learning mode.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		domain->domainname->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }