13fda4c61SEric Biggers // SPDX-License-Identifier: GPL-2.0 23fda4c61SEric Biggers /* 37bf765ddSEric Biggers * 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 <linux/mount.h> 113fda4c61SEric Biggers #include <linux/pagemap.h> 123fda4c61SEric Biggers #include <linux/sched/signal.h> 133fda4c61SEric Biggers #include <linux/uaccess.h> 143fda4c61SEric Biggers 15*56124d6cSEric Biggers struct block_buffer { 16*56124d6cSEric Biggers u32 filled; 17*56124d6cSEric Biggers u8 *data; 18*56124d6cSEric Biggers }; 19c22415d3SEric Biggers 20*56124d6cSEric Biggers /* Hash a block, writing the result to the next level's pending block buffer. */ 21*56124d6cSEric Biggers static int hash_one_block(struct inode *inode, 223fda4c61SEric Biggers const struct merkle_tree_params *params, 23*56124d6cSEric Biggers struct ahash_request *req, struct block_buffer *cur) 243fda4c61SEric Biggers { 25*56124d6cSEric Biggers struct block_buffer *next = cur + 1; 263fda4c61SEric Biggers int err; 273fda4c61SEric Biggers 28*56124d6cSEric Biggers /* Zero-pad the block if it's shorter than the block size. */ 29*56124d6cSEric Biggers memset(&cur->data[cur->filled], 0, params->block_size - cur->filled); 303fda4c61SEric Biggers 31*56124d6cSEric Biggers err = fsverity_hash_block(params, inode, req, virt_to_page(cur->data), 32*56124d6cSEric Biggers offset_in_page(cur->data), 33*56124d6cSEric Biggers &next->data[next->filled]); 343fda4c61SEric Biggers if (err) 353fda4c61SEric Biggers return err; 36*56124d6cSEric Biggers next->filled += params->digest_size; 37*56124d6cSEric Biggers cur->filled = 0; 383fda4c61SEric Biggers return 0; 39*56124d6cSEric Biggers } 403fda4c61SEric Biggers 41*56124d6cSEric Biggers static int write_merkle_tree_block(struct inode *inode, const u8 *buf, 42*56124d6cSEric Biggers unsigned long index, 43*56124d6cSEric Biggers const struct merkle_tree_params *params) 44*56124d6cSEric Biggers { 45*56124d6cSEric Biggers u64 pos = (u64)index << params->log_blocksize; 46*56124d6cSEric Biggers int err; 47*56124d6cSEric Biggers 48*56124d6cSEric Biggers err = inode->i_sb->s_vop->write_merkle_tree_block(inode, buf, pos, 4972ea15f0SEric Biggers params->block_size); 50*56124d6cSEric Biggers if (err) 51*56124d6cSEric Biggers fsverity_err(inode, "Error %d writing Merkle tree block %lu", 52*56124d6cSEric Biggers err, index); 533fda4c61SEric Biggers return err; 543fda4c61SEric Biggers } 553fda4c61SEric Biggers 563fda4c61SEric Biggers /* 57c22415d3SEric Biggers * Build the Merkle tree for the given file using the given parameters, and 583fda4c61SEric Biggers * return the root hash in @root_hash. 593fda4c61SEric Biggers * 603fda4c61SEric Biggers * The tree is written to a filesystem-specific location as determined by the 613fda4c61SEric Biggers * ->write_merkle_tree_block() method. However, the blocks that comprise the 623fda4c61SEric Biggers * tree are the same for all filesystems. 633fda4c61SEric Biggers */ 64c22415d3SEric Biggers static int build_merkle_tree(struct file *filp, 653fda4c61SEric Biggers const struct merkle_tree_params *params, 663fda4c61SEric Biggers u8 *root_hash) 673fda4c61SEric Biggers { 68c22415d3SEric Biggers struct inode *inode = file_inode(filp); 69*56124d6cSEric Biggers const u64 data_size = inode->i_size; 70*56124d6cSEric Biggers const int num_levels = params->num_levels; 713fda4c61SEric Biggers struct ahash_request *req; 72*56124d6cSEric Biggers struct block_buffer _buffers[1 + FS_VERITY_MAX_LEVELS + 1] = {}; 73*56124d6cSEric Biggers struct block_buffer *buffers = &_buffers[1]; 74*56124d6cSEric Biggers unsigned long level_offset[FS_VERITY_MAX_LEVELS]; 75*56124d6cSEric Biggers int level; 76*56124d6cSEric Biggers u64 offset; 77*56124d6cSEric Biggers int err; 783fda4c61SEric Biggers 79*56124d6cSEric Biggers if (data_size == 0) { 803fda4c61SEric Biggers /* Empty file is a special case; root hash is all 0's */ 813fda4c61SEric Biggers memset(root_hash, 0, params->digest_size); 823fda4c61SEric Biggers return 0; 833fda4c61SEric Biggers } 843fda4c61SEric Biggers 85439bea10SEric Biggers /* This allocation never fails, since it's mempool-backed. */ 86439bea10SEric Biggers req = fsverity_alloc_hash_request(params->hash_alg, GFP_KERNEL); 87439bea10SEric Biggers 883fda4c61SEric Biggers /* 89*56124d6cSEric Biggers * Allocate the block buffers. Buffer "-1" is for data blocks. 90*56124d6cSEric Biggers * Buffers 0 <= level < num_levels are for the actual tree levels. 91*56124d6cSEric Biggers * Buffer 'num_levels' is for the root hash. 923fda4c61SEric Biggers */ 93*56124d6cSEric Biggers for (level = -1; level < num_levels; level++) { 94*56124d6cSEric Biggers buffers[level].data = kzalloc(params->block_size, GFP_KERNEL); 95*56124d6cSEric Biggers if (!buffers[level].data) { 96*56124d6cSEric Biggers err = -ENOMEM; 97*56124d6cSEric Biggers goto out; 98*56124d6cSEric Biggers } 99*56124d6cSEric Biggers } 100*56124d6cSEric Biggers buffers[num_levels].data = root_hash; 101*56124d6cSEric Biggers 102*56124d6cSEric Biggers BUILD_BUG_ON(sizeof(level_offset) != sizeof(params->level_start)); 103*56124d6cSEric Biggers memcpy(level_offset, params->level_start, sizeof(level_offset)); 104*56124d6cSEric Biggers 105*56124d6cSEric Biggers /* Hash each data block, also hashing the tree blocks as they fill up */ 106*56124d6cSEric Biggers for (offset = 0; offset < data_size; offset += params->block_size) { 107*56124d6cSEric Biggers ssize_t bytes_read; 108*56124d6cSEric Biggers loff_t pos = offset; 109*56124d6cSEric Biggers 110*56124d6cSEric Biggers buffers[-1].filled = min_t(u64, params->block_size, 111*56124d6cSEric Biggers data_size - offset); 112*56124d6cSEric Biggers bytes_read = __kernel_read(filp, buffers[-1].data, 113*56124d6cSEric Biggers buffers[-1].filled, &pos); 114*56124d6cSEric Biggers if (bytes_read < 0) { 115*56124d6cSEric Biggers err = bytes_read; 116*56124d6cSEric Biggers fsverity_err(inode, "Error %d reading file data", err); 117*56124d6cSEric Biggers goto out; 118*56124d6cSEric Biggers } 119*56124d6cSEric Biggers if (bytes_read != buffers[-1].filled) { 120*56124d6cSEric Biggers err = -EINVAL; 121*56124d6cSEric Biggers fsverity_err(inode, "Short read of file data"); 122*56124d6cSEric Biggers goto out; 123*56124d6cSEric Biggers } 124*56124d6cSEric Biggers err = hash_one_block(inode, params, req, &buffers[-1]); 1253fda4c61SEric Biggers if (err) 1263fda4c61SEric Biggers goto out; 127*56124d6cSEric Biggers for (level = 0; level < num_levels; level++) { 128*56124d6cSEric Biggers if (buffers[level].filled + params->digest_size <= 129*56124d6cSEric Biggers params->block_size) { 130*56124d6cSEric Biggers /* Next block at @level isn't full yet */ 131*56124d6cSEric Biggers break; 1323fda4c61SEric Biggers } 133*56124d6cSEric Biggers /* Next block at @level is full */ 134*56124d6cSEric Biggers 135*56124d6cSEric Biggers err = hash_one_block(inode, params, req, 136*56124d6cSEric Biggers &buffers[level]); 137*56124d6cSEric Biggers if (err) 138*56124d6cSEric Biggers goto out; 139*56124d6cSEric Biggers err = write_merkle_tree_block(inode, 140*56124d6cSEric Biggers buffers[level].data, 141*56124d6cSEric Biggers level_offset[level], 142*56124d6cSEric Biggers params); 143*56124d6cSEric Biggers if (err) 144*56124d6cSEric Biggers goto out; 145*56124d6cSEric Biggers level_offset[level]++; 146*56124d6cSEric Biggers } 147*56124d6cSEric Biggers if (fatal_signal_pending(current)) { 148*56124d6cSEric Biggers err = -EINTR; 149*56124d6cSEric Biggers goto out; 150*56124d6cSEric Biggers } 151*56124d6cSEric Biggers cond_resched(); 152*56124d6cSEric Biggers } 153*56124d6cSEric Biggers /* Finish all nonempty pending tree blocks. */ 154*56124d6cSEric Biggers for (level = 0; level < num_levels; level++) { 155*56124d6cSEric Biggers if (buffers[level].filled != 0) { 156*56124d6cSEric Biggers err = hash_one_block(inode, params, req, 157*56124d6cSEric Biggers &buffers[level]); 158*56124d6cSEric Biggers if (err) 159*56124d6cSEric Biggers goto out; 160*56124d6cSEric Biggers err = write_merkle_tree_block(inode, 161*56124d6cSEric Biggers buffers[level].data, 162*56124d6cSEric Biggers level_offset[level], 163*56124d6cSEric Biggers params); 164*56124d6cSEric Biggers if (err) 165*56124d6cSEric Biggers goto out; 166*56124d6cSEric Biggers } 167*56124d6cSEric Biggers } 168*56124d6cSEric Biggers /* The root hash was filled by the last call to hash_one_block(). */ 169*56124d6cSEric Biggers if (WARN_ON(buffers[num_levels].filled != params->digest_size)) { 170*56124d6cSEric Biggers err = -EINVAL; 171*56124d6cSEric Biggers goto out; 172*56124d6cSEric Biggers } 1733fda4c61SEric Biggers err = 0; 1743fda4c61SEric Biggers out: 175*56124d6cSEric Biggers for (level = -1; level < num_levels; level++) 176*56124d6cSEric Biggers kfree(buffers[level].data); 177439bea10SEric Biggers fsverity_free_hash_request(params->hash_alg, req); 1783fda4c61SEric Biggers return err; 1793fda4c61SEric Biggers } 1803fda4c61SEric Biggers 1813fda4c61SEric Biggers static int enable_verity(struct file *filp, 1823fda4c61SEric Biggers const struct fsverity_enable_arg *arg) 1833fda4c61SEric Biggers { 1843fda4c61SEric Biggers struct inode *inode = file_inode(filp); 1853fda4c61SEric Biggers const struct fsverity_operations *vops = inode->i_sb->s_vop; 1863fda4c61SEric Biggers struct merkle_tree_params params = { }; 1873fda4c61SEric Biggers struct fsverity_descriptor *desc; 188e6af1bb0SZhang Jianhua size_t desc_size = struct_size(desc, signature, arg->sig_size); 1893fda4c61SEric Biggers struct fsverity_info *vi; 1903fda4c61SEric Biggers int err; 1913fda4c61SEric Biggers 1923fda4c61SEric Biggers /* Start initializing the fsverity_descriptor */ 1933fda4c61SEric Biggers desc = kzalloc(desc_size, GFP_KERNEL); 1943fda4c61SEric Biggers if (!desc) 1953fda4c61SEric Biggers return -ENOMEM; 1963fda4c61SEric Biggers desc->version = 1; 1973fda4c61SEric Biggers desc->hash_algorithm = arg->hash_algorithm; 1983fda4c61SEric Biggers desc->log_blocksize = ilog2(arg->block_size); 1993fda4c61SEric Biggers 2003fda4c61SEric Biggers /* Get the salt if the user provided one */ 2013fda4c61SEric Biggers if (arg->salt_size && 202da3a3da4SEric Biggers copy_from_user(desc->salt, u64_to_user_ptr(arg->salt_ptr), 2033fda4c61SEric Biggers arg->salt_size)) { 2043fda4c61SEric Biggers err = -EFAULT; 2053fda4c61SEric Biggers goto out; 2063fda4c61SEric Biggers } 2073fda4c61SEric Biggers desc->salt_size = arg->salt_size; 2083fda4c61SEric Biggers 209432434c9SEric Biggers /* Get the signature if the user provided one */ 210432434c9SEric Biggers if (arg->sig_size && 211da3a3da4SEric Biggers copy_from_user(desc->signature, u64_to_user_ptr(arg->sig_ptr), 212432434c9SEric Biggers arg->sig_size)) { 213432434c9SEric Biggers err = -EFAULT; 214432434c9SEric Biggers goto out; 215432434c9SEric Biggers } 216432434c9SEric Biggers desc->sig_size = cpu_to_le32(arg->sig_size); 217432434c9SEric Biggers 2183fda4c61SEric Biggers desc->data_size = cpu_to_le64(inode->i_size); 2193fda4c61SEric Biggers 2203fda4c61SEric Biggers /* Prepare the Merkle tree parameters */ 2213fda4c61SEric Biggers err = fsverity_init_merkle_tree_params(¶ms, inode, 2223fda4c61SEric Biggers arg->hash_algorithm, 2233fda4c61SEric Biggers desc->log_blocksize, 2243fda4c61SEric Biggers desc->salt, desc->salt_size); 2253fda4c61SEric Biggers if (err) 2263fda4c61SEric Biggers goto out; 2273fda4c61SEric Biggers 2283fda4c61SEric Biggers /* 2293fda4c61SEric Biggers * Start enabling verity on this file, serialized by the inode lock. 2303fda4c61SEric Biggers * Fail if verity is already enabled or is already being enabled. 2313fda4c61SEric Biggers */ 2323fda4c61SEric Biggers inode_lock(inode); 2333fda4c61SEric Biggers if (IS_VERITY(inode)) 2343fda4c61SEric Biggers err = -EEXIST; 2353fda4c61SEric Biggers else 2363fda4c61SEric Biggers err = vops->begin_enable_verity(filp); 2373fda4c61SEric Biggers inode_unlock(inode); 2383fda4c61SEric Biggers if (err) 2393fda4c61SEric Biggers goto out; 2403fda4c61SEric Biggers 2413fda4c61SEric Biggers /* 2423fda4c61SEric Biggers * Build the Merkle tree. Don't hold the inode lock during this, since 2433fda4c61SEric Biggers * on huge files this may take a very long time and we don't want to 2443fda4c61SEric Biggers * force unrelated syscalls like chown() to block forever. We don't 2453fda4c61SEric Biggers * need the inode lock here because deny_write_access() already prevents 2463fda4c61SEric Biggers * the file from being written to or truncated, and we still serialize 2473fda4c61SEric Biggers * ->begin_enable_verity() and ->end_enable_verity() using the inode 2483fda4c61SEric Biggers * lock and only allow one process to be here at a time on a given file. 2493fda4c61SEric Biggers */ 2503fda4c61SEric Biggers BUILD_BUG_ON(sizeof(desc->root_hash) < FS_VERITY_MAX_DIGEST_SIZE); 251c22415d3SEric Biggers err = build_merkle_tree(filp, ¶ms, desc->root_hash); 2523fda4c61SEric Biggers if (err) { 2533fda4c61SEric Biggers fsverity_err(inode, "Error %d building Merkle tree", err); 2543fda4c61SEric Biggers goto rollback; 2553fda4c61SEric Biggers } 2563fda4c61SEric Biggers 2573fda4c61SEric Biggers /* 2583fda4c61SEric Biggers * Create the fsverity_info. Don't bother trying to save work by 2593fda4c61SEric Biggers * reusing the merkle_tree_params from above. Instead, just create the 2603fda4c61SEric Biggers * fsverity_info from the fsverity_descriptor as if it were just loaded 2613fda4c61SEric Biggers * from disk. This is simpler, and it serves as an extra check that the 2623fda4c61SEric Biggers * metadata we're writing is valid before actually enabling verity. 2633fda4c61SEric Biggers */ 264b0487edeSZhang Jianhua vi = fsverity_create_info(inode, desc); 2653fda4c61SEric Biggers if (IS_ERR(vi)) { 2663fda4c61SEric Biggers err = PTR_ERR(vi); 2673fda4c61SEric Biggers goto rollback; 2683fda4c61SEric Biggers } 2693fda4c61SEric Biggers 2703fda4c61SEric Biggers /* 2713fda4c61SEric Biggers * Tell the filesystem to finish enabling verity on the file. 2723fda4c61SEric Biggers * Serialized with ->begin_enable_verity() by the inode lock. 2733fda4c61SEric Biggers */ 2743fda4c61SEric Biggers inode_lock(inode); 2753fda4c61SEric Biggers err = vops->end_enable_verity(filp, desc, desc_size, params.tree_size); 2763fda4c61SEric Biggers inode_unlock(inode); 2773fda4c61SEric Biggers if (err) { 2783fda4c61SEric Biggers fsverity_err(inode, "%ps() failed with err %d", 2793fda4c61SEric Biggers vops->end_enable_verity, err); 2803fda4c61SEric Biggers fsverity_free_info(vi); 2813fda4c61SEric Biggers } else if (WARN_ON(!IS_VERITY(inode))) { 2823fda4c61SEric Biggers err = -EINVAL; 2833fda4c61SEric Biggers fsverity_free_info(vi); 2843fda4c61SEric Biggers } else { 2853fda4c61SEric Biggers /* Successfully enabled verity */ 2863fda4c61SEric Biggers 2873fda4c61SEric Biggers /* 2883fda4c61SEric Biggers * Readers can start using ->i_verity_info immediately, so it 2893fda4c61SEric Biggers * can't be rolled back once set. So don't set it until just 2903fda4c61SEric Biggers * after the filesystem has successfully enabled verity. 2913fda4c61SEric Biggers */ 2923fda4c61SEric Biggers fsverity_set_info(inode, vi); 2933fda4c61SEric Biggers } 2943fda4c61SEric Biggers out: 2953fda4c61SEric Biggers kfree(params.hashstate); 2963fda4c61SEric Biggers kfree(desc); 2973fda4c61SEric Biggers return err; 2983fda4c61SEric Biggers 2993fda4c61SEric Biggers rollback: 3003fda4c61SEric Biggers inode_lock(inode); 3013fda4c61SEric Biggers (void)vops->end_enable_verity(filp, NULL, 0, params.tree_size); 3023fda4c61SEric Biggers inode_unlock(inode); 3033fda4c61SEric Biggers goto out; 3043fda4c61SEric Biggers } 3053fda4c61SEric Biggers 3063fda4c61SEric Biggers /** 3073fda4c61SEric Biggers * fsverity_ioctl_enable() - enable verity on a file 3086377a38bSEric Biggers * @filp: file to enable verity on 3096377a38bSEric Biggers * @uarg: user pointer to fsverity_enable_arg 3103fda4c61SEric Biggers * 3113fda4c61SEric Biggers * Enable fs-verity on a file. See the "FS_IOC_ENABLE_VERITY" section of 3123fda4c61SEric Biggers * Documentation/filesystems/fsverity.rst for the documentation. 3133fda4c61SEric Biggers * 3143fda4c61SEric Biggers * Return: 0 on success, -errno on failure 3153fda4c61SEric Biggers */ 3163fda4c61SEric Biggers int fsverity_ioctl_enable(struct file *filp, const void __user *uarg) 3173fda4c61SEric Biggers { 3183fda4c61SEric Biggers struct inode *inode = file_inode(filp); 3193fda4c61SEric Biggers struct fsverity_enable_arg arg; 3203fda4c61SEric Biggers int err; 3213fda4c61SEric Biggers 3223fda4c61SEric Biggers if (copy_from_user(&arg, uarg, sizeof(arg))) 3233fda4c61SEric Biggers return -EFAULT; 3243fda4c61SEric Biggers 3253fda4c61SEric Biggers if (arg.version != 1) 3263fda4c61SEric Biggers return -EINVAL; 3273fda4c61SEric Biggers 3283fda4c61SEric Biggers if (arg.__reserved1 || 3293fda4c61SEric Biggers memchr_inv(arg.__reserved2, 0, sizeof(arg.__reserved2))) 3303fda4c61SEric Biggers return -EINVAL; 3313fda4c61SEric Biggers 332*56124d6cSEric Biggers if (!is_power_of_2(arg.block_size)) 3333fda4c61SEric Biggers return -EINVAL; 3343fda4c61SEric Biggers 335c593642cSPankaj Bharadiya if (arg.salt_size > sizeof_field(struct fsverity_descriptor, salt)) 3363fda4c61SEric Biggers return -EMSGSIZE; 3373fda4c61SEric Biggers 338432434c9SEric Biggers if (arg.sig_size > FS_VERITY_MAX_SIGNATURE_SIZE) 339432434c9SEric Biggers return -EMSGSIZE; 3403fda4c61SEric Biggers 3413fda4c61SEric Biggers /* 3423fda4c61SEric Biggers * Require a regular file with write access. But the actual fd must 3433fda4c61SEric Biggers * still be readonly so that we can lock out all writers. This is 3443fda4c61SEric Biggers * needed to guarantee that no writable fds exist to the file once it 3453fda4c61SEric Biggers * has verity enabled, and to stabilize the data being hashed. 3463fda4c61SEric Biggers */ 3473fda4c61SEric Biggers 34802f92b38SChristian Brauner err = file_permission(filp, MAY_WRITE); 3493fda4c61SEric Biggers if (err) 3503fda4c61SEric Biggers return err; 3513fda4c61SEric Biggers 3523fda4c61SEric Biggers if (IS_APPEND(inode)) 3533fda4c61SEric Biggers return -EPERM; 3543fda4c61SEric Biggers 3553fda4c61SEric Biggers if (S_ISDIR(inode->i_mode)) 3563fda4c61SEric Biggers return -EISDIR; 3573fda4c61SEric Biggers 3583fda4c61SEric Biggers if (!S_ISREG(inode->i_mode)) 3593fda4c61SEric Biggers return -EINVAL; 3603fda4c61SEric Biggers 3613fda4c61SEric Biggers err = mnt_want_write_file(filp); 3623fda4c61SEric Biggers if (err) /* -EROFS */ 3633fda4c61SEric Biggers return err; 3643fda4c61SEric Biggers 3653fda4c61SEric Biggers err = deny_write_access(filp); 3663fda4c61SEric Biggers if (err) /* -ETXTBSY */ 3673fda4c61SEric Biggers goto out_drop_write; 3683fda4c61SEric Biggers 3693fda4c61SEric Biggers err = enable_verity(filp, &arg); 3703fda4c61SEric Biggers if (err) 3713fda4c61SEric Biggers goto out_allow_write_access; 3723fda4c61SEric Biggers 3733fda4c61SEric Biggers /* 3743fda4c61SEric Biggers * Some pages of the file may have been evicted from pagecache after 3753fda4c61SEric Biggers * being used in the Merkle tree construction, then read into pagecache 3763fda4c61SEric Biggers * again by another process reading from the file concurrently. Since 377ed45e201SEric Biggers * these pages didn't undergo verification against the file digest which 378ed45e201SEric Biggers * fs-verity now claims to be enforcing, we have to wipe the pagecache 379ed45e201SEric Biggers * to ensure that all future reads are verified. 3803fda4c61SEric Biggers */ 3813fda4c61SEric Biggers filemap_write_and_wait(inode->i_mapping); 3823fda4c61SEric Biggers invalidate_inode_pages2(inode->i_mapping); 3833fda4c61SEric Biggers 3843fda4c61SEric Biggers /* 3853fda4c61SEric Biggers * allow_write_access() is needed to pair with deny_write_access(). 3863fda4c61SEric Biggers * Regardless, the filesystem won't allow writing to verity files. 3873fda4c61SEric Biggers */ 3883fda4c61SEric Biggers out_allow_write_access: 3893fda4c61SEric Biggers allow_write_access(filp); 3903fda4c61SEric Biggers out_drop_write: 3913fda4c61SEric Biggers mnt_drop_write_file(filp); 3923fda4c61SEric Biggers return err; 3933fda4c61SEric Biggers } 3943fda4c61SEric Biggers EXPORT_SYMBOL_GPL(fsverity_ioctl_enable); 395