// SPDX-License-Identifier: GPL-2.0
/*
 * Ioctl to enable verity on a file
 *
 * Copyright 2019 Google LLC
 */

#include "fsverity_private.h"

#include <linux/mount.h>
#include <linux/pagemap.h>
#include <linux/slab.h>
#include <linux/sched/signal.h>
#include <linux/uaccess.h>

struct block_buffer {
	u32 filled;
	bool is_root_hash;
	u8 *data;
};

/* Hash a block, writing the result to the next level's pending block buffer. */
static int hash_one_block(struct inode *inode,
			  const struct merkle_tree_params *params,
			  struct ahash_request *req, struct block_buffer *cur)
{
	struct block_buffer *next = cur + 1;
	int err;

	/*
	 * Safety check to prevent a buffer overflow in case of a filesystem bug
	 * that allows the file size to change despite deny_write_access(), or a
	 * bug in the Merkle tree logic itself
	 */
	if (WARN_ON_ONCE(next->is_root_hash && next->filled != 0))
		return -EINVAL;

	/* Zero-pad the block if it's shorter than the block size. */
	memset(&cur->data[cur->filled], 0, params->block_size - cur->filled);

	err = fsverity_hash_block(params, inode, req, virt_to_page(cur->data),
				  offset_in_page(cur->data),
				  &next->data[next->filled]);
	if (err)
		return err;
	next->filled += params->digest_size;
	cur->filled = 0;
	return 0;
}

static int write_merkle_tree_block(struct inode *inode, const u8 *buf,
				   unsigned long index,
				   const struct merkle_tree_params *params)
{
	u64 pos = (u64)index << params->log_blocksize;
	int err;

	err = inode->i_sb->s_vop->write_merkle_tree_block(inode, buf, pos,
							  params->block_size);
	if (err)
		fsverity_err(inode, "Error %d writing Merkle tree block %lu",
			     err, index);
	return err;
}

/*
 * Build the Merkle tree for the given file using the given parameters, and
 * return the root hash in @root_hash.
 *
 * The tree is written to a filesystem-specific location as determined by the
 * ->write_merkle_tree_block() method.  However, the blocks that comprise the
 * tree are the same for all filesystems.
 */
static int build_merkle_tree(struct file *filp,
			     const struct merkle_tree_params *params,
			     u8 *root_hash)
{
	struct inode *inode = file_inode(filp);
	const u64 data_size = inode->i_size;
	const int num_levels = params->num_levels;
	struct ahash_request *req;
	struct block_buffer _buffers[1 + FS_VERITY_MAX_LEVELS + 1] = {};
	struct block_buffer *buffers = &_buffers[1];
	unsigned long level_offset[FS_VERITY_MAX_LEVELS];
	int level;
	u64 offset;
	int err;

	if (data_size == 0) {
		/* Empty file is a special case; root hash is all 0's */
		memset(root_hash, 0, params->digest_size);
		return 0;
	}

	/* This allocation never fails, since it's mempool-backed. */
	req = fsverity_alloc_hash_request(params->hash_alg, GFP_KERNEL);

	/*
	 * Allocate the block buffers.  Buffer "-1" is for data blocks.
	 * Buffers 0 <= level < num_levels are for the actual tree levels.
	 * Buffer 'num_levels' is for the root hash.
	 */
	for (level = -1; level < num_levels; level++) {
		buffers[level].data = kzalloc(params->block_size, GFP_KERNEL);
		if (!buffers[level].data) {
			err = -ENOMEM;
			goto out;
		}
	}
	buffers[num_levels].data = root_hash;
	buffers[num_levels].is_root_hash = true;

	BUILD_BUG_ON(sizeof(level_offset) != sizeof(params->level_start));
	memcpy(level_offset, params->level_start, sizeof(level_offset));

	/* Hash each data block, also hashing the tree blocks as they fill up */
	for (offset = 0; offset < data_size; offset += params->block_size) {
		ssize_t bytes_read;
		loff_t pos = offset;

		buffers[-1].filled = min_t(u64, params->block_size,
					   data_size - offset);
		bytes_read = __kernel_read(filp, buffers[-1].data,
					   buffers[-1].filled, &pos);
		if (bytes_read < 0) {
			err = bytes_read;
			fsverity_err(inode, "Error %d reading file data", err);
			goto out;
		}
		if (bytes_read != buffers[-1].filled) {
			err = -EINVAL;
			fsverity_err(inode, "Short read of file data");
			goto out;
		}
		err = hash_one_block(inode, params, req, &buffers[-1]);
		if (err)
			goto out;
		for (level = 0; level < num_levels; level++) {
			if (buffers[level].filled + params->digest_size <=
			    params->block_size) {
				/* Next block at @level isn't full yet */
				break;
			}
			/* Next block at @level is full */

			err = hash_one_block(inode, params, req,
					     &buffers[level]);
			if (err)
				goto out;
			err = write_merkle_tree_block(inode,
						      buffers[level].data,
						      level_offset[level],
						      params);
			if (err)
				goto out;
			level_offset[level]++;
		}
		if (fatal_signal_pending(current)) {
			err = -EINTR;
			goto out;
		}
		cond_resched();
	}
	/* Finish all nonempty pending tree blocks. */
	for (level = 0; level < num_levels; level++) {
		if (buffers[level].filled != 0) {
			err = hash_one_block(inode, params, req,
					     &buffers[level]);
			if (err)
				goto out;
			err = write_merkle_tree_block(inode,
						      buffers[level].data,
						      level_offset[level],
						      params);
			if (err)
				goto out;
		}
	}
	/* The root hash was filled by the last call to hash_one_block(). */
	if (WARN_ON(buffers[num_levels].filled != params->digest_size)) {
		err = -EINVAL;
		goto out;
	}
	err = 0;
out:
	for (level = -1; level < num_levels; level++)
		kfree(buffers[level].data);
	fsverity_free_hash_request(params->hash_alg, req);
	return err;
}

static int enable_verity(struct file *filp,
			 const struct fsverity_enable_arg *arg)
{
	struct inode *inode = file_inode(filp);
	const struct fsverity_operations *vops = inode->i_sb->s_vop;
	struct merkle_tree_params params = { };
	struct fsverity_descriptor *desc;
	size_t desc_size = struct_size(desc, signature, arg->sig_size);
	struct fsverity_info *vi;
	int err;

	/* Start initializing the fsverity_descriptor */
	desc = kzalloc(desc_size, GFP_KERNEL);
	if (!desc)
		return -ENOMEM;
	desc->version = 1;
	desc->hash_algorithm = arg->hash_algorithm;
	desc->log_blocksize = ilog2(arg->block_size);

	/* Get the salt if the user provided one */
	if (arg->salt_size &&
	    copy_from_user(desc->salt, u64_to_user_ptr(arg->salt_ptr),
			   arg->salt_size)) {
		err = -EFAULT;
		goto out;
	}
	desc->salt_size = arg->salt_size;

	/* Get the signature if the user provided one */
	if (arg->sig_size &&
	    copy_from_user(desc->signature, u64_to_user_ptr(arg->sig_ptr),
			   arg->sig_size)) {
		err = -EFAULT;
		goto out;
	}
	desc->sig_size = cpu_to_le32(arg->sig_size);

	desc->data_size = cpu_to_le64(inode->i_size);

	/* Prepare the Merkle tree parameters */
	err = fsverity_init_merkle_tree_params(&params, inode,
					       arg->hash_algorithm,
					       desc->log_blocksize,
					       desc->salt, desc->salt_size);
	if (err)
		goto out;

	/*
	 * Start enabling verity on this file, serialized by the inode lock.
	 * Fail if verity is already enabled or is already being enabled.
	 */
	inode_lock(inode);
	if (IS_VERITY(inode))
		err = -EEXIST;
	else
		err = vops->begin_enable_verity(filp);
	inode_unlock(inode);
	if (err)
		goto out;

	/*
	 * Build the Merkle tree.  Don't hold the inode lock during this, since
	 * on huge files this may take a very long time and we don't want to
	 * force unrelated syscalls like chown() to block forever.  We don't
	 * need the inode lock here because deny_write_access() already prevents
	 * the file from being written to or truncated, and we still serialize
	 * ->begin_enable_verity() and ->end_enable_verity() using the inode
	 * lock and only allow one process to be here at a time on a given file.
	 */
	BUILD_BUG_ON(sizeof(desc->root_hash) < FS_VERITY_MAX_DIGEST_SIZE);
	err = build_merkle_tree(filp, &params, desc->root_hash);
	if (err) {
		fsverity_err(inode, "Error %d building Merkle tree", err);
		goto rollback;
	}

	/*
	 * Create the fsverity_info.  Don't bother trying to save work by
	 * reusing the merkle_tree_params from above.  Instead, just create the
	 * fsverity_info from the fsverity_descriptor as if it were just loaded
	 * from disk.  This is simpler, and it serves as an extra check that the
	 * metadata we're writing is valid before actually enabling verity.
	 */
	vi = fsverity_create_info(inode, desc);
	if (IS_ERR(vi)) {
		err = PTR_ERR(vi);
		goto rollback;
	}

	/*
	 * Tell the filesystem to finish enabling verity on the file.
	 * Serialized with ->begin_enable_verity() by the inode lock.
	 */
	inode_lock(inode);
	err = vops->end_enable_verity(filp, desc, desc_size, params.tree_size);
	inode_unlock(inode);
	if (err) {
		fsverity_err(inode, "%ps() failed with err %d",
			     vops->end_enable_verity, err);
		fsverity_free_info(vi);
	} else if (WARN_ON(!IS_VERITY(inode))) {
		err = -EINVAL;
		fsverity_free_info(vi);
	} else {
		/* Successfully enabled verity */

		/*
		 * Readers can start using ->i_verity_info immediately, so it
		 * can't be rolled back once set.  So don't set it until just
		 * after the filesystem has successfully enabled verity.
		 */
		fsverity_set_info(inode, vi);
	}
out:
	kfree(params.hashstate);
	kfree(desc);
	return err;

rollback:
	inode_lock(inode);
	(void)vops->end_enable_verity(filp, NULL, 0, params.tree_size);
	inode_unlock(inode);
	goto out;
}

/**
 * fsverity_ioctl_enable() - enable verity on a file
 * @filp: file to enable verity on
 * @uarg: user pointer to fsverity_enable_arg
 *
 * Enable fs-verity on a file.  See the "FS_IOC_ENABLE_VERITY" section of
 * Documentation/filesystems/fsverity.rst for the documentation.
 *
 * Return: 0 on success, -errno on failure
 */
int fsverity_ioctl_enable(struct file *filp, const void __user *uarg)
{
	struct inode *inode = file_inode(filp);
	struct fsverity_enable_arg arg;
	int err;

	if (copy_from_user(&arg, uarg, sizeof(arg)))
		return -EFAULT;

	if (arg.version != 1)
		return -EINVAL;

	if (arg.__reserved1 ||
	    memchr_inv(arg.__reserved2, 0, sizeof(arg.__reserved2)))
		return -EINVAL;

	if (!is_power_of_2(arg.block_size))
		return -EINVAL;

	if (arg.salt_size > sizeof_field(struct fsverity_descriptor, salt))
		return -EMSGSIZE;

	if (arg.sig_size > FS_VERITY_MAX_SIGNATURE_SIZE)
		return -EMSGSIZE;

	/*
	 * Require a regular file with write access.  But the actual fd must
	 * still be readonly so that we can lock out all writers.  This is
	 * needed to guarantee that no writable fds exist to the file once it
	 * has verity enabled, and to stabilize the data being hashed.
	 */

	err = file_permission(filp, MAY_WRITE);
	if (err)
		return err;
	/*
	 * __kernel_read() is used while building the Merkle tree.  So, we can't
	 * allow file descriptors that were opened for ioctl access only, using
	 * the special nonstandard access mode 3.  O_RDONLY only, please!
	 */
	if (!(filp->f_mode & FMODE_READ))
		return -EBADF;

	if (IS_APPEND(inode))
		return -EPERM;

	if (S_ISDIR(inode->i_mode))
		return -EISDIR;

	if (!S_ISREG(inode->i_mode))
		return -EINVAL;

	err = mnt_want_write_file(filp);
	if (err) /* -EROFS */
		return err;

	err = deny_write_access(filp);
	if (err) /* -ETXTBSY */
		goto out_drop_write;

	err = enable_verity(filp, &arg);

	/*
	 * We no longer drop the inode's pagecache after enabling verity.  This
	 * used to be done to try to avoid a race condition where pages could be
	 * evicted after being used in the Merkle tree construction, then
	 * re-instantiated by a concurrent read.  Such pages are unverified, and
	 * the backing storage could have filled them with different content, so
	 * they shouldn't be used to fulfill reads once verity is enabled.
	 *
	 * But, dropping the pagecache has a big performance impact, and it
	 * doesn't fully solve the race condition anyway.  So for those reasons,
	 * and also because this race condition isn't very important relatively
	 * speaking (especially for small-ish files, where the chance of a page
	 * being used, evicted, *and* re-instantiated all while enabling verity
	 * is quite small), we no longer drop the inode's pagecache.
	 */

	/*
	 * allow_write_access() is needed to pair with deny_write_access().
	 * Regardless, the filesystem won't allow writing to verity files.
	 */
	allow_write_access(filp);
out_drop_write:
	mnt_drop_write_file(filp);
	return err;
}
EXPORT_SYMBOL_GPL(fsverity_ioctl_enable);
