13fda4c61SEric Biggers // SPDX-License-Identifier: GPL-2.0 23fda4c61SEric Biggers /* 33fda4c61SEric Biggers * fs/verity/enable.c: ioctl to enable verity on a file 43fda4c61SEric Biggers * 53fda4c61SEric Biggers * Copyright 2019 Google LLC 63fda4c61SEric Biggers */ 73fda4c61SEric Biggers 83fda4c61SEric Biggers #include "fsverity_private.h" 93fda4c61SEric Biggers 103fda4c61SEric Biggers #include <crypto/hash.h> 11fd39073dSEric Biggers #include <linux/backing-dev.h> 123fda4c61SEric Biggers #include <linux/mount.h> 133fda4c61SEric Biggers #include <linux/pagemap.h> 143fda4c61SEric Biggers #include <linux/sched/signal.h> 153fda4c61SEric Biggers #include <linux/uaccess.h> 163fda4c61SEric Biggers 17c22415d3SEric Biggers /* 18c22415d3SEric Biggers * Read a file data page for Merkle tree construction. Do aggressive readahead, 19c22415d3SEric Biggers * since we're sequentially reading the entire file. 20c22415d3SEric Biggers */ 21c22415d3SEric Biggers static struct page *read_file_data_page(struct file *filp, pgoff_t index, 22c22415d3SEric Biggers struct file_ra_state *ra, 23c22415d3SEric Biggers unsigned long remaining_pages) 24c22415d3SEric Biggers { 25c22415d3SEric Biggers struct page *page; 26c22415d3SEric Biggers 27c22415d3SEric Biggers page = find_get_page_flags(filp->f_mapping, index, FGP_ACCESSED); 28c22415d3SEric Biggers if (!page || !PageUptodate(page)) { 29c22415d3SEric Biggers if (page) 30c22415d3SEric Biggers put_page(page); 31c22415d3SEric Biggers else 32c22415d3SEric Biggers page_cache_sync_readahead(filp->f_mapping, ra, filp, 33c22415d3SEric Biggers index, remaining_pages); 34c22415d3SEric Biggers page = read_mapping_page(filp->f_mapping, index, NULL); 35c22415d3SEric Biggers if (IS_ERR(page)) 36c22415d3SEric Biggers return page; 37c22415d3SEric Biggers } 38c22415d3SEric Biggers if (PageReadahead(page)) 39c22415d3SEric Biggers page_cache_async_readahead(filp->f_mapping, ra, filp, page, 40c22415d3SEric Biggers index, remaining_pages); 41c22415d3SEric Biggers return page; 42c22415d3SEric Biggers } 43c22415d3SEric Biggers 44c22415d3SEric Biggers static int build_merkle_tree_level(struct file *filp, unsigned int level, 453fda4c61SEric Biggers u64 num_blocks_to_hash, 463fda4c61SEric Biggers const struct merkle_tree_params *params, 473fda4c61SEric Biggers u8 *pending_hashes, 483fda4c61SEric Biggers struct ahash_request *req) 493fda4c61SEric Biggers { 50c22415d3SEric Biggers struct inode *inode = file_inode(filp); 513fda4c61SEric Biggers const struct fsverity_operations *vops = inode->i_sb->s_vop; 52c22415d3SEric Biggers struct file_ra_state ra = { 0 }; 533fda4c61SEric Biggers unsigned int pending_size = 0; 543fda4c61SEric Biggers u64 dst_block_num; 553fda4c61SEric Biggers u64 i; 563fda4c61SEric Biggers int err; 573fda4c61SEric Biggers 583fda4c61SEric Biggers if (WARN_ON(params->block_size != PAGE_SIZE)) /* checked earlier too */ 593fda4c61SEric Biggers return -EINVAL; 603fda4c61SEric Biggers 613fda4c61SEric Biggers if (level < params->num_levels) { 623fda4c61SEric Biggers dst_block_num = params->level_start[level]; 633fda4c61SEric Biggers } else { 643fda4c61SEric Biggers if (WARN_ON(num_blocks_to_hash != 1)) 653fda4c61SEric Biggers return -EINVAL; 663fda4c61SEric Biggers dst_block_num = 0; /* unused */ 673fda4c61SEric Biggers } 683fda4c61SEric Biggers 69c22415d3SEric Biggers file_ra_state_init(&ra, filp->f_mapping); 70c22415d3SEric Biggers 713fda4c61SEric Biggers for (i = 0; i < num_blocks_to_hash; i++) { 723fda4c61SEric Biggers struct page *src_page; 733fda4c61SEric Biggers 743fda4c61SEric Biggers if ((pgoff_t)i % 10000 == 0 || i + 1 == num_blocks_to_hash) 753fda4c61SEric Biggers pr_debug("Hashing block %llu of %llu for level %u\n", 763fda4c61SEric Biggers i + 1, num_blocks_to_hash, level); 773fda4c61SEric Biggers 783fda4c61SEric Biggers if (level == 0) { 793fda4c61SEric Biggers /* Leaf: hashing a data block */ 80c22415d3SEric Biggers src_page = read_file_data_page(filp, i, &ra, 81c22415d3SEric Biggers num_blocks_to_hash - i); 823fda4c61SEric Biggers if (IS_ERR(src_page)) { 833fda4c61SEric Biggers err = PTR_ERR(src_page); 843fda4c61SEric Biggers fsverity_err(inode, 853fda4c61SEric Biggers "Error %d reading data page %llu", 863fda4c61SEric Biggers err, i); 873fda4c61SEric Biggers return err; 883fda4c61SEric Biggers } 893fda4c61SEric Biggers } else { 90fd39073dSEric Biggers unsigned long num_ra_pages = 91fd39073dSEric Biggers min_t(unsigned long, num_blocks_to_hash - i, 92fd39073dSEric Biggers inode->i_sb->s_bdi->io_pages); 93fd39073dSEric Biggers 943fda4c61SEric Biggers /* Non-leaf: hashing hash block from level below */ 953fda4c61SEric Biggers src_page = vops->read_merkle_tree_page(inode, 96fd39073dSEric Biggers params->level_start[level - 1] + i, 97fd39073dSEric Biggers num_ra_pages); 983fda4c61SEric Biggers if (IS_ERR(src_page)) { 993fda4c61SEric Biggers err = PTR_ERR(src_page); 1003fda4c61SEric Biggers fsverity_err(inode, 1013fda4c61SEric Biggers "Error %d reading Merkle tree page %llu", 1023fda4c61SEric Biggers err, params->level_start[level - 1] + i); 1033fda4c61SEric Biggers return err; 1043fda4c61SEric Biggers } 1053fda4c61SEric Biggers } 1063fda4c61SEric Biggers 1073fda4c61SEric Biggers err = fsverity_hash_page(params, inode, req, src_page, 1083fda4c61SEric Biggers &pending_hashes[pending_size]); 1093fda4c61SEric Biggers put_page(src_page); 1103fda4c61SEric Biggers if (err) 1113fda4c61SEric Biggers return err; 1123fda4c61SEric Biggers pending_size += params->digest_size; 1133fda4c61SEric Biggers 1143fda4c61SEric Biggers if (level == params->num_levels) /* Root hash? */ 1153fda4c61SEric Biggers return 0; 1163fda4c61SEric Biggers 1173fda4c61SEric Biggers if (pending_size + params->digest_size > params->block_size || 1183fda4c61SEric Biggers i + 1 == num_blocks_to_hash) { 1193fda4c61SEric Biggers /* Flush the pending hash block */ 1203fda4c61SEric Biggers memset(&pending_hashes[pending_size], 0, 1213fda4c61SEric Biggers params->block_size - pending_size); 1223fda4c61SEric Biggers err = vops->write_merkle_tree_block(inode, 1233fda4c61SEric Biggers pending_hashes, 1243fda4c61SEric Biggers dst_block_num, 1253fda4c61SEric Biggers params->log_blocksize); 1263fda4c61SEric Biggers if (err) { 1273fda4c61SEric Biggers fsverity_err(inode, 1283fda4c61SEric Biggers "Error %d writing Merkle tree block %llu", 1293fda4c61SEric Biggers err, dst_block_num); 1303fda4c61SEric Biggers return err; 1313fda4c61SEric Biggers } 1323fda4c61SEric Biggers dst_block_num++; 1333fda4c61SEric Biggers pending_size = 0; 1343fda4c61SEric Biggers } 1353fda4c61SEric Biggers 1363fda4c61SEric Biggers if (fatal_signal_pending(current)) 1373fda4c61SEric Biggers return -EINTR; 1383fda4c61SEric Biggers cond_resched(); 1393fda4c61SEric Biggers } 1403fda4c61SEric Biggers return 0; 1413fda4c61SEric Biggers } 1423fda4c61SEric Biggers 1433fda4c61SEric Biggers /* 144c22415d3SEric Biggers * Build the Merkle tree for the given file using the given parameters, and 1453fda4c61SEric Biggers * return the root hash in @root_hash. 1463fda4c61SEric Biggers * 1473fda4c61SEric Biggers * The tree is written to a filesystem-specific location as determined by the 1483fda4c61SEric Biggers * ->write_merkle_tree_block() method. However, the blocks that comprise the 1493fda4c61SEric Biggers * tree are the same for all filesystems. 1503fda4c61SEric Biggers */ 151c22415d3SEric Biggers static int build_merkle_tree(struct file *filp, 1523fda4c61SEric Biggers const struct merkle_tree_params *params, 1533fda4c61SEric Biggers u8 *root_hash) 1543fda4c61SEric Biggers { 155c22415d3SEric Biggers struct inode *inode = file_inode(filp); 1563fda4c61SEric Biggers u8 *pending_hashes; 1573fda4c61SEric Biggers struct ahash_request *req; 1583fda4c61SEric Biggers u64 blocks; 1593fda4c61SEric Biggers unsigned int level; 1603fda4c61SEric Biggers int err = -ENOMEM; 1613fda4c61SEric Biggers 1623fda4c61SEric Biggers if (inode->i_size == 0) { 1633fda4c61SEric Biggers /* Empty file is a special case; root hash is all 0's */ 1643fda4c61SEric Biggers memset(root_hash, 0, params->digest_size); 1653fda4c61SEric Biggers return 0; 1663fda4c61SEric Biggers } 1673fda4c61SEric Biggers 168439bea10SEric Biggers /* This allocation never fails, since it's mempool-backed. */ 169439bea10SEric Biggers req = fsverity_alloc_hash_request(params->hash_alg, GFP_KERNEL); 170439bea10SEric Biggers 1713fda4c61SEric Biggers pending_hashes = kmalloc(params->block_size, GFP_KERNEL); 172439bea10SEric Biggers if (!pending_hashes) 1733fda4c61SEric Biggers goto out; 1743fda4c61SEric Biggers 1753fda4c61SEric Biggers /* 1763fda4c61SEric Biggers * Build each level of the Merkle tree, starting at the leaf level 1773fda4c61SEric Biggers * (level 0) and ascending to the root node (level 'num_levels - 1'). 1783fda4c61SEric Biggers * Then at the end (level 'num_levels'), calculate the root hash. 1793fda4c61SEric Biggers */ 1803fda4c61SEric Biggers blocks = (inode->i_size + params->block_size - 1) >> 1813fda4c61SEric Biggers params->log_blocksize; 1823fda4c61SEric Biggers for (level = 0; level <= params->num_levels; level++) { 183c22415d3SEric Biggers err = build_merkle_tree_level(filp, level, blocks, params, 1843fda4c61SEric Biggers pending_hashes, req); 1853fda4c61SEric Biggers if (err) 1863fda4c61SEric Biggers goto out; 1873fda4c61SEric Biggers blocks = (blocks + params->hashes_per_block - 1) >> 1883fda4c61SEric Biggers params->log_arity; 1893fda4c61SEric Biggers } 1903fda4c61SEric Biggers memcpy(root_hash, pending_hashes, params->digest_size); 1913fda4c61SEric Biggers err = 0; 1923fda4c61SEric Biggers out: 1933fda4c61SEric Biggers kfree(pending_hashes); 194439bea10SEric Biggers fsverity_free_hash_request(params->hash_alg, req); 1953fda4c61SEric Biggers return err; 1963fda4c61SEric Biggers } 1973fda4c61SEric Biggers 1983fda4c61SEric Biggers static int enable_verity(struct file *filp, 1993fda4c61SEric Biggers const struct fsverity_enable_arg *arg) 2003fda4c61SEric Biggers { 2013fda4c61SEric Biggers struct inode *inode = file_inode(filp); 2023fda4c61SEric Biggers const struct fsverity_operations *vops = inode->i_sb->s_vop; 2033fda4c61SEric Biggers struct merkle_tree_params params = { }; 2043fda4c61SEric Biggers struct fsverity_descriptor *desc; 205432434c9SEric Biggers size_t desc_size = sizeof(*desc) + arg->sig_size; 2063fda4c61SEric Biggers struct fsverity_info *vi; 2073fda4c61SEric Biggers int err; 2083fda4c61SEric Biggers 2093fda4c61SEric Biggers /* Start initializing the fsverity_descriptor */ 2103fda4c61SEric Biggers desc = kzalloc(desc_size, GFP_KERNEL); 2113fda4c61SEric Biggers if (!desc) 2123fda4c61SEric Biggers return -ENOMEM; 2133fda4c61SEric Biggers desc->version = 1; 2143fda4c61SEric Biggers desc->hash_algorithm = arg->hash_algorithm; 2153fda4c61SEric Biggers desc->log_blocksize = ilog2(arg->block_size); 2163fda4c61SEric Biggers 2173fda4c61SEric Biggers /* Get the salt if the user provided one */ 2183fda4c61SEric Biggers if (arg->salt_size && 219da3a3da4SEric Biggers copy_from_user(desc->salt, u64_to_user_ptr(arg->salt_ptr), 2203fda4c61SEric Biggers arg->salt_size)) { 2213fda4c61SEric Biggers err = -EFAULT; 2223fda4c61SEric Biggers goto out; 2233fda4c61SEric Biggers } 2243fda4c61SEric Biggers desc->salt_size = arg->salt_size; 2253fda4c61SEric Biggers 226432434c9SEric Biggers /* Get the signature if the user provided one */ 227432434c9SEric Biggers if (arg->sig_size && 228da3a3da4SEric Biggers copy_from_user(desc->signature, u64_to_user_ptr(arg->sig_ptr), 229432434c9SEric Biggers arg->sig_size)) { 230432434c9SEric Biggers err = -EFAULT; 231432434c9SEric Biggers goto out; 232432434c9SEric Biggers } 233432434c9SEric Biggers desc->sig_size = cpu_to_le32(arg->sig_size); 234432434c9SEric Biggers 2353fda4c61SEric Biggers desc->data_size = cpu_to_le64(inode->i_size); 2363fda4c61SEric Biggers 2373fda4c61SEric Biggers /* Prepare the Merkle tree parameters */ 2383fda4c61SEric Biggers err = fsverity_init_merkle_tree_params(¶ms, inode, 2393fda4c61SEric Biggers arg->hash_algorithm, 2403fda4c61SEric Biggers desc->log_blocksize, 2413fda4c61SEric Biggers desc->salt, desc->salt_size); 2423fda4c61SEric Biggers if (err) 2433fda4c61SEric Biggers goto out; 2443fda4c61SEric Biggers 2453fda4c61SEric Biggers /* 2463fda4c61SEric Biggers * Start enabling verity on this file, serialized by the inode lock. 2473fda4c61SEric Biggers * Fail if verity is already enabled or is already being enabled. 2483fda4c61SEric Biggers */ 2493fda4c61SEric Biggers inode_lock(inode); 2503fda4c61SEric Biggers if (IS_VERITY(inode)) 2513fda4c61SEric Biggers err = -EEXIST; 2523fda4c61SEric Biggers else 2533fda4c61SEric Biggers err = vops->begin_enable_verity(filp); 2543fda4c61SEric Biggers inode_unlock(inode); 2553fda4c61SEric Biggers if (err) 2563fda4c61SEric Biggers goto out; 2573fda4c61SEric Biggers 2583fda4c61SEric Biggers /* 2593fda4c61SEric Biggers * Build the Merkle tree. Don't hold the inode lock during this, since 2603fda4c61SEric Biggers * on huge files this may take a very long time and we don't want to 2613fda4c61SEric Biggers * force unrelated syscalls like chown() to block forever. We don't 2623fda4c61SEric Biggers * need the inode lock here because deny_write_access() already prevents 2633fda4c61SEric Biggers * the file from being written to or truncated, and we still serialize 2643fda4c61SEric Biggers * ->begin_enable_verity() and ->end_enable_verity() using the inode 2653fda4c61SEric Biggers * lock and only allow one process to be here at a time on a given file. 2663fda4c61SEric Biggers */ 2673fda4c61SEric Biggers pr_debug("Building Merkle tree...\n"); 2683fda4c61SEric Biggers BUILD_BUG_ON(sizeof(desc->root_hash) < FS_VERITY_MAX_DIGEST_SIZE); 269c22415d3SEric Biggers err = build_merkle_tree(filp, ¶ms, desc->root_hash); 2703fda4c61SEric Biggers if (err) { 2713fda4c61SEric Biggers fsverity_err(inode, "Error %d building Merkle tree", err); 2723fda4c61SEric Biggers goto rollback; 2733fda4c61SEric Biggers } 2743fda4c61SEric Biggers pr_debug("Done building Merkle tree. Root hash is %s:%*phN\n", 2753fda4c61SEric Biggers params.hash_alg->name, params.digest_size, desc->root_hash); 2763fda4c61SEric Biggers 2773fda4c61SEric Biggers /* 2783fda4c61SEric Biggers * Create the fsverity_info. Don't bother trying to save work by 2793fda4c61SEric Biggers * reusing the merkle_tree_params from above. Instead, just create the 2803fda4c61SEric Biggers * fsverity_info from the fsverity_descriptor as if it were just loaded 2813fda4c61SEric Biggers * from disk. This is simpler, and it serves as an extra check that the 2823fda4c61SEric Biggers * metadata we're writing is valid before actually enabling verity. 2833fda4c61SEric Biggers */ 2843fda4c61SEric Biggers vi = fsverity_create_info(inode, desc, desc_size); 2853fda4c61SEric Biggers if (IS_ERR(vi)) { 2863fda4c61SEric Biggers err = PTR_ERR(vi); 2873fda4c61SEric Biggers goto rollback; 2883fda4c61SEric Biggers } 2893fda4c61SEric Biggers 290432434c9SEric Biggers if (arg->sig_size) 291432434c9SEric Biggers pr_debug("Storing a %u-byte PKCS#7 signature alongside the file\n", 292432434c9SEric Biggers arg->sig_size); 293432434c9SEric Biggers 2943fda4c61SEric Biggers /* 2953fda4c61SEric Biggers * Tell the filesystem to finish enabling verity on the file. 2963fda4c61SEric Biggers * Serialized with ->begin_enable_verity() by the inode lock. 2973fda4c61SEric Biggers */ 2983fda4c61SEric Biggers inode_lock(inode); 2993fda4c61SEric Biggers err = vops->end_enable_verity(filp, desc, desc_size, params.tree_size); 3003fda4c61SEric Biggers inode_unlock(inode); 3013fda4c61SEric Biggers if (err) { 3023fda4c61SEric Biggers fsverity_err(inode, "%ps() failed with err %d", 3033fda4c61SEric Biggers vops->end_enable_verity, err); 3043fda4c61SEric Biggers fsverity_free_info(vi); 3053fda4c61SEric Biggers } else if (WARN_ON(!IS_VERITY(inode))) { 3063fda4c61SEric Biggers err = -EINVAL; 3073fda4c61SEric Biggers fsverity_free_info(vi); 3083fda4c61SEric Biggers } else { 3093fda4c61SEric Biggers /* Successfully enabled verity */ 3103fda4c61SEric Biggers 3113fda4c61SEric Biggers /* 3123fda4c61SEric Biggers * Readers can start using ->i_verity_info immediately, so it 3133fda4c61SEric Biggers * can't be rolled back once set. So don't set it until just 3143fda4c61SEric Biggers * after the filesystem has successfully enabled verity. 3153fda4c61SEric Biggers */ 3163fda4c61SEric Biggers fsverity_set_info(inode, vi); 3173fda4c61SEric Biggers } 3183fda4c61SEric Biggers out: 3193fda4c61SEric Biggers kfree(params.hashstate); 3203fda4c61SEric Biggers kfree(desc); 3213fda4c61SEric Biggers return err; 3223fda4c61SEric Biggers 3233fda4c61SEric Biggers rollback: 3243fda4c61SEric Biggers inode_lock(inode); 3253fda4c61SEric Biggers (void)vops->end_enable_verity(filp, NULL, 0, params.tree_size); 3263fda4c61SEric Biggers inode_unlock(inode); 3273fda4c61SEric Biggers goto out; 3283fda4c61SEric Biggers } 3293fda4c61SEric Biggers 3303fda4c61SEric Biggers /** 3313fda4c61SEric Biggers * fsverity_ioctl_enable() - enable verity on a file 3323fda4c61SEric Biggers * 3333fda4c61SEric Biggers * Enable fs-verity on a file. See the "FS_IOC_ENABLE_VERITY" section of 3343fda4c61SEric Biggers * Documentation/filesystems/fsverity.rst for the documentation. 3353fda4c61SEric Biggers * 3363fda4c61SEric Biggers * Return: 0 on success, -errno on failure 3373fda4c61SEric Biggers */ 3383fda4c61SEric Biggers int fsverity_ioctl_enable(struct file *filp, const void __user *uarg) 3393fda4c61SEric Biggers { 3403fda4c61SEric Biggers struct inode *inode = file_inode(filp); 3413fda4c61SEric Biggers struct fsverity_enable_arg arg; 3423fda4c61SEric Biggers int err; 3433fda4c61SEric Biggers 3443fda4c61SEric Biggers if (copy_from_user(&arg, uarg, sizeof(arg))) 3453fda4c61SEric Biggers return -EFAULT; 3463fda4c61SEric Biggers 3473fda4c61SEric Biggers if (arg.version != 1) 3483fda4c61SEric Biggers return -EINVAL; 3493fda4c61SEric Biggers 3503fda4c61SEric Biggers if (arg.__reserved1 || 3513fda4c61SEric Biggers memchr_inv(arg.__reserved2, 0, sizeof(arg.__reserved2))) 3523fda4c61SEric Biggers return -EINVAL; 3533fda4c61SEric Biggers 3543fda4c61SEric Biggers if (arg.block_size != PAGE_SIZE) 3553fda4c61SEric Biggers return -EINVAL; 3563fda4c61SEric Biggers 357c593642cSPankaj Bharadiya if (arg.salt_size > sizeof_field(struct fsverity_descriptor, salt)) 3583fda4c61SEric Biggers return -EMSGSIZE; 3593fda4c61SEric Biggers 360432434c9SEric Biggers if (arg.sig_size > FS_VERITY_MAX_SIGNATURE_SIZE) 361432434c9SEric Biggers return -EMSGSIZE; 3623fda4c61SEric Biggers 3633fda4c61SEric Biggers /* 3643fda4c61SEric Biggers * Require a regular file with write access. But the actual fd must 3653fda4c61SEric Biggers * still be readonly so that we can lock out all writers. This is 3663fda4c61SEric Biggers * needed to guarantee that no writable fds exist to the file once it 3673fda4c61SEric Biggers * has verity enabled, and to stabilize the data being hashed. 3683fda4c61SEric Biggers */ 3693fda4c61SEric Biggers 3703fda4c61SEric Biggers err = inode_permission(inode, MAY_WRITE); 3713fda4c61SEric Biggers if (err) 3723fda4c61SEric Biggers return err; 3733fda4c61SEric Biggers 3743fda4c61SEric Biggers if (IS_APPEND(inode)) 3753fda4c61SEric Biggers return -EPERM; 3763fda4c61SEric Biggers 3773fda4c61SEric Biggers if (S_ISDIR(inode->i_mode)) 3783fda4c61SEric Biggers return -EISDIR; 3793fda4c61SEric Biggers 3803fda4c61SEric Biggers if (!S_ISREG(inode->i_mode)) 3813fda4c61SEric Biggers return -EINVAL; 3823fda4c61SEric Biggers 3833fda4c61SEric Biggers err = mnt_want_write_file(filp); 3843fda4c61SEric Biggers if (err) /* -EROFS */ 3853fda4c61SEric Biggers return err; 3863fda4c61SEric Biggers 3873fda4c61SEric Biggers err = deny_write_access(filp); 3883fda4c61SEric Biggers if (err) /* -ETXTBSY */ 3893fda4c61SEric Biggers goto out_drop_write; 3903fda4c61SEric Biggers 3913fda4c61SEric Biggers err = enable_verity(filp, &arg); 3923fda4c61SEric Biggers if (err) 3933fda4c61SEric Biggers goto out_allow_write_access; 3943fda4c61SEric Biggers 3953fda4c61SEric Biggers /* 3963fda4c61SEric Biggers * Some pages of the file may have been evicted from pagecache after 3973fda4c61SEric Biggers * being used in the Merkle tree construction, then read into pagecache 3983fda4c61SEric Biggers * again by another process reading from the file concurrently. Since 3993fda4c61SEric Biggers * these pages didn't undergo verification against the file measurement 4003fda4c61SEric Biggers * which fs-verity now claims to be enforcing, we have to wipe the 4013fda4c61SEric Biggers * pagecache to ensure that all future reads are verified. 4023fda4c61SEric Biggers */ 4033fda4c61SEric Biggers filemap_write_and_wait(inode->i_mapping); 4043fda4c61SEric Biggers invalidate_inode_pages2(inode->i_mapping); 4053fda4c61SEric Biggers 4063fda4c61SEric Biggers /* 4073fda4c61SEric Biggers * allow_write_access() is needed to pair with deny_write_access(). 4083fda4c61SEric Biggers * Regardless, the filesystem won't allow writing to verity files. 4093fda4c61SEric Biggers */ 4103fda4c61SEric Biggers out_allow_write_access: 4113fda4c61SEric Biggers allow_write_access(filp); 4123fda4c61SEric Biggers out_drop_write: 4133fda4c61SEric Biggers mnt_drop_write_file(filp); 4143fda4c61SEric Biggers return err; 4153fda4c61SEric Biggers } 4163fda4c61SEric Biggers EXPORT_SYMBOL_GPL(fsverity_ioctl_enable); 417