/*
 * security/tomoyo/file.c
 *
 * Implementation of the Domain-Based Mandatory Access Control.
 *
 * Copyright (C) 2005-2009  NTT DATA CORPORATION
 *
 * Version: 2.2.0   2009/04/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;
}
