// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2020 Google LLC
 */

/*
 * fs-verity integration into incfs
 *
 * Since incfs has its own merkle tree implementation, most of fs/verity/ is not
 * needed. incfs also only needs to support the case where
 * CONFIG_FS_VERITY_BUILTIN_SIGNATURES=n. Therefore, the integration consists of
 * the following modifications:
 *
 * 1. Add the (optional) verity signature to the incfs file format. (Not really
 *    needed anymore, but this is kept around since this is the behavior of
 *    fs/verity/ even when CONFIG_FS_VERITY_BUILTIN_SIGNATURES=n.)
 * 2. Add a pointer to the digest of the fs-verity descriptor struct to the
 *    data_file struct that incfs attaches to each file inode.
 * 3. Add the following ioclts:
 *  - FS_IOC_ENABLE_VERITY
 *  - FS_IOC_GETFLAGS
 *  - FS_IOC_MEASURE_VERITY
 * 4. When FS_IOC_ENABLE_VERITY is called on a non-verity file, the
 *    fs-verity descriptor struct is populated and digested. Then the S_VERITY
 *    flag is set and the xattr incfs.verity is set. If the signature is
 *    non-NULL, an INCFS_MD_VERITY_SIGNATURE is added to the backing file
 *    containing the signature.
 * 5. When a file with an incfs.verity xattr's inode is initialized, the
 *    inode’s S_VERITY flag is set.
 * 6. When a file with the S_VERITY flag set on its inode is opened, the
 *    data_file is checked for its verity digest. If the file doesn’t have a
 *    digest, the file’s digest is calculated as above, checked, and set, or the
 *    open is denied if it is not valid.
 * 7. FS_IOC_GETFLAGS simply returns the value of the S_VERITY flag
 * 8. FS_IOC_MEASURE_VERITY simply returns the cached digest
 * 9. The final complication is that if FS_IOC_ENABLE_VERITY is called on a file
 *    which doesn’t have a merkle tree, the merkle tree is calculated before the
 *    rest of the process is completed.
 */

#include <crypto/hash.h>
#include <crypto/sha2.h>
#include <linux/fsverity.h>
#include <linux/mount.h>

#include "verity.h"

#include "data_mgmt.h"
#include "format.h"
#include "integrity.h"
#include "vfs.h"

#define FS_VERITY_MAX_SIGNATURE_SIZE	16128

static int incfs_get_root_hash(struct file *filp, u8 *root_hash)
{
	struct data_file *df = get_incfs_data_file(filp);

	if (!df)
		return -EINVAL;

	memcpy(root_hash, df->df_hash_tree->root_hash,
	       df->df_hash_tree->alg->digest_size);

	return 0;
}

static int incfs_end_enable_verity(struct file *filp, u8 *sig, size_t sig_size)
{
	struct inode *inode = file_inode(filp);
	struct mem_range signature = {
		.data = sig,
		.len = sig_size,
	};
	struct data_file *df = get_incfs_data_file(filp);
	struct backing_file_context *bfc;
	int error;
	struct incfs_df_verity_signature *vs = NULL;
	loff_t offset;

	if (!df || !df->df_backing_file_context)
		return -EFSCORRUPTED;

	if (sig) {
		vs = kzalloc(sizeof(*vs), GFP_NOFS);
		if (!vs)
			return -ENOMEM;
	}

	bfc = df->df_backing_file_context;
	error = mutex_lock_interruptible(&bfc->bc_mutex);
	if (error)
		goto out;

	error = incfs_write_verity_signature_to_backing_file(bfc, signature,
							     &offset);
	mutex_unlock(&bfc->bc_mutex);
	if (error)
		goto out;

	/*
	 * Set verity xattr so we can set S_VERITY without opening backing file
	 */
	error = vfs_setxattr(&nop_mnt_idmap, bfc->bc_file->f_path.dentry,
			     INCFS_XATTR_VERITY_NAME, NULL, 0, XATTR_CREATE);
	if (error) {
		pr_warn("incfs: error setting verity xattr: %d\n", error);
		goto out;
	}

	if (sig) {
		*vs = (struct incfs_df_verity_signature) {
			.size = signature.len,
			.offset = offset,
		};

		df->df_verity_signature = vs;
		vs = NULL;
	}

	inode_set_flags(inode, S_VERITY, S_VERITY);

out:
	kfree(vs);
	return error;
}

static int incfs_compute_file_digest(struct incfs_hash_alg *alg,
				struct fsverity_descriptor *desc,
				u8 *digest)
{
	SHASH_DESC_ON_STACK(d, alg->shash);

	d->tfm = alg->shash;
	return crypto_shash_digest(d, (u8 *)desc, sizeof(*desc), digest);
}

static enum incfs_hash_tree_algorithm incfs_convert_fsverity_hash_alg(
								int hash_alg)
{
	switch (hash_alg) {
	case FS_VERITY_HASH_ALG_SHA256:
		return INCFS_HASH_TREE_SHA256;
	default:
		return -EINVAL;
	}
}

static struct mem_range incfs_get_verity_digest(struct inode *inode)
{
	struct inode_info *node = get_incfs_node(inode);
	struct data_file *df;
	struct mem_range verity_file_digest;

	if (!node) {
		pr_warn("Invalid inode\n");
		return range(NULL, 0);
	}

	df = node->n_file;

	/*
	 * Pairs with the cmpxchg_release() in incfs_set_verity_digest().
	 * I.e., another task may publish ->df_verity_file_digest concurrently,
	 * executing a RELEASE barrier.  We need to use smp_load_acquire() here
	 * to safely ACQUIRE the memory the other task published.
	 */
	verity_file_digest.data = smp_load_acquire(
					&df->df_verity_file_digest.data);
	verity_file_digest.len = df->df_verity_file_digest.len;
	return verity_file_digest;
}

static void incfs_set_verity_digest(struct inode *inode,
				     struct mem_range verity_file_digest)
{
	struct inode_info *node = get_incfs_node(inode);
	struct data_file *df;

	if (!node) {
		pr_warn("Invalid inode\n");
		kfree(verity_file_digest.data);
		return;
	}

	df = node->n_file;
	df->df_verity_file_digest.len = verity_file_digest.len;

	/*
	 * Multiple tasks may race to set ->df_verity_file_digest.data, so use
	 * cmpxchg_release().  This pairs with the smp_load_acquire() in
	 * incfs_get_verity_digest().  I.e., here we publish
	 * ->df_verity_file_digest.data, with a RELEASE barrier so that other
	 * tasks can ACQUIRE it.
	 */
	if (cmpxchg_release(&df->df_verity_file_digest.data, NULL,
			    verity_file_digest.data) != NULL)
		/* Lost the race, so free the file_digest we allocated. */
		kfree(verity_file_digest.data);
}

/* Calculate the digest of the fsverity_descriptor. */
static struct mem_range incfs_calc_verity_digest_from_desc(
					const struct inode *inode,
					struct fsverity_descriptor *desc)
{
	enum incfs_hash_tree_algorithm incfs_hash_alg;
	struct mem_range verity_file_digest;
	int err;
	struct incfs_hash_alg *hash_alg;

	incfs_hash_alg = incfs_convert_fsverity_hash_alg(desc->hash_algorithm);
	if (incfs_hash_alg < 0)
		return range(ERR_PTR(incfs_hash_alg), 0);

	hash_alg = incfs_get_hash_alg(incfs_hash_alg);
	if (IS_ERR(hash_alg))
		return range((u8 *)hash_alg, 0);

	verity_file_digest = range(kzalloc(hash_alg->digest_size, GFP_KERNEL),
				   hash_alg->digest_size);
	if (!verity_file_digest.data)
		return range(ERR_PTR(-ENOMEM), 0);

	err = incfs_compute_file_digest(hash_alg, desc,
					verity_file_digest.data);
	if (err) {
		pr_err("Error %d computing file digest", err);
		kfree(verity_file_digest.data);
		return range(ERR_PTR(err), 0);
	}
	pr_debug("Computed file digest: %s:%*phN\n",
		 hash_alg->name, (int) verity_file_digest.len,
		 verity_file_digest.data);
	return verity_file_digest;
}

static struct fsverity_descriptor *incfs_get_fsverity_descriptor(
					struct file *filp, int hash_algorithm)
{
	struct inode *inode = file_inode(filp);
	struct fsverity_descriptor *desc = kzalloc(sizeof(*desc), GFP_KERNEL);
	int err;

	if (!desc)
		return ERR_PTR(-ENOMEM);

	*desc = (struct fsverity_descriptor) {
		.version = 1,
		.hash_algorithm = hash_algorithm,
		.log_blocksize = ilog2(INCFS_DATA_FILE_BLOCK_SIZE),
		.data_size = cpu_to_le64(inode->i_size),
	};

	err = incfs_get_root_hash(filp, desc->root_hash);
	if (err) {
		kfree(desc);
		return ERR_PTR(err);
	}

	return desc;
}

static struct mem_range incfs_calc_verity_digest(
					struct inode *inode, struct file *filp,
					int hash_algorithm)
{
	struct fsverity_descriptor *desc = incfs_get_fsverity_descriptor(filp,
							hash_algorithm);
	struct mem_range verity_file_digest;

	if (IS_ERR(desc))
		return range((u8 *)desc, 0);
	verity_file_digest = incfs_calc_verity_digest_from_desc(inode, desc);
	kfree(desc);
	return verity_file_digest;
}

static int incfs_build_merkle_tree(struct file *f, struct data_file *df,
			     struct backing_file_context *bfc,
			     struct mtree *hash_tree, loff_t hash_offset,
			     struct incfs_hash_alg *alg, struct mem_range hash)
{
	int error = 0;
	int limit, lvl, i, result;
	struct mem_range buf = {.len = INCFS_DATA_FILE_BLOCK_SIZE};
	struct mem_range tmp = {.len = 2 * INCFS_DATA_FILE_BLOCK_SIZE};

	buf.data = (u8 *)kzalloc(buf.len, GFP_NOFS);
	tmp.data = (u8 *)kzalloc(tmp.len, GFP_NOFS);
	if (!buf.data || !tmp.data) {
		error = -ENOMEM;
		goto out;
	}

	/*
	 * lvl - 1 is the level we are reading, lvl the level we are writing
	 * lvl == -1 means actual blocks
	 * lvl == hash_tree->depth means root hash
	 */
	limit = df->df_data_block_count;
	for (lvl = 0; lvl <= hash_tree->depth; lvl++) {
		for (i = 0; i < limit; ++i) {
			loff_t hash_level_offset;
			struct mem_range partial_buf = buf;

			if (lvl == 0)
				result = incfs_read_data_file_block(partial_buf,
						f, i, tmp, NULL, NULL);
			else {
				hash_level_offset = hash_offset +
				       hash_tree->hash_level_suboffset[lvl - 1];

				result = incfs_kread(bfc, partial_buf.data,
						partial_buf.len,
						hash_level_offset + i *
						INCFS_DATA_FILE_BLOCK_SIZE);
			}

			if (result < 0) {
				error = result;
				goto out;
			}

			partial_buf.len = result;
			error = incfs_calc_digest(alg, partial_buf, hash);
			if (error)
				goto out;

			/*
			 * last level - only one hash to take and it is stored
			 * in the incfs signature record
			 */
			if (lvl == hash_tree->depth)
				break;

			hash_level_offset = hash_offset +
				hash_tree->hash_level_suboffset[lvl];

			result = incfs_kwrite(bfc, hash.data, hash.len,
					hash_level_offset + hash.len * i);

			if (result < 0) {
				error = result;
				goto out;
			}

			if (result != hash.len) {
				error = -EIO;
				goto out;
			}
		}
		limit = DIV_ROUND_UP(limit,
				     INCFS_DATA_FILE_BLOCK_SIZE / hash.len);
	}

out:
	kfree(tmp.data);
	kfree(buf.data);
	return error;
}

/*
 * incfs files have a signature record that is separate from the
 * verity_signature record. The signature record does not actually contain a
 * signature, rather it contains the size/offset of the hash tree, and a binary
 * blob which contains the root hash and potentially a signature.
 *
 * If the file was created with a signature record, then this function simply
 * returns.
 *
 * Otherwise it will create a signature record with a minimal binary blob as
 * defined by the structure below, create space for the hash tree and then
 * populate it using incfs_build_merkle_tree
 */
static int incfs_add_signature_record(struct file *f)
{
	/* See incfs_parse_signature */
	struct {
		__le32 version;
		__le32 size_of_hash_info_section;
		struct {
			__le32 hash_algorithm;
			u8 log2_blocksize;
			__le32 salt_size;
			u8 salt[0];
			__le32 hash_size;
			u8 root_hash[32];
		} __packed hash_section;
		__le32 size_of_signing_info_section;
		u8 signing_info_section[0];
	} __packed sig = {
		.version = cpu_to_le32(INCFS_SIGNATURE_VERSION),
		.size_of_hash_info_section =
			cpu_to_le32(sizeof(sig.hash_section)),
		.hash_section = {
			.hash_algorithm = cpu_to_le32(INCFS_HASH_TREE_SHA256),
			.log2_blocksize = ilog2(INCFS_DATA_FILE_BLOCK_SIZE),
			.hash_size = cpu_to_le32(SHA256_DIGEST_SIZE),
		},
	};

	struct data_file *df = get_incfs_data_file(f);
	struct mtree *hash_tree = NULL;
	struct backing_file_context *bfc;
	int error;
	loff_t hash_offset, sig_offset;
	struct incfs_hash_alg *alg = incfs_get_hash_alg(INCFS_HASH_TREE_SHA256);
	u8 hash_buf[INCFS_MAX_HASH_SIZE];
	int hash_size = alg->digest_size;
	struct mem_range hash = range(hash_buf, hash_size);
	int result;
	struct incfs_df_signature *signature = NULL;

	if (!df)
		return -EINVAL;

	if (df->df_header_flags & INCFS_FILE_MAPPED)
		return -EINVAL;

	/* Already signed? */
	if (df->df_signature && df->df_hash_tree)
		return 0;

	if (df->df_signature || df->df_hash_tree)
		return -EFSCORRUPTED;

	/* Add signature metadata record to file */
	hash_tree = incfs_alloc_mtree(range((u8 *)&sig, sizeof(sig)),
				      df->df_data_block_count);
	if (IS_ERR(hash_tree))
		return PTR_ERR(hash_tree);

	bfc = df->df_backing_file_context;
	if (!bfc) {
		error = -EFSCORRUPTED;
		goto out;
	}

	error = mutex_lock_interruptible(&bfc->bc_mutex);
	if (error)
		goto out;

	error = incfs_write_signature_to_backing_file(bfc,
				range((u8 *)&sig, sizeof(sig)),
				hash_tree->hash_tree_area_size,
				&hash_offset, &sig_offset);
	mutex_unlock(&bfc->bc_mutex);
	if (error)
		goto out;

	/* Populate merkle tree */
	error = incfs_build_merkle_tree(f, df, bfc, hash_tree, hash_offset, alg,
				  hash);
	if (error)
		goto out;

	/* Update signature metadata record */
	memcpy(sig.hash_section.root_hash, hash.data, alg->digest_size);
	result = incfs_kwrite(bfc, &sig, sizeof(sig), sig_offset);
	if (result < 0) {
		error = result;
		goto out;
	}

	if (result != sizeof(sig)) {
		error = -EIO;
		goto out;
	}

	/* Update in-memory records */
	memcpy(hash_tree->root_hash, hash.data, alg->digest_size);
	signature = kzalloc(sizeof(*signature), GFP_NOFS);
	if (!signature) {
		error = -ENOMEM;
		goto out;
	}
	*signature = (struct incfs_df_signature) {
		.hash_offset = hash_offset,
		.hash_size = hash_tree->hash_tree_area_size,
		.sig_offset = sig_offset,
		.sig_size = sizeof(sig),
	};
	df->df_signature = signature;
	signature = NULL;

	/*
	 * Use memory barrier to prevent readpage seeing the hash tree until
	 * it's fully there
	 */
	smp_store_release(&df->df_hash_tree, hash_tree);
	hash_tree = NULL;

out:
	kfree(signature);
	kfree(hash_tree);
	return error;
}

static int incfs_enable_verity(struct file *filp,
			 const struct fsverity_enable_arg *arg)
{
	struct inode *inode = file_inode(filp);
	struct data_file *df = get_incfs_data_file(filp);
	u8 *signature = NULL;
	struct mem_range verity_file_digest = range(NULL, 0);
	int err;

	if (!df)
		return -EFSCORRUPTED;

	err = mutex_lock_interruptible(&df->df_enable_verity);
	if (err)
		return err;

	if (IS_VERITY(inode)) {
		err = -EEXIST;
		goto out;
	}

	err = incfs_add_signature_record(filp);
	if (err)
		goto out;

	/* Get the signature if the user provided one */
	if (arg->sig_size) {
		signature = memdup_user(u64_to_user_ptr(arg->sig_ptr),
					arg->sig_size);
		if (IS_ERR(signature)) {
			err = PTR_ERR(signature);
			signature = NULL;
			goto out;
		}
	}

	verity_file_digest = incfs_calc_verity_digest(inode, filp,
					arg->hash_algorithm);
	if (IS_ERR(verity_file_digest.data)) {
		err = PTR_ERR(verity_file_digest.data);
		verity_file_digest.data = NULL;
		goto out;
	}

	err = incfs_end_enable_verity(filp, signature, arg->sig_size);
	if (err)
		goto out;

	/* Successfully enabled verity */
	incfs_set_verity_digest(inode, verity_file_digest);
	verity_file_digest.data = NULL;
out:
	mutex_unlock(&df->df_enable_verity);
	kfree(signature);
	kfree(verity_file_digest.data);
	if (err)
		pr_err("%s failed with err %d\n", __func__, err);
	return err;
}

int incfs_ioctl_enable_verity(struct file *filp, const void __user *uarg)
{
	struct inode *inode = file_inode(filp);
	struct fsverity_enable_arg arg;

	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 (arg.hash_algorithm != FS_VERITY_HASH_ALG_SHA256)
		return -EINVAL;

	if (arg.block_size != PAGE_SIZE)
		return -EINVAL;

	if (arg.salt_size)
		return -EINVAL;

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

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

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

	return incfs_enable_verity(filp, &arg);
}

static u8 *incfs_get_verity_signature(struct file *filp, size_t *sig_size)
{
	struct data_file *df = get_incfs_data_file(filp);
	struct incfs_df_verity_signature *vs;
	u8 *signature;
	int res;

	if (!df || !df->df_backing_file_context)
		return ERR_PTR(-EFSCORRUPTED);

	vs = df->df_verity_signature;
	if (!vs) {
		*sig_size = 0;
		return NULL;
	}

	if (!vs->size) {
		*sig_size = 0;
		return ERR_PTR(-EFSCORRUPTED);
	}

	signature = kzalloc(vs->size, GFP_KERNEL);
	if (!signature)
		return ERR_PTR(-ENOMEM);

	res = incfs_kread(df->df_backing_file_context,
			  signature, vs->size, vs->offset);

	if (res < 0)
		goto err_out;

	if (res != vs->size) {
		res = -EINVAL;
		goto err_out;
	}

	*sig_size = vs->size;
	return signature;

err_out:
	kfree(signature);
	return ERR_PTR(res);
}

/* Ensure data_file->df_verity_file_digest is populated */
static int ensure_verity_info(struct inode *inode, struct file *filp)
{
	struct mem_range verity_file_digest;

	/* See if this file's verity file digest is already cached */
	verity_file_digest = incfs_get_verity_digest(inode);
	if (verity_file_digest.data)
		return 0;

	verity_file_digest = incfs_calc_verity_digest(inode, filp,
						     FS_VERITY_HASH_ALG_SHA256);
	if (IS_ERR(verity_file_digest.data))
		return PTR_ERR(verity_file_digest.data);

	incfs_set_verity_digest(inode, verity_file_digest);
	return 0;
}

/**
 * incfs_fsverity_file_open() - prepare to open a file that may be
 * verity-enabled
 * @inode: the inode being opened
 * @filp: the struct file being set up
 *
 * When opening a verity file, set up data_file->df_verity_file_digest if not
 * already done. Note that incfs does not allow opening for writing, so there is
 * no need for that check.
 *
 * Return: 0 on success, -errno on failure
 */
int incfs_fsverity_file_open(struct inode *inode, struct file *filp)
{
	if (IS_VERITY(inode))
		return ensure_verity_info(inode, filp);

	return 0;
}

int incfs_ioctl_measure_verity(struct file *filp, void __user *_uarg)
{
	struct inode *inode = file_inode(filp);
	struct mem_range verity_file_digest = incfs_get_verity_digest(inode);
	struct fsverity_digest __user *uarg = _uarg;
	struct fsverity_digest arg;

	if (!verity_file_digest.data || !verity_file_digest.len)
		return -ENODATA; /* not a verity file */

	/*
	 * The user specifies the digest_size their buffer has space for; we can
	 * return the digest if it fits in the available space.  We write back
	 * the actual size, which may be shorter than the user-specified size.
	 */

	if (get_user(arg.digest_size, &uarg->digest_size))
		return -EFAULT;
	if (arg.digest_size < verity_file_digest.len)
		return -EOVERFLOW;

	memset(&arg, 0, sizeof(arg));
	arg.digest_algorithm = FS_VERITY_HASH_ALG_SHA256;
	arg.digest_size = verity_file_digest.len;

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

	if (copy_to_user(uarg->digest, verity_file_digest.data,
			 verity_file_digest.len))
		return -EFAULT;

	return 0;
}

static int incfs_read_merkle_tree(struct file *filp, void __user *buf,
				  u64 start_offset, int length)
{
	struct mem_range tmp_buf;
	size_t offset;
	int retval = 0;
	int err = 0;
	struct data_file *df = get_incfs_data_file(filp);

	if (!df)
		return -EINVAL;

	tmp_buf = (struct mem_range) {
		.data = kzalloc(INCFS_DATA_FILE_BLOCK_SIZE, GFP_NOFS),
		.len = INCFS_DATA_FILE_BLOCK_SIZE,
	};
	if (!tmp_buf.data)
		return -ENOMEM;

	for (offset = start_offset; offset < start_offset + length;
	     offset += tmp_buf.len) {
		err = incfs_read_merkle_tree_blocks(tmp_buf, df, offset);

		if (err < 0)
			break;

		if (err != tmp_buf.len)
			break;

		if (copy_to_user(buf, tmp_buf.data, tmp_buf.len))
			break;

		buf += tmp_buf.len;
		retval += tmp_buf.len;
	}

	kfree(tmp_buf.data);
	return retval ? retval : err;
}

static int incfs_read_descriptor(struct file *filp,
				 void __user *buf, u64 offset, int length)
{
	int err;
	struct fsverity_descriptor *desc = incfs_get_fsverity_descriptor(filp,
						FS_VERITY_HASH_ALG_SHA256);

	if (IS_ERR(desc))
		return PTR_ERR(desc);
	length = min_t(u64, length, sizeof(*desc));
	err = copy_to_user(buf, desc, length);
	kfree(desc);
	return err ? err : length;
}

static int incfs_read_signature(struct file *filp,
				void __user *buf, u64 offset, int length)
{
	size_t sig_size;
	static u8 *signature;
	int err;

	signature = incfs_get_verity_signature(filp, &sig_size);
	if (IS_ERR(signature))
		return PTR_ERR(signature);

	if (!signature)
		return -ENODATA;

	length = min_t(u64, length, sig_size);
	err = copy_to_user(buf, signature, length);
	kfree(signature);
	return err ? err : length;
}

int incfs_ioctl_read_verity_metadata(struct file *filp,
				     const void __user *uarg)
{
	struct fsverity_read_metadata_arg arg;
	int length;
	void __user *buf;

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

	if (arg.__reserved)
		return -EINVAL;

	/* offset + length must not overflow. */
	if (arg.offset + arg.length < arg.offset)
		return -EINVAL;

	/* Ensure that the return value will fit in INT_MAX. */
	length = min_t(u64, arg.length, INT_MAX);

	buf = u64_to_user_ptr(arg.buf_ptr);

	switch (arg.metadata_type) {
	case FS_VERITY_METADATA_TYPE_MERKLE_TREE:
		return incfs_read_merkle_tree(filp, buf, arg.offset, length);
	case FS_VERITY_METADATA_TYPE_DESCRIPTOR:
		return incfs_read_descriptor(filp, buf, arg.offset, length);
	case FS_VERITY_METADATA_TYPE_SIGNATURE:
		return incfs_read_signature(filp, buf, arg.offset, length);
	default:
		return -EINVAL;
	}
}
