// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2010 IBM Corporation
 *
 * Authors:
 * Mimi Zohar <zohar@us.ibm.com>
 *
 * File: evm_secfs.c
 *	- Used to signal when key is on keyring
 *	- Get the key and enable EVM
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/audit.h>
#include <linux/uaccess.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include "evm.h"

static struct dentry *evm_dir;
static struct dentry *evm_init_tpm;
static struct dentry *evm_symlink;

#ifdef CONFIG_EVM_ADD_XATTRS
static struct dentry *evm_xattrs;
static DEFINE_MUTEX(xattr_list_mutex);
static int evm_xattrs_locked;
#endif

/**
 * evm_read_key - read() for <securityfs>/evm
 *
 * @filp: file pointer, not actually used
 * @buf: where to put the result
 * @count: maximum to send along
 * @ppos: where to start
 *
 * Returns number of bytes read or error code, as appropriate
 */
static ssize_t evm_read_key(struct file *filp, char __user *buf,
			    size_t count, loff_t *ppos)
{
	char temp[80];
	ssize_t rc;

	if (*ppos != 0)
		return 0;

	sprintf(temp, "%d", (evm_initialized & ~EVM_SETUP_COMPLETE));
	rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));

	return rc;
}

/**
 * evm_write_key - write() for <securityfs>/evm
 * @file: file pointer, not actually used
 * @buf: where to get the data from
 * @count: bytes sent
 * @ppos: where to start
 *
 * Used to signal that key is on the kernel key ring.
 * - get the integrity hmac key from the kernel key ring
 * - create list of hmac protected extended attributes
 * Returns number of bytes written or error code, as appropriate
 */
static ssize_t evm_write_key(struct file *file, const char __user *buf,
			     size_t count, loff_t *ppos)
{
	unsigned int i;
	int ret;

	if (!capable(CAP_SYS_ADMIN) || (evm_initialized & EVM_SETUP_COMPLETE))
		return -EPERM;

	ret = kstrtouint_from_user(buf, count, 0, &i);

	if (ret)
		return ret;

	/* Reject invalid values */
	if (!i || (i & ~EVM_INIT_MASK) != 0)
		return -EINVAL;

	/*
	 * Don't allow a request to enable metadata writes if
	 * an HMAC key is loaded.
	 */
	if ((i & EVM_ALLOW_METADATA_WRITES) &&
	    (evm_initialized & EVM_INIT_HMAC) != 0)
		return -EPERM;

	if (i & EVM_INIT_HMAC) {
		ret = evm_init_key();
		if (ret != 0)
			return ret;
		/* Forbid further writes after the symmetric key is loaded */
		i |= EVM_SETUP_COMPLETE;
	}

	evm_initialized |= i;

	/* Don't allow protected metadata modification if a symmetric key
	 * is loaded
	 */
	if (evm_initialized & EVM_INIT_HMAC)
		evm_initialized &= ~(EVM_ALLOW_METADATA_WRITES);

	return count;
}

static const struct file_operations evm_key_ops = {
	.read		= evm_read_key,
	.write		= evm_write_key,
};

#ifdef CONFIG_EVM_ADD_XATTRS
/**
 * evm_read_xattrs - read() for <securityfs>/evm_xattrs
 *
 * @filp: file pointer, not actually used
 * @buf: where to put the result
 * @count: maximum to send along
 * @ppos: where to start
 *
 * Returns number of bytes read or error code, as appropriate
 */
static ssize_t evm_read_xattrs(struct file *filp, char __user *buf,
			       size_t count, loff_t *ppos)
{
	char *temp;
	int offset = 0;
	ssize_t rc, size = 0;
	struct xattr_list *xattr;

	if (*ppos != 0)
		return 0;

	rc = mutex_lock_interruptible(&xattr_list_mutex);
	if (rc)
		return -ERESTARTSYS;

	list_for_each_entry(xattr, &evm_config_xattrnames, list)
		size += strlen(xattr->name) + 1;

	temp = kmalloc(size + 1, GFP_KERNEL);
	if (!temp) {
		mutex_unlock(&xattr_list_mutex);
		return -ENOMEM;
	}

	list_for_each_entry(xattr, &evm_config_xattrnames, list) {
		sprintf(temp + offset, "%s\n", xattr->name);
		offset += strlen(xattr->name) + 1;
	}

	mutex_unlock(&xattr_list_mutex);
	rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp));

	kfree(temp);

	return rc;
}

/**
 * evm_write_xattrs - write() for <securityfs>/evm_xattrs
 * @file: file pointer, not actually used
 * @buf: where to get the data from
 * @count: bytes sent
 * @ppos: where to start
 *
 * Returns number of bytes written or error code, as appropriate
 */
static ssize_t evm_write_xattrs(struct file *file, const char __user *buf,
				size_t count, loff_t *ppos)
{
	int len, err;
	struct xattr_list *xattr, *tmp;
	struct audit_buffer *ab;
	struct iattr newattrs;
	struct inode *inode;

	if (!capable(CAP_SYS_ADMIN) || evm_xattrs_locked)
		return -EPERM;

	if (*ppos != 0)
		return -EINVAL;

	if (count > XATTR_NAME_MAX)
		return -E2BIG;

	ab = audit_log_start(audit_context(), GFP_KERNEL,
			     AUDIT_INTEGRITY_EVM_XATTR);
	if (!ab)
		return -ENOMEM;

	xattr = kmalloc(sizeof(struct xattr_list), GFP_KERNEL);
	if (!xattr) {
		err = -ENOMEM;
		goto out;
	}

	xattr->name = memdup_user_nul(buf, count);
	if (IS_ERR(xattr->name)) {
		err = PTR_ERR(xattr->name);
		xattr->name = NULL;
		goto out;
	}

	/* Remove any trailing newline */
	len = strlen(xattr->name);
	if (len && xattr->name[len-1] == '\n')
		xattr->name[len-1] = '\0';

	audit_log_format(ab, "xattr=");
	audit_log_untrustedstring(ab, xattr->name);

	if (strcmp(xattr->name, ".") == 0) {
		evm_xattrs_locked = 1;
		newattrs.ia_mode = S_IFREG | 0440;
		newattrs.ia_valid = ATTR_MODE;
		inode = evm_xattrs->d_inode;
		inode_lock(inode);
		err = simple_setattr(evm_xattrs, &newattrs);
		inode_unlock(inode);
		if (!err)
			err = count;
		goto out;
	}

	if (strncmp(xattr->name, XATTR_SECURITY_PREFIX,
		    XATTR_SECURITY_PREFIX_LEN) != 0) {
		err = -EINVAL;
		goto out;
	}

	/*
	 * xattr_list_mutex guards against races in evm_read_xattrs().
	 * Entries are only added to the evm_config_xattrnames list
	 * and never deleted. Therefore, the list is traversed
	 * using list_for_each_entry_lockless() without holding
	 * the mutex in evm_calc_hmac_or_hash(), evm_find_protected_xattrs()
	 * and evm_protected_xattr().
	 */
	mutex_lock(&xattr_list_mutex);
	list_for_each_entry(tmp, &evm_config_xattrnames, list) {
		if (strcmp(xattr->name, tmp->name) == 0) {
			err = -EEXIST;
			mutex_unlock(&xattr_list_mutex);
			goto out;
		}
	}
	list_add_tail_rcu(&xattr->list, &evm_config_xattrnames);
	mutex_unlock(&xattr_list_mutex);

	audit_log_format(ab, " res=0");
	audit_log_end(ab);
	return count;
out:
	audit_log_format(ab, " res=%d", err);
	audit_log_end(ab);
	if (xattr) {
		kfree(xattr->name);
		kfree(xattr);
	}
	return err;
}

static const struct file_operations evm_xattr_ops = {
	.read		= evm_read_xattrs,
	.write		= evm_write_xattrs,
};

static int evm_init_xattrs(void)
{
	evm_xattrs = securityfs_create_file("evm_xattrs", 0660, evm_dir, NULL,
					    &evm_xattr_ops);
	if (!evm_xattrs || IS_ERR(evm_xattrs))
		return -EFAULT;

	return 0;
}
#else
static int evm_init_xattrs(void)
{
	return 0;
}
#endif

int __init evm_init_secfs(void)
{
	int error = 0;

	evm_dir = securityfs_create_dir("evm", integrity_dir);
	if (!evm_dir || IS_ERR(evm_dir))
		return -EFAULT;

	evm_init_tpm = securityfs_create_file("evm", 0660,
					      evm_dir, NULL, &evm_key_ops);
	if (!evm_init_tpm || IS_ERR(evm_init_tpm)) {
		error = -EFAULT;
		goto out;
	}

	evm_symlink = securityfs_create_symlink("evm", NULL,
						"integrity/evm/evm", NULL);
	if (!evm_symlink || IS_ERR(evm_symlink)) {
		error = -EFAULT;
		goto out;
	}

	if (evm_init_xattrs() != 0) {
		error = -EFAULT;
		goto out;
	}

	return 0;
out:
	securityfs_remove(evm_symlink);
	securityfs_remove(evm_init_tpm);
	securityfs_remove(evm_dir);
	return error;
}
