// SPDX-License-Identifier: GPL-2.0
/*
* security/tomoyo/util.c
*
* Copyright (C) 2005-2011 NTT DATA CORPORATION
*/
#include <linux/slab.h>
#include <linux/rculist.h>
#include "common.h"
/* Lock for protecting policy. */
DEFINE_MUTEX(tomoyo_policy_lock);
/* Has /sbin/init started? */
bool tomoyo_policy_loaded;
/*
* Mapping table from "enum tomoyo_mac_index" to
* "enum tomoyo_mac_category_index".
*/
const u8 tomoyo_index2category[TOMOYO_MAX_MAC_INDEX] = {
/* CONFIG::file group */
[TOMOYO_MAC_FILE_EXECUTE] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_OPEN] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_CREATE] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_UNLINK] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_GETATTR] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_MKDIR] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_RMDIR] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_MKFIFO] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_MKSOCK] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_TRUNCATE] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_SYMLINK] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_MKBLOCK] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_MKCHAR] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_LINK] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_RENAME] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_CHMOD] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_CHOWN] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_CHGRP] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_IOCTL] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_CHROOT] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_MOUNT] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_UMOUNT] = TOMOYO_MAC_CATEGORY_FILE,
[TOMOYO_MAC_FILE_PIVOT_ROOT] = TOMOYO_MAC_CATEGORY_FILE,
/* CONFIG::network group */
[TOMOYO_MAC_NETWORK_INET_STREAM_BIND] =
TOMOYO_MAC_CATEGORY_NETWORK,
[TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN] =
TOMOYO_MAC_CATEGORY_NETWORK,
[TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT] =
TOMOYO_MAC_CATEGORY_NETWORK,
[TOMOYO_MAC_NETWORK_INET_DGRAM_BIND] =
TOMOYO_MAC_CATEGORY_NETWORK,
[TOMOYO_MAC_NETWORK_INET_DGRAM_SEND] =
TOMOYO_MAC_CATEGORY_NETWORK,
[TOMOYO_MAC_NETWORK_INET_RAW_BIND] =
TOMOYO_MAC_CATEGORY_NETWORK,
[TOMOYO_MAC_NETWORK_INET_RAW_SEND] =
TOMOYO_MAC_CATEGORY_NETWORK,
[TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND] =
TOMOYO_MAC_CATEGORY_NETWORK,
[TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN] =
TOMOYO_MAC_CATEGORY_NETWORK,
[TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT] =
TOMOYO_MAC_CATEGORY_NETWORK,
[TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND] =
TOMOYO_MAC_CATEGORY_NETWORK,
[TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND] =
TOMOYO_MAC_CATEGORY_NETWORK,
[TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND] =
TOMOYO_MAC_CATEGORY_NETWORK,
[TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN] =
TOMOYO_MAC_CATEGORY_NETWORK,
[TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] =
TOMOYO_MAC_CATEGORY_NETWORK,
/* CONFIG::misc group */
[TOMOYO_MAC_ENVIRON] = TOMOYO_MAC_CATEGORY_MISC,
};
/**
* tomoyo_convert_time - Convert time_t to YYYY/MM/DD hh/mm/ss.
*
* @time: Seconds since 1970/01/01 00:00:00.
* @stamp: Pointer to "struct tomoyo_time".
*
* Returns nothing.
*/
void tomoyo_convert_time(time64_t time64, struct tomoyo_time *stamp)
{
struct tm tm;
time64_to_tm(time64, 0, &tm);
stamp->sec = tm.tm_sec;
stamp->min = tm.tm_min;
stamp->hour = tm.tm_hour;
stamp->day = tm.tm_mday;
stamp->month = tm.tm_mon + 1;
stamp->year = tm.tm_year + 1900;
}
/**
* tomoyo_permstr - Find permission keywords.
*
* @string: String representation for permissions in foo/bar/buz format.
* @keyword: Keyword to find from @string/
*
* Returns true if @keyword was found in @string, false otherwise.
*
* This function assumes that strncmp(w1, w2, strlen(w1)) != 0 if w1 != w2.
*/
bool tomoyo_permstr(const char *string, const char *keyword)
{
const char *cp = strstr(string, keyword);
if (cp)
return cp == string || *(cp - 1) == '/';
return false;
}
/**
* 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;
}
static bool tomoyo_correct_path2(const char *filename, const size_t len);
/**
* tomoyo_get_domainname - Read a domainname from a line.
*
* @param: Pointer to "struct tomoyo_acl_param".
*
* Returns a domainname on success, NULL otherwise.
*/
const struct tomoyo_path_info *tomoyo_get_domainname
(struct tomoyo_acl_param *param)
{
char *start = param->data;
char *pos = start;
while (*pos) {
if (*pos++ != ' ' ||
tomoyo_correct_path2(pos, strchrnul(pos, ' ') - pos))
continue;
*(pos - 1) = '\0';
break;
}
param->data = pos;
if (tomoyo_correct_domain(