/*
 * security/tomoyo/file.c
 *
 * Implementation of the Domain-Based Mandatory Access Control.
 *
 * Copyright (C) 2005-2009  NTT DATA CORPORATION
 *
 * Version: 2.2.0-pre   2009/02/01
 *
 */

#include "common.h"
#include "tomoyo.h"
#include "realpath.h"
#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])

/* Structure for "allow_read" keyword. */
struct tomoyo_globally_readable_file_entry {
	struct list_head list;
	const struct tomoyo_path_info *filename;
	bool is_deleted;
};

/* Structure for "file_pattern" keyword. */
struct tomoyo_pattern_entry {
	struct list_head list;
	const struct tomoyo_path_info *pattern;
	bool is_deleted;
};

/* Structure for "deny_rewrite" keyword. */
struct tomoyo_no_rewrite_entry {
	struct list_head list;
	const struct tomoyo_path_info *pattern;
	bool is_deleted;
};

/* Keyword array for single path operations. */
static const char *tomoyo_sp_keyword[TOMOYO_MAX_SINGLE_PATH_OPERATION] = {
	[TOMOYO_TYPE_READ_WRITE_ACL] = "read/write",
	[TOMOYO_TYPE_EXECUTE_ACL]    = "execute",
	[TOMOYO_TYPE_READ_ACL]       = "read",
	[TOMOYO_TYPE_WRITE_ACL]      = "write",
	[TOMOYO_TYPE_CREATE_ACL]     = "create",
	[TOMOYO_TYPE_UNLINK_ACL]     = "unlink",
	[TOMOYO_TYPE_MKDIR_ACL]      = "mkdir",
	[TOMOYO_TYPE_RMDIR_ACL]      = "rmdir",
	[TOMOYO_TYPE_MKFIFO_ACL]     = "mkfifo",
	[TOMOYO_TYPE_MKSOCK_ACL]     = "mksock",
	[TOMOYO_TYPE_MKBLOCK_ACL]    = "mkblock",
	[TOMOYO_TYPE_MKCHAR_ACL]     = "mkchar",
	[TOMOYO_TYPE_TRUNCATE_ACL]   = "truncate",
	[TOMOYO_TYPE_SYMLINK_ACL]    = "symlink",
	[TOMOYO_TYPE_REWRITE_ACL]    = "rewrite",
};

/* Keyword array for double path operations. */
static const char *tomoyo_dp_keyword[TOMOYO_MAX_DOUBLE_PATH_OPERATION] = {
	[TOMOYO_TYPE_LINK_ACL]    = "link",
	[TOMOYO_TYPE_RENAME_ACL]  = "rename",
};

/**
 * tomoyo_sp2keyword - Get the name of single path operation.
 *
 * @operation: Type of operation.
 *
 * Returns the name of single path operation.
 */
const char *tomoyo_sp2keyword(const u8 operation)
{
	return (operation < TOMOYO_MAX_SINGLE_PATH_OPERATION)
		? tomoyo_sp_keyword[operation] : NULL;
}

/**
 * tomoyo_dp2keyword - Get the name of double path operation.
 *
 * @operation: Type of operation.
 *
 * Returns the name of double path operation.
 */
const char *tomoyo_dp2keyword(const u8 operation)
{
	return (operation < TOMOYO_MAX_DOUBLE_PATH_OPERATION)
		? tomoyo_dp_keyword[operation] : NULL;
}

/**
 * tomoyo_strendswith - Check whether the token ends with the given token.
 *
 * @name: The token to check.
 * @tail: The token to find.
 *
 * Returns true if @name ends with @tail, false otherwise.
 */
static bool tomoyo_strendswith(const char *name, const char *tail)
{
	int len;

	if (!name || !tail)
		return false;
	len = strlen(name) - strlen(tail);
	return len >= 0 && !strcmp(name + len, tail);
}

/**
 * tomoyo_get_path - Get realpath.
 *
 * @path: Pointer to "struct path".
 *
 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
 */
static struct tomoyo_path_info *tomoyo_get_path(struct path *path)
{
	int error;
	struct tomoyo_path_info_with_data *buf = tomoyo_alloc(sizeof(*buf));

	if (!buf)
		return NULL;
	/* Reserve one byte for appending "/". */
	error = tomoyo_realpath_from_path2(path, buf->body,
					   sizeof(buf->body) - 2);
	if (!error) {
		buf->head.name = buf->body;
		tomoyo_fill_path_info(&buf->head);
		return &buf->head;
	}
	tomoyo_free(buf);
	return NULL;
}

/* Lock for domain->acl_info_list. */
DECLARE_RWSEM(tomoyo_domain_acl_info_list_lock);

static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
					 const char *filename2,
					 struct tomoyo_domain_info *
					 const domain, const bool is_delete);
static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
					 struct tomoyo_domain_info *
					 const domain, const bool is_delete);

/* The list for "struct tomoyo_globally_readable_file_entry". */
static LIST_HEAD(tomoyo_globally_readable_list);
static DECLARE_RWSEM(tomoyo_globally_readable_list_lock);

/**
 * tomoyo_update_globally_readable_entry - Update "struct tomoyo_globally_readable_file_entry" list.
 *
 * @filename:  Filename unconditionally permitted to open() for reading.
 * @is_delete: True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 */
static int tomoyo_update_globally_readable_entry(const char *filename,
						 const bool is_delete)
{
	struct tomoyo_globally_readable_file_entry *new_entry;
	struct tomoyo_globally_readable_file_entry *ptr;
	const struct tomoyo_path_info *saved_filename;
	int error = -ENOMEM;

	if (!tomoyo_is_correct_path(filename, 1, 0, -1, __func__))
		return -EINVAL;
	saved_filename = tomoyo_save_name(filename);
	if (!saved_filename)
		return -ENOMEM;
	/***** EXCLUSIVE SECTION START *****/
	down_write(&tomoyo_globally_readable_list_lock);
	list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) {
		if (ptr->filename != saved_filename)
			continue;
		ptr->is_deleted = is_delete;
		error = 0;
		goto out;
	}
	if (is_delete) {
		error = -ENOENT;
		goto out;
	}
	new_entry = tomoyo_alloc_element(sizeof(*new_entry));
	if (!new_entry)
		goto out;
	new_entry->filename = saved_filename;
	list_add_tail(&new_entry->list, &tomoyo_globally_readable_list);
	error = 0;
 out:
	up_write(&tomoyo_globally_readable_list_lock);
	/***** EXCLUSIVE SECTION END *****/
	return error;
}

/**
 * tomoyo_is_globally_readable_file - Check if the file is unconditionnaly permitted to be open()ed for reading.
 *
 * @filename: The filename to check.
 *
 * Returns true if any domain can open @filename for reading, false otherwise.
 */
static bool tomoyo_is_globally_readable_file(const struct tomoyo_path_info *
					     filename)
{
	struct tomoyo_globally_readable_file_entry *ptr;
	bool found = false;
	down_read(&tomoyo_globally_readable_list_lock);
	list_for_each_entry(ptr, &tomoyo_globally_readable_list, list) {
		if (!ptr->is_deleted &&
		    tomoyo_path_matches_pattern(filename, ptr->filename)) {
			found = true;
			break;
		}
	}
	up_read(&tomoyo_globally_readable_list_lock);
	return found;
}

/**
 * tomoyo_write_globally_readable_policy - Write "struct tomoyo_globally_readable_file_entry" list.
 *
 * @data:      String to parse.
 * @is_delete: True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_write_globally_readable_policy(char *data, const bool is_delete)
{
	return tomoyo_update_globally_readable_entry(data, is_delete);
}

/**
 * tomoyo_read_globally_readable_policy - Read "struct tomoyo_globally_readable_file_entry" list.
 *
 * @head: Pointer to "struct tomoyo_io_buffer".
 *
 * Returns true on success, false otherwise.
 */
bool tomoyo_read_globally_readable_policy(struct tomoyo_io_buffer *head)
{
	struct list_head *pos;
	bool done = true;

	down_read(&tomoyo_globally_readable_list_lock);
	list_for_each_cookie(pos, head->read_var2,
			     &tomoyo_globally_readable_list) {
		struct tomoyo_globally_readable_file_entry *ptr;
		ptr = list_entry(pos,
				 struct tomoyo_globally_readable_file_entry,
				 list);
		if (ptr->is_deleted)
			continue;
		if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_ALLOW_READ "%s\n",
				      ptr->filename->name)) {
			done = false;
			break;
		}
	}
	up_read(&tomoyo_globally_readable_list_lock);
	return done;
}

/* The list for "struct tomoyo_pattern_entry". */
static LIST_HEAD(tomoyo_pattern_list);
static DECLARE_RWSEM(tomoyo_pattern_list_lock);

/**
 * tomoyo_update_file_pattern_entry - Update "struct tomoyo_pattern_entry" list.
 *
 * @pattern:   Pathname pattern.
 * @is_delete: True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 */
static int tomoyo_update_file_pattern_entry(const char *pattern,
					    const bool is_delete)
{
	struct tomoyo_pattern_entry *new_entry;
	struct tomoyo_pattern_entry *ptr;
	const struct tomoyo_path_info *saved_pattern;
	int error = -ENOMEM;

	if (!tomoyo_is_correct_path(pattern, 0, 1, 0, __func__))
		return -EINVAL;
	saved_pattern = tomoyo_save_name(pattern);
	if (!saved_pattern)
		return -ENOMEM;
	/***** EXCLUSIVE SECTION START *****/
	down_write(&tomoyo_pattern_list_lock);
	list_for_each_entry(ptr, &tomoyo_pattern_list, list) {
		if (saved_pattern != ptr->pattern)
			continue;
		ptr->is_deleted = is_delete;
		error = 0;
		goto out;
	}
	if (is_delete) {
		error = -ENOENT;
		goto out;
	}
	new_entry = tomoyo_alloc_element(sizeof(*new_entry));
	if (!new_entry)
		goto out;
	new_entry->pattern = saved_pattern;
	list_add_tail(&new_entry->list, &tomoyo_pattern_list);
	error = 0;
 out:
	up_write(&tomoyo_pattern_list_lock);
	/***** EXCLUSIVE SECTION END *****/
	return error;
}

/**
 * tomoyo_get_file_pattern - Get patterned pathname.
 *
 * @filename: The filename to find patterned pathname.
 *
 * Returns pointer to pathname pattern if matched, @filename otherwise.
 */
static const struct tomoyo_path_info *
tomoyo_get_file_pattern(const struct tomoyo_path_info *filename)
{
	struct tomoyo_pattern_entry *ptr;
	const struct tomoyo_path_info *pattern = NULL;

	down_read(&tomoyo_pattern_list_lock);
	list_for_each_entry(ptr, &tomoyo_pattern_list, list) {
		if (ptr->is_deleted)
			continue;
		if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
			continue;
		pattern = ptr->pattern;
		if (tomoyo_strendswith(pattern->name, "/\\*")) {
			/* Do nothing. Try to find the better match. */
		} else {
			/* This would be the better match. Use this. */
			break;
		}
	}
	up_read(&tomoyo_pattern_list_lock);
	if (pattern)
		filename = pattern;
	return filename;
}

/**
 * tomoyo_write_pattern_policy - Write "struct tomoyo_pattern_entry" list.
 *
 * @data:      String to parse.
 * @is_delete: True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_write_pattern_policy(char *data, const bool is_delete)
{
	return tomoyo_update_file_pattern_entry(data, is_delete);
}

/**
 * tomoyo_read_file_pattern - Read "struct tomoyo_pattern_entry" list.
 *
 * @head: Pointer to "struct tomoyo_io_buffer".
 *
 * Returns true on success, false otherwise.
 */
bool tomoyo_read_file_pattern(struct tomoyo_io_buffer *head)
{
	struct list_head *pos;
	bool done = true;

	down_read(&tomoyo_pattern_list_lock);
	list_for_each_cookie(pos, head->read_var2, &tomoyo_pattern_list) {
		struct tomoyo_pattern_entry *ptr;
		ptr = list_entry(pos, struct tomoyo_pattern_entry, list);
		if (ptr->is_deleted)
			continue;
		if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_FILE_PATTERN "%s\n",
				      ptr->pattern->name)) {
			done = false;
			break;
		}
	}
	up_read(&tomoyo_pattern_list_lock);
	return done;
}

/* The list for "struct tomoyo_no_rewrite_entry". */
static LIST_HEAD(tomoyo_no_rewrite_list);
static DECLARE_RWSEM(tomoyo_no_rewrite_list_lock);

/**
 * tomoyo_update_no_rewrite_entry - Update "struct tomoyo_no_rewrite_entry" list.
 *
 * @pattern:   Pathname pattern that are not rewritable by default.
 * @is_delete: True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 */
static int tomoyo_update_no_rewrite_entry(const char *pattern,
					  const bool is_delete)
{
	struct tomoyo_no_rewrite_entry *new_entry, *ptr;
	const struct tomoyo_path_info *saved_pattern;
	int error = -ENOMEM;

	if (!tomoyo_is_correct_path(pattern, 0, 0, 0, __func__))
		return -EINVAL;
	saved_pattern = tomoyo_save_name(pattern);
	if (!saved_pattern)
		return -ENOMEM;
	/***** EXCLUSIVE SECTION START *****/
	down_write(&tomoyo_no_rewrite_list_lock);
	list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) {
		if (ptr->pattern != saved_pattern)
			continue;
		ptr->is_deleted = is_delete;
		error = 0;
		goto out;
	}
	if (is_delete) {
		error = -ENOENT;
		goto out;
	}
	new_entry = tomoyo_alloc_element(sizeof(*new_entry));
	if (!new_entry)
		goto out;
	new_entry->pattern = saved_pattern;
	list_add_tail(&new_entry->list, &tomoyo_no_rewrite_list);
	error = 0;
 out:
	up_write(&tomoyo_no_rewrite_list_lock);
	/***** EXCLUSIVE SECTION END *****/
	return error;
}

/**
 * tomoyo_is_no_rewrite_file - Check if the given pathname is not permitted to be rewrited.
 *
 * @filename: Filename to check.
 *
 * Returns true if @filename is specified by "deny_rewrite" directive,
 * false otherwise.
 */
static bool tomoyo_is_no_rewrite_file(const struct tomoyo_path_info *filename)
{
	struct tomoyo_no_rewrite_entry *ptr;
	bool found = false;

	down_read(&tomoyo_no_rewrite_list_lock);
	list_for_each_entry(ptr, &tomoyo_no_rewrite_list, list) {
		if (ptr->is_deleted)
			continue;
		if (!tomoyo_path_matches_pattern(filename, ptr->pattern))
			continue;
		found = true;
		break;
	}
	up_read(&tomoyo_no_rewrite_list_lock);
	return found;
}

/**
 * tomoyo_write_no_rewrite_policy - Write "struct tomoyo_no_rewrite_entry" list.
 *
 * @data:      String to parse.
 * @is_delete: True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_write_no_rewrite_policy(char *data, const bool is_delete)
{
	return tomoyo_update_no_rewrite_entry(data, is_delete);
}

/**
 * tomoyo_read_no_rewrite_policy - Read "struct tomoyo_no_rewrite_entry" list.
 *
 * @head: Pointer to "struct tomoyo_io_buffer".
 *
 * Returns true on success, false otherwise.
 */
bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
{
	struct list_head *pos;
	bool done = true;

	down_read(&tomoyo_no_rewrite_list_lock);
	list_for_each_cookie(pos, head->read_var2, &tomoyo_no_rewrite_list) {
		struct tomoyo_no_rewrite_entry *ptr;
		ptr = list_entry(pos, struct tomoyo_no_rewrite_entry, list);
		if (ptr->is_deleted)
			continue;
		if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_DENY_REWRITE "%s\n",
				      ptr->pattern->name)) {
			done = false;
			break;
		}
	}
	up_read(&tomoyo_no_rewrite_list_lock);
	return done;
}

/**
 * tomoyo_update_file_acl - Update file's read/write/execute ACL.
 *
 * @filename:  Filename.
 * @perm:      Permission (between 1 to 7).
 * @domain:    Pointer to "struct tomoyo_domain_info".
 * @is_delete: True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 *
 * This is legacy support interface for older policy syntax.
 * Current policy syntax uses "allow_read/write" instead of "6",
 * "allow_read" instead of "4", "allow_write" instead of "2",
 * "allow_execute" instead of "1".
 */
static int tomoyo_update_file_acl(const char *filename, u8 perm,
				  struct tomoyo_domain_info * const domain,
				  const bool is_delete)
{
	if (perm > 7 || !perm) {
		printk(KERN_DEBUG "%s: Invalid permission '%d %s'\n",
		       __func__, perm, filename);
		return -EINVAL;
	}
	if (filename[0] != '@' && tomoyo_strendswith(filename, "/"))
		/*
		 * Only 'allow_mkdir' and 'allow_rmdir' are valid for
		 * directory permissions.
		 */
		return 0;
	if (perm & 4)
		tomoyo_update_single_path_acl(TOMOYO_TYPE_READ_ACL, filename,
					      domain, is_delete);
	if (perm & 2)
		tomoyo_update_single_path_acl(TOMOYO_TYPE_WRITE_ACL, filename,
					      domain, is_delete);
	if (perm & 1)
		tomoyo_update_single_path_acl(TOMOYO_TYPE_EXECUTE_ACL,
					      filename, domain, is_delete);
	return 0;
}

/**
 * tomoyo_check_single_path_acl2 - Check permission for single path operation.
 *
 * @domain:          Pointer to "struct tomoyo_domain_info".
 * @filename:        Filename to check.
 * @perm:            Permission.
 * @may_use_pattern: True if patterned ACL is permitted.
 *
 * Returns 0 on success, -EPERM otherwise.
 */
static int tomoyo_check_single_path_acl2(const struct tomoyo_domain_info *
					 domain,
					 const struct tomoyo_path_info *
					 filename,
					 const u16 perm,
					 const bool may_use_pattern)
{
	struct tomoyo_acl_info *ptr;
	int error = -EPERM;

	down_read(&tomoyo_domain_acl_info_list_lock);
	list_for_each_entry(ptr, &domain->acl_info_list, list) {
		struct tomoyo_single_path_acl_record *acl;
		if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL)
			continue;
		acl = container_of(ptr, struct tomoyo_single_path_acl_record,
				   head);
		if (!(acl->perm & perm))
			continue;
		if (may_use_pattern || !acl->filename->is_patterned) {
			if (!tomoyo_path_matches_pattern(filename,
							 acl->filename))
				continue;
		} else {
			continue;
		}
		error = 0;
		break;
	}
	up_read(&tomoyo_domain_acl_info_list_lock);
	return error;
}

/**
 * tomoyo_check_file_acl - Check permission for opening files.
 *
 * @domain:    Pointer to "struct tomoyo_domain_info".
 * @filename:  Filename to check.
 * @operation: Mode ("read" or "write" or "read/write" or "execute").
 *
 * Returns 0 on success, -EPERM otherwise.
 */
static int tomoyo_check_file_acl(const struct tomoyo_domain_info *domain,
				 const struct tomoyo_path_info *filename,
				 const u8 operation)
{
	u16 perm = 0;

	if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
		return 0;
	if (operation == 6)
		perm = 1 << TOMOYO_TYPE_READ_WRITE_ACL;
	else if (operation == 4)
		perm = 1 << TOMOYO_TYPE_READ_ACL;
	else if (operation == 2)
		perm = 1 << TOMOYO_TYPE_WRITE_ACL;
	else if (operation == 1)
		perm = 1 << TOMOYO_TYPE_EXECUTE_ACL;
	else
		BUG();
	return tomoyo_check_single_path_acl2(domain, filename, perm,
					     operation != 1);
}

/**
 * tomoyo_check_file_perm2 - Check permission for opening files.
 *
 * @domain:    Pointer to "struct tomoyo_domain_info".
 * @filename:  Filename to check.
 * @perm:      Mode ("read" or "write" or "read/write" or "execute").
 * @operation: Operation name passed used for verbose mode.
 * @mode:      Access control mode.
 *
 * Returns 0 on success, negative value otherwise.
 */
static int tomoyo_check_file_perm2(struct tomoyo_domain_info * const domain,
				   const struct tomoyo_path_info *filename,
				   const u8 perm, const char *operation,
				   const u8 mode)
{
	const bool is_enforce = (mode == 3);
	const char *msg = "<unknown>";
	int error = 0;

	if (!filename)
		return 0;
	error = tomoyo_check_file_acl(domain, filename, perm);
	if (error && perm == 4 &&
	    (domain->flags & TOMOYO_DOMAIN_FLAGS_IGNORE_GLOBAL_ALLOW_READ) == 0
	    && tomoyo_is_globally_readable_file(filename))
		error = 0;
	if (perm == 6)
		msg = tomoyo_sp2keyword(TOMOYO_TYPE_READ_WRITE_ACL);
	else if (perm == 4)
		msg = tomoyo_sp2keyword(TOMOYO_TYPE_READ_ACL);
	else if (perm == 2)
		msg = tomoyo_sp2keyword(TOMOYO_TYPE_WRITE_ACL);
	else if (perm == 1)
		msg = tomoyo_sp2keyword(TOMOYO_TYPE_EXECUTE_ACL);
	else
		BUG();
	if (!error)
		return 0;
	if (tomoyo_verbose_mode(domain))
		printk(KERN_WARNING "TOMOYO-%s: Access '%s(%s) %s' denied "
		       "for %s\n", tomoyo_get_msg(is_enforce), msg, operation,
		       filename->name, tomoyo_get_last_name(domain));
	if (is_enforce)
		return error;
	if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) {
		/* Don't use patterns for execute permission. */
		const struct tomoyo_path_info *patterned_file = (perm != 1) ?
			tomoyo_get_file_pattern(filename) : filename;
		tomoyo_update_file_acl(patterned_file->name, perm,
				       domain, false);
	}
	return 0;
}

/**
 * tomoyo_write_file_policy - Update file related list.
 *
 * @data:      String to parse.
 * @domain:    Pointer to "struct tomoyo_domain_info".
 * @is_delete: True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_write_file_policy(char *data, struct tomoyo_domain_info *domain,
			     const bool is_delete)
{
	char *filename = strchr(data, ' ');
	char *filename2;
	unsigned int perm;
	u8 type;

	if (!filename)
		return -EINVAL;
	*filename++ = '\0';
	if (sscanf(data, "%u", &perm) == 1)
		return tomoyo_update_file_acl(filename, (u8) perm, domain,
					      is_delete);
	if (strncmp(data, "allow_", 6))
		goto out;
	data += 6;
	for (type = 0; type < TOMOYO_MAX_SINGLE_PATH_OPERATION; type++) {
		if (strcmp(data, tomoyo_sp_keyword[type]))
			continue;
		return tomoyo_update_single_path_acl(type, filename,
						     domain, is_delete);
	}
	filename2 = strchr(filename, ' ');
	if (!filename2)
		goto out;
	*filename2++ = '\0';
	for (type = 0; type < TOMOYO_MAX_DOUBLE_PATH_OPERATION; type++) {
		if (strcmp(data, tomoyo_dp_keyword[type]))
			continue;
		return tomoyo_update_double_path_acl(type, filename, filename2,
						     domain, is_delete);
	}
 out:
	return -EINVAL;
}

/**
 * tomoyo_update_single_path_acl - Update "struct tomoyo_single_path_acl_record" list.
 *
 * @type:      Type of operation.
 * @filename:  Filename.
 * @domain:    Pointer to "struct tomoyo_domain_info".
 * @is_delete: True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 */
static int tomoyo_update_single_path_acl(const u8 type, const char *filename,
					 struct tomoyo_domain_info *
					 const domain, const bool is_delete)
{
	static const u16 rw_mask =
		(1 << TOMOYO_TYPE_READ_ACL) | (1 << TOMOYO_TYPE_WRITE_ACL);
	const struct tomoyo_path_info *saved_filename;
	struct tomoyo_acl_info *ptr;
	struct tomoyo_single_path_acl_record *acl;
	int error = -ENOMEM;
	const u16 perm = 1 << type;

	if (!domain)
		return -EINVAL;
	if (!tomoyo_is_correct_path(filename, 0, 0, 0, __func__))
		return -EINVAL;
	saved_filename = tomoyo_save_name(filename);
	if (!saved_filename)
		return -ENOMEM;
	/***** EXCLUSIVE SECTION START *****/
	down_write(&tomoyo_domain_acl_info_list_lock);
	if (is_delete)
		goto delete;
	list_for_each_entry(ptr, &domain->acl_info_list, list) {
		if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL)
			continue;
		acl = container_of(ptr, struct tomoyo_single_path_acl_record,
				   head);
		if (acl->filename != saved_filename)
			continue;
		/* Special case. Clear all bits if marked as deleted. */
		if (ptr->type & TOMOYO_ACL_DELETED)
			acl->perm = 0;
		acl->perm |= perm;
		if ((acl->perm & rw_mask) == rw_mask)
			acl->perm |= 1 << TOMOYO_TYPE_READ_WRITE_ACL;
		else if (acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL))
			acl->perm |= rw_mask;
		ptr->type &= ~TOMOYO_ACL_DELETED;
		error = 0;
		goto out;
	}
	/* Not found. Append it to the tail. */
	acl = tomoyo_alloc_acl_element(TOMOYO_TYPE_SINGLE_PATH_ACL);
	if (!acl)
		goto out;
	acl->perm = perm;
	if (perm == (1 << TOMOYO_TYPE_READ_WRITE_ACL))
		acl->perm |= rw_mask;
	acl->filename = saved_filename;
	list_add_tail(&acl->head.list, &domain->acl_info_list);
	error = 0;
	goto out;
 delete:
	error = -ENOENT;
	list_for_each_entry(ptr, &domain->acl_info_list, list) {
		if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_SINGLE_PATH_ACL)
			continue;
		acl = container_of(ptr, struct tomoyo_single_path_acl_record,
				   head);
		if (acl->filename != saved_filename)
			continue;
		acl->perm &= ~perm;
		if ((acl->perm & rw_mask) != rw_mask)
			acl->perm &= ~(1 << TOMOYO_TYPE_READ_WRITE_ACL);
		else if (!(acl->perm & (1 << TOMOYO_TYPE_READ_WRITE_ACL)))
			acl->perm &= ~rw_mask;
		if (!acl->perm)
			ptr->type |= TOMOYO_ACL_DELETED;
		error = 0;
		break;
	}
 out:
	up_write(&tomoyo_domain_acl_info_list_lock);
	/***** EXCLUSIVE SECTION END *****/
	return error;
}

/**
 * tomoyo_update_double_path_acl - Update "struct tomoyo_double_path_acl_record" list.
 *
 * @type:      Type of operation.
 * @filename1: First filename.
 * @filename2: Second filename.
 * @domain:    Pointer to "struct tomoyo_domain_info".
 * @is_delete: True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 */
static int tomoyo_update_double_path_acl(const u8 type, const char *filename1,
					 const char *filename2,
					 struct tomoyo_domain_info *
					 const domain, const bool is_delete)
{
	const struct tomoyo_path_info *saved_filename1;
	const struct tomoyo_path_info *saved_filename2;
	struct tomoyo_acl_info *ptr;
	struct tomoyo_double_path_acl_record *acl;
	int error = -ENOMEM;
	const u8 perm = 1 << type;

	if (!domain)
		return -EINVAL;
	if (!tomoyo_is_correct_path(filename1, 0, 0, 0, __func__) ||
	    !tomoyo_is_correct_path(filename2, 0, 0, 0, __func__))
		return -EINVAL;
	saved_filename1 = tomoyo_save_name(filename1);
	saved_filename2 = tomoyo_save_name(filename2);
	if (!saved_filename1 || !saved_filename2)
		return -ENOMEM;
	/***** EXCLUSIVE SECTION START *****/
	down_write(&tomoyo_domain_acl_info_list_lock);
	if (is_delete)
		goto delete;
	list_for_each_entry(ptr, &domain->acl_info_list, list) {
		if (tomoyo_acl_type1(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
			continue;
		acl = container_of(ptr, struct tomoyo_double_path_acl_record,
				   head);
		if (acl->filename1 != saved_filename1 ||
		    acl->filename2 != saved_filename2)
			continue;
		/* Special case. Clear all bits if marked as deleted. */
		if (ptr->type & TOMOYO_ACL_DELETED)
			acl->perm = 0;
		acl->perm |= perm;
		ptr->type &= ~TOMOYO_ACL_DELETED;
		error = 0;
		goto out;
	}
	/* Not found. Append it to the tail. */
	acl = tomoyo_alloc_acl_element(TOMOYO_TYPE_DOUBLE_PATH_ACL);
	if (!acl)
		goto out;
	acl->perm = perm;
	acl->filename1 = saved_filename1;
	acl->filename2 = saved_filename2;
	list_add_tail(&acl->head.list, &domain->acl_info_list);
	error = 0;
	goto out;
 delete:
	error = -ENOENT;
	list_for_each_entry(ptr, &domain->acl_info_list, list) {
		if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
			continue;
		acl = container_of(ptr, struct tomoyo_double_path_acl_record,
				   head);
		if (acl->filename1 != saved_filename1 ||
		    acl->filename2 != saved_filename2)
			continue;
		acl->perm &= ~perm;
		if (!acl->perm)
			ptr->type |= TOMOYO_ACL_DELETED;
		error = 0;
		break;
	}
 out:
	up_write(&tomoyo_domain_acl_info_list_lock);
	/***** EXCLUSIVE SECTION END *****/
	return error;
}

/**
 * tomoyo_check_single_path_acl - Check permission for single path operation.
 *
 * @domain:   Pointer to "struct tomoyo_domain_info".
 * @type:     Type of operation.
 * @filename: Filename to check.
 *
 * Returns 0 on success, negative value otherwise.
 */
static int tomoyo_check_single_path_acl(struct tomoyo_domain_info *domain,
					const u8 type,
					const struct tomoyo_path_info *filename)
{
	if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
		return 0;
	return tomoyo_check_single_path_acl2(domain, filename, 1 << type, 1);
}

/**
 * tomoyo_check_double_path_acl - Check permission for double path operation.
 *
 * @domain:    Pointer to "struct tomoyo_domain_info".
 * @type:      Type of operation.
 * @filename1: First filename to check.
 * @filename2: Second filename to check.
 *
 * Returns 0 on success, -EPERM otherwise.
 */
static int tomoyo_check_double_path_acl(const struct tomoyo_domain_info *domain,
					const u8 type,
					const struct tomoyo_path_info *
					filename1,
					const struct tomoyo_path_info *
					filename2)
{
	struct tomoyo_acl_info *ptr;
	const u8 perm = 1 << type;
	int error = -EPERM;

	if (!tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE))
		return 0;
	down_read(&tomoyo_domain_acl_info_list_lock);
	list_for_each_entry(ptr, &domain->acl_info_list, list) {
		struct tomoyo_double_path_acl_record *acl;
		if (tomoyo_acl_type2(ptr) != TOMOYO_TYPE_DOUBLE_PATH_ACL)
			continue;
		acl = container_of(ptr, struct tomoyo_double_path_acl_record,
				   head);
		if (!(acl->perm & perm))
			continue;
		if (!tomoyo_path_matches_pattern(filename1, acl->filename1))
			continue;
		if (!tomoyo_path_matches_pattern(filename2, acl->filename2))
			continue;
		error = 0;
		break;
	}
	up_read(&tomoyo_domain_acl_info_list_lock);
	return error;
}

/**
 * tomoyo_check_single_path_permission2 - Check permission for single path operation.
 *
 * @domain:    Pointer to "struct tomoyo_domain_info".
 * @operation: Type of operation.
 * @filename:  Filename to check.
 * @mode:      Access control mode.
 *
 * Returns 0 on success, negative value otherwise.
 */
static int tomoyo_check_single_path_permission2(struct tomoyo_domain_info *
						const domain, u8 operation,
						const struct tomoyo_path_info *
						filename, const u8 mode)
{
	const char *msg;
	int error;
	const bool is_enforce = (mode == 3);

	if (!mode)
		return 0;
 next:
	error = tomoyo_check_single_path_acl(domain, operation, filename);
	msg = tomoyo_sp2keyword(operation);
	if (!error)
		goto ok;
	if (tomoyo_verbose_mode(domain))
		printk(KERN_WARNING "TOMOYO-%s: Access '%s %s' denied for %s\n",
		       tomoyo_get_msg(is_enforce), msg, filename->name,
		       tomoyo_get_last_name(domain));
	if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) {
		const char *name = tomoyo_get_file_pattern(filename)->name;
		tomoyo_update_single_path_acl(operation, name, domain, false);
	}
	if (!is_enforce)
		error = 0;
 ok:
	/*
	 * Since "allow_truncate" doesn't imply "allow_rewrite" permission,
	 * we need to check "allow_rewrite" permission if the filename is
	 * specified by "deny_rewrite" keyword.
	 */
	if (!error && operation == TOMOYO_TYPE_TRUNCATE_ACL &&
	    tomoyo_is_no_rewrite_file(filename)) {
		operation = TOMOYO_TYPE_REWRITE_ACL;
		goto next;
	}
	return error;
}

/**
 * tomoyo_check_file_perm - Check permission for sysctl()'s "read" and "write".
 *
 * @domain:    Pointer to "struct tomoyo_domain_info".
 * @filename:  Filename to check.
 * @perm:      Mode ("read" or "write" or "read/write").
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_check_file_perm(struct tomoyo_domain_info *domain,
			   const char *filename, const u8 perm)
{
	struct tomoyo_path_info name;
	const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);

	if (!mode)
		return 0;
	name.name = filename;
	tomoyo_fill_path_info(&name);
	return tomoyo_check_file_perm2(domain, &name, perm, "sysctl", mode);
}

/**
 * tomoyo_check_exec_perm - Check permission for "execute".
 *
 * @domain:   Pointer to "struct tomoyo_domain_info".
 * @filename: Check permission for "execute".
 * @tmp:      Buffer for temporary use.
 *
 * Returns 0 on success, negativevalue otherwise.
 */
int tomoyo_check_exec_perm(struct tomoyo_domain_info *domain,
			   const struct tomoyo_path_info *filename,
			   struct tomoyo_page_buffer *tmp)
{
	const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);

	if (!mode)
		return 0;
	return tomoyo_check_file_perm2(domain, filename, 1, "do_execve", mode);
}

/**
 * tomoyo_check_open_permission - Check permission for "read" and "write".
 *
 * @domain: Pointer to "struct tomoyo_domain_info".
 * @path:   Pointer to "struct path".
 * @flag:   Flags for open().
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
				 struct path *path, const int flag)
{
	const u8 acc_mode = ACC_MODE(flag);
	int error = -ENOMEM;
	struct tomoyo_path_info *buf;
	const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
	const bool is_enforce = (mode == 3);

	if (!mode || !path->mnt)
		return 0;
	if (acc_mode == 0)
		return 0;
	if (path->dentry->d_inode && S_ISDIR(path->dentry->d_inode->i_mode))
		/*
		 * I don't check directories here because mkdir() and rmdir()
		 * don't call me.
		 */
		return 0;
	buf = tomoyo_get_path(path);
	if (!buf)
		goto out;
	error = 0;
	/*
	 * If the filename is specified by "deny_rewrite" keyword,
	 * we need to check "allow_rewrite" permission when the filename is not
	 * opened for append mode or the filename is truncated at open time.
	 */
	if ((acc_mode & MAY_WRITE) &&
	    ((flag & O_TRUNC) || !(flag & O_APPEND)) &&
	    (tomoyo_is_no_rewrite_file(buf))) {
		error = tomoyo_check_single_path_permission2(domain,
						     TOMOYO_TYPE_REWRITE_ACL,
							     buf, mode);
	}
	if (!error)
		error = tomoyo_check_file_perm2(domain, buf, acc_mode, "open",
						mode);
	if (!error && (flag & O_TRUNC))
		error = tomoyo_check_single_path_permission2(domain,
						     TOMOYO_TYPE_TRUNCATE_ACL,
							     buf, mode);
 out:
	tomoyo_free(buf);
	if (!is_enforce)
		error = 0;
	return error;
}

/**
 * tomoyo_check_1path_perm - Check permission for "create", "unlink", "mkdir", "rmdir", "mkfifo", "mksock", "mkblock", "mkchar", "truncate" and "symlink".
 *
 * @domain:    Pointer to "struct tomoyo_domain_info".
 * @operation: Type of operation.
 * @path:      Pointer to "struct path".
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_check_1path_perm(struct tomoyo_domain_info *domain,
			    const u8 operation, struct path *path)
{
	int error = -ENOMEM;
	struct tomoyo_path_info *buf;
	const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
	const bool is_enforce = (mode == 3);

	if (!mode || !path->mnt)
		return 0;
	buf = tomoyo_get_path(path);
	if (!buf)
		goto out;
	switch (operation) {
	case TOMOYO_TYPE_MKDIR_ACL:
	case TOMOYO_TYPE_RMDIR_ACL:
		if (!buf->is_dir) {
			/*
			 * tomoyo_get_path() reserves space for appending "/."
			 */
			strcat((char *) buf->name, "/");
			tomoyo_fill_path_info(buf);
		}
	}
	error = tomoyo_check_single_path_permission2(domain, operation, buf,
						     mode);
 out:
	tomoyo_free(buf);
	if (!is_enforce)
		error = 0;
	return error;
}

/**
 * tomoyo_check_rewrite_permission - Check permission for "rewrite".
 *
 * @domain: Pointer to "struct tomoyo_domain_info".
 * @filp: Pointer to "struct file".
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain,
				    struct file *filp)
{
	int error = -ENOMEM;
	const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
	const bool is_enforce = (mode == 3);
	struct tomoyo_path_info *buf;

	if (!mode || !filp->f_path.mnt)
		return 0;
	buf = tomoyo_get_path(&filp->f_path);
	if (!buf)
		goto out;
	if (!tomoyo_is_no_rewrite_file(buf)) {
		error = 0;
		goto out;
	}
	error = tomoyo_check_single_path_permission2(domain,
						     TOMOYO_TYPE_REWRITE_ACL,
						     buf, mode);
 out:
	tomoyo_free(buf);
	if (!is_enforce)
		error = 0;
	return error;
}

/**
 * tomoyo_check_2path_perm - Check permission for "rename" and "link".
 *
 * @domain:    Pointer to "struct tomoyo_domain_info".
 * @operation: Type of operation.
 * @path1:      Pointer to "struct path".
 * @path2:      Pointer to "struct path".
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_check_2path_perm(struct tomoyo_domain_info * const domain,
			    const u8 operation, struct path *path1,
			    struct path *path2)
{
	int error = -ENOMEM;
	struct tomoyo_path_info *buf1, *buf2;
	const u8 mode = tomoyo_check_flags(domain, TOMOYO_MAC_FOR_FILE);
	const bool is_enforce = (mode == 3);
	const char *msg;

	if (!mode || !path1->mnt || !path2->mnt)
		return 0;
	buf1 = tomoyo_get_path(path1);
	buf2 = tomoyo_get_path(path2);
	if (!buf1 || !buf2)
		goto out;
	{
		struct dentry *dentry = path1->dentry;
		if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) {
			/*
			 * tomoyo_get_path() reserves space for appending "/."
			 */
			if (!buf1->is_dir) {
				strcat((char *) buf1->name, "/");
				tomoyo_fill_path_info(buf1);
			}
			if (!buf2->is_dir) {
				strcat((char *) buf2->name, "/");
				tomoyo_fill_path_info(buf2);
			}
		}
	}
	error = tomoyo_check_double_path_acl(domain, operation, buf1, buf2);
	msg = tomoyo_dp2keyword(operation);
	if (!error)
		goto out;
	if (tomoyo_verbose_mode(domain))
		printk(KERN_WARNING "TOMOYO-%s: Access '%s %s %s' "
		       "denied for %s\n", tomoyo_get_msg(is_enforce),
		       msg, buf1->name, buf2->name,
		       tomoyo_get_last_name(domain));
	if (mode == 1 && tomoyo_domain_quota_is_ok(domain)) {
		const char *name1 = tomoyo_get_file_pattern(buf1)->name;
		const char *name2 = tomoyo_get_file_pattern(buf2)->name;
		tomoyo_update_double_path_acl(operation, name1, name2, domain,
					      false);
	}
 out:
	tomoyo_free(buf1);
	tomoyo_free(buf2);
	if (!is_enforce)
		error = 0;
	return error;
}
