Project import generated by Copybara.
GitOrigin-RevId: 0acb173e07e155358594d3ce7b5f19e91bb9fec3
diff --git a/fs/verity/enable.c b/fs/verity/enable.c
index d988e8c..eabc6ac 100644
--- a/fs/verity/enable.c
+++ b/fs/verity/enable.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Ioctl to enable verity on a file
+ * fs/verity/enable.c: ioctl to enable verity on a file
*
* Copyright 2019 Google LLC
*/
@@ -8,48 +8,18 @@
#include "fsverity_private.h"
#include <crypto/hash.h>
-#include <linux/backing-dev.h>
#include <linux/mount.h>
#include <linux/pagemap.h>
#include <linux/sched/signal.h>
#include <linux/uaccess.h>
-/*
- * Read a file data page for Merkle tree construction. Do aggressive readahead,
- * since we're sequentially reading the entire file.
- */
-static struct page *read_file_data_page(struct file *filp, pgoff_t index,
- struct file_ra_state *ra,
- unsigned long remaining_pages)
-{
- struct page *page;
-
- page = find_get_page_flags(filp->f_mapping, index, FGP_ACCESSED);
- if (!page || !PageUptodate(page)) {
- if (page)
- put_page(page);
- else
- page_cache_sync_readahead(filp->f_mapping, ra, filp,
- index, remaining_pages);
- page = read_mapping_page(filp->f_mapping, index, NULL);
- if (IS_ERR(page))
- return page;
- }
- if (PageReadahead(page))
- page_cache_async_readahead(filp->f_mapping, ra, filp, page,
- index, remaining_pages);
- return page;
-}
-
-static int build_merkle_tree_level(struct file *filp, unsigned int level,
+static int build_merkle_tree_level(struct inode *inode, unsigned int level,
u64 num_blocks_to_hash,
const struct merkle_tree_params *params,
u8 *pending_hashes,
struct ahash_request *req)
{
- struct inode *inode = file_inode(filp);
const struct fsverity_operations *vops = inode->i_sb->s_vop;
- struct file_ra_state ra = { 0 };
unsigned int pending_size = 0;
u64 dst_block_num;
u64 i;
@@ -66,8 +36,6 @@ static int build_merkle_tree_level(struct file *filp, unsigned int level,
dst_block_num = 0; /* unused */
}
- file_ra_state_init(&ra, filp->f_mapping);
-
for (i = 0; i < num_blocks_to_hash; i++) {
struct page *src_page;
@@ -77,8 +45,7 @@ static int build_merkle_tree_level(struct file *filp, unsigned int level,
if (level == 0) {
/* Leaf: hashing a data block */
- src_page = read_file_data_page(filp, i, &ra,
- num_blocks_to_hash - i);
+ src_page = read_mapping_page(inode->i_mapping, i, NULL);
if (IS_ERR(src_page)) {
err = PTR_ERR(src_page);
fsverity_err(inode,
@@ -87,14 +54,9 @@ static int build_merkle_tree_level(struct file *filp, unsigned int level,
return err;
}
} else {
- unsigned long num_ra_pages =
- min_t(unsigned long, num_blocks_to_hash - i,
- inode->i_sb->s_bdi->io_pages);
-
/* Non-leaf: hashing hash block from level below */
src_page = vops->read_merkle_tree_page(inode,
- params->level_start[level - 1] + i,
- num_ra_pages);
+ params->level_start[level - 1] + i);
if (IS_ERR(src_page)) {
err = PTR_ERR(src_page);
fsverity_err(inode,
@@ -141,18 +103,17 @@ static int build_merkle_tree_level(struct file *filp, unsigned int level,
}
/*
- * Build the Merkle tree for the given file using the given parameters, and
+ * Build the Merkle tree for the given inode 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,
+static int build_merkle_tree(struct inode *inode,
const struct merkle_tree_params *params,
u8 *root_hash)
{
- struct inode *inode = file_inode(filp);
u8 *pending_hashes;
struct ahash_request *req;
u64 blocks;
@@ -165,11 +126,9 @@ static int build_merkle_tree(struct file *filp,
return 0;
}
- /* This allocation never fails, since it's mempool-backed. */
- req = fsverity_alloc_hash_request(params->hash_alg, GFP_KERNEL);
-
pending_hashes = kmalloc(params->block_size, GFP_KERNEL);
- if (!pending_hashes)
+ req = ahash_request_alloc(params->hash_alg->tfm, GFP_KERNEL);
+ if (!pending_hashes || !req)
goto out;
/*
@@ -177,10 +136,10 @@ static int build_merkle_tree(struct file *filp,
* (level 0) and ascending to the root node (level 'num_levels - 1').
* Then at the end (level 'num_levels'), calculate the root hash.
*/
- blocks = ((u64)inode->i_size + params->block_size - 1) >>
+ blocks = (inode->i_size + params->block_size - 1) >>
params->log_blocksize;
for (level = 0; level <= params->num_levels; level++) {
- err = build_merkle_tree_level(filp, level, blocks, params,
+ err = build_merkle_tree_level(inode, level, blocks, params,
pending_hashes, req);
if (err)
goto out;
@@ -191,7 +150,7 @@ static int build_merkle_tree(struct file *filp,
err = 0;
out:
kfree(pending_hashes);
- fsverity_free_hash_request(params->hash_alg, req);
+ ahash_request_free(req);
return err;
}
@@ -216,7 +175,8 @@ static int enable_verity(struct file *filp,
/* Get the salt if the user provided one */
if (arg->salt_size &&
- copy_from_user(desc->salt, u64_to_user_ptr(arg->salt_ptr),
+ copy_from_user(desc->salt,
+ (const u8 __user *)(uintptr_t)arg->salt_ptr,
arg->salt_size)) {
err = -EFAULT;
goto out;
@@ -225,7 +185,8 @@ static int enable_verity(struct file *filp,
/* Get the signature if the user provided one */
if (arg->sig_size &&
- copy_from_user(desc->signature, u64_to_user_ptr(arg->sig_ptr),
+ copy_from_user(desc->signature,
+ (const u8 __user *)(uintptr_t)arg->sig_ptr,
arg->sig_size)) {
err = -EFAULT;
goto out;
@@ -266,7 +227,7 @@ static int enable_verity(struct file *filp,
*/
pr_debug("Building Merkle tree...\n");
BUILD_BUG_ON(sizeof(desc->root_hash) < FS_VERITY_MAX_DIGEST_SIZE);
- err = build_merkle_tree(filp, ¶ms, desc->root_hash);
+ err = build_merkle_tree(inode, ¶ms, desc->root_hash);
if (err) {
fsverity_err(inode, "Error %d building Merkle tree", err);
goto rollback;
@@ -329,8 +290,6 @@ static int enable_verity(struct file *filp,
/**
* 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.
@@ -398,9 +357,9 @@ int fsverity_ioctl_enable(struct file *filp, const void __user *uarg)
* Some pages of the file may have been evicted from pagecache after
* being used in the Merkle tree construction, then read into pagecache
* again by another process reading from the file concurrently. Since
- * these pages didn't undergo verification against the file digest which
- * fs-verity now claims to be enforcing, we have to wipe the pagecache
- * to ensure that all future reads are verified.
+ * these pages didn't undergo verification against the file measurement
+ * which fs-verity now claims to be enforcing, we have to wipe the
+ * pagecache to ensure that all future reads are verified.
*/
filemap_write_and_wait(inode->i_mapping);
invalidate_inode_pages2(inode->i_mapping);