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> 113fda4c61SEric Biggers #include <linux/mount.h> 123fda4c61SEric Biggers #include <linux/pagemap.h> 133fda4c61SEric Biggers #include <linux/sched/signal.h> 143fda4c61SEric Biggers #include <linux/uaccess.h> 153fda4c61SEric Biggers 163fda4c61SEric Biggers static int build_merkle_tree_level(struct inode *inode, unsigned int level, 173fda4c61SEric Biggers u64 num_blocks_to_hash, 183fda4c61SEric Biggers const struct merkle_tree_params *params, 193fda4c61SEric Biggers u8 *pending_hashes, 203fda4c61SEric Biggers struct ahash_request *req) 213fda4c61SEric Biggers { 223fda4c61SEric Biggers const struct fsverity_operations *vops = inode->i_sb->s_vop; 233fda4c61SEric Biggers unsigned int pending_size = 0; 243fda4c61SEric Biggers u64 dst_block_num; 253fda4c61SEric Biggers u64 i; 263fda4c61SEric Biggers int err; 273fda4c61SEric Biggers 283fda4c61SEric Biggers if (WARN_ON(params->block_size != PAGE_SIZE)) /* checked earlier too */ 293fda4c61SEric Biggers return -EINVAL; 303fda4c61SEric Biggers 313fda4c61SEric Biggers if (level < params->num_levels) { 323fda4c61SEric Biggers dst_block_num = params->level_start[level]; 333fda4c61SEric Biggers } else { 343fda4c61SEric Biggers if (WARN_ON(num_blocks_to_hash != 1)) 353fda4c61SEric Biggers return -EINVAL; 363fda4c61SEric Biggers dst_block_num = 0; /* unused */ 373fda4c61SEric Biggers } 383fda4c61SEric Biggers 393fda4c61SEric Biggers for (i = 0; i < num_blocks_to_hash; i++) { 403fda4c61SEric Biggers struct page *src_page; 413fda4c61SEric Biggers 423fda4c61SEric Biggers if ((pgoff_t)i % 10000 == 0 || i + 1 == num_blocks_to_hash) 433fda4c61SEric Biggers pr_debug("Hashing block %llu of %llu for level %u\n", 443fda4c61SEric Biggers i + 1, num_blocks_to_hash, level); 453fda4c61SEric Biggers 463fda4c61SEric Biggers if (level == 0) { 473fda4c61SEric Biggers /* Leaf: hashing a data block */ 483fda4c61SEric Biggers src_page = read_mapping_page(inode->i_mapping, i, NULL); 493fda4c61SEric Biggers if (IS_ERR(src_page)) { 503fda4c61SEric Biggers err = PTR_ERR(src_page); 513fda4c61SEric Biggers fsverity_err(inode, 523fda4c61SEric Biggers "Error %d reading data page %llu", 533fda4c61SEric Biggers err, i); 543fda4c61SEric Biggers return err; 553fda4c61SEric Biggers } 563fda4c61SEric Biggers } else { 573fda4c61SEric Biggers /* Non-leaf: hashing hash block from level below */ 583fda4c61SEric Biggers src_page = vops->read_merkle_tree_page(inode, 593fda4c61SEric Biggers params->level_start[level - 1] + i); 603fda4c61SEric Biggers if (IS_ERR(src_page)) { 613fda4c61SEric Biggers err = PTR_ERR(src_page); 623fda4c61SEric Biggers fsverity_err(inode, 633fda4c61SEric Biggers "Error %d reading Merkle tree page %llu", 643fda4c61SEric Biggers err, params->level_start[level - 1] + i); 653fda4c61SEric Biggers return err; 663fda4c61SEric Biggers } 673fda4c61SEric Biggers } 683fda4c61SEric Biggers 693fda4c61SEric Biggers err = fsverity_hash_page(params, inode, req, src_page, 703fda4c61SEric Biggers &pending_hashes[pending_size]); 713fda4c61SEric Biggers put_page(src_page); 723fda4c61SEric Biggers if (err) 733fda4c61SEric Biggers return err; 743fda4c61SEric Biggers pending_size += params->digest_size; 753fda4c61SEric Biggers 763fda4c61SEric Biggers if (level == params->num_levels) /* Root hash? */ 773fda4c61SEric Biggers return 0; 783fda4c61SEric Biggers 793fda4c61SEric Biggers if (pending_size + params->digest_size > params->block_size || 803fda4c61SEric Biggers i + 1 == num_blocks_to_hash) { 813fda4c61SEric Biggers /* Flush the pending hash block */ 823fda4c61SEric Biggers memset(&pending_hashes[pending_size], 0, 833fda4c61SEric Biggers params->block_size - pending_size); 843fda4c61SEric Biggers err = vops->write_merkle_tree_block(inode, 853fda4c61SEric Biggers pending_hashes, 863fda4c61SEric Biggers dst_block_num, 873fda4c61SEric Biggers params->log_blocksize); 883fda4c61SEric Biggers if (err) { 893fda4c61SEric Biggers fsverity_err(inode, 903fda4c61SEric Biggers "Error %d writing Merkle tree block %llu", 913fda4c61SEric Biggers err, dst_block_num); 923fda4c61SEric Biggers return err; 933fda4c61SEric Biggers } 943fda4c61SEric Biggers dst_block_num++; 953fda4c61SEric Biggers pending_size = 0; 963fda4c61SEric Biggers } 973fda4c61SEric Biggers 983fda4c61SEric Biggers if (fatal_signal_pending(current)) 993fda4c61SEric Biggers return -EINTR; 1003fda4c61SEric Biggers cond_resched(); 1013fda4c61SEric Biggers } 1023fda4c61SEric Biggers return 0; 1033fda4c61SEric Biggers } 1043fda4c61SEric Biggers 1053fda4c61SEric Biggers /* 1063fda4c61SEric Biggers * Build the Merkle tree for the given inode using the given parameters, and 1073fda4c61SEric Biggers * return the root hash in @root_hash. 1083fda4c61SEric Biggers * 1093fda4c61SEric Biggers * The tree is written to a filesystem-specific location as determined by the 1103fda4c61SEric Biggers * ->write_merkle_tree_block() method. However, the blocks that comprise the 1113fda4c61SEric Biggers * tree are the same for all filesystems. 1123fda4c61SEric Biggers */ 1133fda4c61SEric Biggers static int build_merkle_tree(struct inode *inode, 1143fda4c61SEric Biggers const struct merkle_tree_params *params, 1153fda4c61SEric Biggers u8 *root_hash) 1163fda4c61SEric Biggers { 1173fda4c61SEric Biggers u8 *pending_hashes; 1183fda4c61SEric Biggers struct ahash_request *req; 1193fda4c61SEric Biggers u64 blocks; 1203fda4c61SEric Biggers unsigned int level; 1213fda4c61SEric Biggers int err = -ENOMEM; 1223fda4c61SEric Biggers 1233fda4c61SEric Biggers if (inode->i_size == 0) { 1243fda4c61SEric Biggers /* Empty file is a special case; root hash is all 0's */ 1253fda4c61SEric Biggers memset(root_hash, 0, params->digest_size); 1263fda4c61SEric Biggers return 0; 1273fda4c61SEric Biggers } 1283fda4c61SEric Biggers 1293fda4c61SEric Biggers pending_hashes = kmalloc(params->block_size, GFP_KERNEL); 1303fda4c61SEric Biggers req = ahash_request_alloc(params->hash_alg->tfm, GFP_KERNEL); 1313fda4c61SEric Biggers if (!pending_hashes || !req) 1323fda4c61SEric Biggers goto out; 1333fda4c61SEric Biggers 1343fda4c61SEric Biggers /* 1353fda4c61SEric Biggers * Build each level of the Merkle tree, starting at the leaf level 1363fda4c61SEric Biggers * (level 0) and ascending to the root node (level 'num_levels - 1'). 1373fda4c61SEric Biggers * Then at the end (level 'num_levels'), calculate the root hash. 1383fda4c61SEric Biggers */ 1393fda4c61SEric Biggers blocks = (inode->i_size + params->block_size - 1) >> 1403fda4c61SEric Biggers params->log_blocksize; 1413fda4c61SEric Biggers for (level = 0; level <= params->num_levels; level++) { 1423fda4c61SEric Biggers err = build_merkle_tree_level(inode, level, blocks, params, 1433fda4c61SEric Biggers pending_hashes, req); 1443fda4c61SEric Biggers if (err) 1453fda4c61SEric Biggers goto out; 1463fda4c61SEric Biggers blocks = (blocks + params->hashes_per_block - 1) >> 1473fda4c61SEric Biggers params->log_arity; 1483fda4c61SEric Biggers } 1493fda4c61SEric Biggers memcpy(root_hash, pending_hashes, params->digest_size); 1503fda4c61SEric Biggers err = 0; 1513fda4c61SEric Biggers out: 1523fda4c61SEric Biggers kfree(pending_hashes); 1533fda4c61SEric Biggers ahash_request_free(req); 1543fda4c61SEric Biggers return err; 1553fda4c61SEric Biggers } 1563fda4c61SEric Biggers 1573fda4c61SEric Biggers static int enable_verity(struct file *filp, 1583fda4c61SEric Biggers const struct fsverity_enable_arg *arg) 1593fda4c61SEric Biggers { 1603fda4c61SEric Biggers struct inode *inode = file_inode(filp); 1613fda4c61SEric Biggers const struct fsverity_operations *vops = inode->i_sb->s_vop; 1623fda4c61SEric Biggers struct merkle_tree_params params = { }; 1633fda4c61SEric Biggers struct fsverity_descriptor *desc; 164432434c9SEric Biggers size_t desc_size = sizeof(*desc) + arg->sig_size; 1653fda4c61SEric Biggers struct fsverity_info *vi; 1663fda4c61SEric Biggers int err; 1673fda4c61SEric Biggers 1683fda4c61SEric Biggers /* Start initializing the fsverity_descriptor */ 1693fda4c61SEric Biggers desc = kzalloc(desc_size, GFP_KERNEL); 1703fda4c61SEric Biggers if (!desc) 1713fda4c61SEric Biggers return -ENOMEM; 1723fda4c61SEric Biggers desc->version = 1; 1733fda4c61SEric Biggers desc->hash_algorithm = arg->hash_algorithm; 1743fda4c61SEric Biggers desc->log_blocksize = ilog2(arg->block_size); 1753fda4c61SEric Biggers 1763fda4c61SEric Biggers /* Get the salt if the user provided one */ 1773fda4c61SEric Biggers if (arg->salt_size && 1783fda4c61SEric Biggers copy_from_user(desc->salt, 1793fda4c61SEric Biggers (const u8 __user *)(uintptr_t)arg->salt_ptr, 1803fda4c61SEric Biggers arg->salt_size)) { 1813fda4c61SEric Biggers err = -EFAULT; 1823fda4c61SEric Biggers goto out; 1833fda4c61SEric Biggers } 1843fda4c61SEric Biggers desc->salt_size = arg->salt_size; 1853fda4c61SEric Biggers 186432434c9SEric Biggers /* Get the signature if the user provided one */ 187432434c9SEric Biggers if (arg->sig_size && 188432434c9SEric Biggers copy_from_user(desc->signature, 189432434c9SEric Biggers (const u8 __user *)(uintptr_t)arg->sig_ptr, 190432434c9SEric Biggers arg->sig_size)) { 191432434c9SEric Biggers err = -EFAULT; 192432434c9SEric Biggers goto out; 193432434c9SEric Biggers } 194432434c9SEric Biggers desc->sig_size = cpu_to_le32(arg->sig_size); 195432434c9SEric Biggers 1963fda4c61SEric Biggers desc->data_size = cpu_to_le64(inode->i_size); 1973fda4c61SEric Biggers 1983fda4c61SEric Biggers /* Prepare the Merkle tree parameters */ 1993fda4c61SEric Biggers err = fsverity_init_merkle_tree_params(¶ms, inode, 2003fda4c61SEric Biggers arg->hash_algorithm, 2013fda4c61SEric Biggers desc->log_blocksize, 2023fda4c61SEric Biggers desc->salt, desc->salt_size); 2033fda4c61SEric Biggers if (err) 2043fda4c61SEric Biggers goto out; 2053fda4c61SEric Biggers 2063fda4c61SEric Biggers /* 2073fda4c61SEric Biggers * Start enabling verity on this file, serialized by the inode lock. 2083fda4c61SEric Biggers * Fail if verity is already enabled or is already being enabled. 2093fda4c61SEric Biggers */ 2103fda4c61SEric Biggers inode_lock(inode); 2113fda4c61SEric Biggers if (IS_VERITY(inode)) 2123fda4c61SEric Biggers err = -EEXIST; 2133fda4c61SEric Biggers else 2143fda4c61SEric Biggers err = vops->begin_enable_verity(filp); 2153fda4c61SEric Biggers inode_unlock(inode); 2163fda4c61SEric Biggers if (err) 2173fda4c61SEric Biggers goto out; 2183fda4c61SEric Biggers 2193fda4c61SEric Biggers /* 2203fda4c61SEric Biggers * Build the Merkle tree. Don't hold the inode lock during this, since 2213fda4c61SEric Biggers * on huge files this may take a very long time and we don't want to 2223fda4c61SEric Biggers * force unrelated syscalls like chown() to block forever. We don't 2233fda4c61SEric Biggers * need the inode lock here because deny_write_access() already prevents 2243fda4c61SEric Biggers * the file from being written to or truncated, and we still serialize 2253fda4c61SEric Biggers * ->begin_enable_verity() and ->end_enable_verity() using the inode 2263fda4c61SEric Biggers * lock and only allow one process to be here at a time on a given file. 2273fda4c61SEric Biggers */ 2283fda4c61SEric Biggers pr_debug("Building Merkle tree...\n"); 2293fda4c61SEric Biggers BUILD_BUG_ON(sizeof(desc->root_hash) < FS_VERITY_MAX_DIGEST_SIZE); 2303fda4c61SEric Biggers err = build_merkle_tree(inode, ¶ms, desc->root_hash); 2313fda4c61SEric Biggers if (err) { 2323fda4c61SEric Biggers fsverity_err(inode, "Error %d building Merkle tree", err); 2333fda4c61SEric Biggers goto rollback; 2343fda4c61SEric Biggers } 2353fda4c61SEric Biggers pr_debug("Done building Merkle tree. Root hash is %s:%*phN\n", 2363fda4c61SEric Biggers params.hash_alg->name, params.digest_size, desc->root_hash); 2373fda4c61SEric Biggers 2383fda4c61SEric Biggers /* 2393fda4c61SEric Biggers * Create the fsverity_info. Don't bother trying to save work by 2403fda4c61SEric Biggers * reusing the merkle_tree_params from above. Instead, just create the 2413fda4c61SEric Biggers * fsverity_info from the fsverity_descriptor as if it were just loaded 2423fda4c61SEric Biggers * from disk. This is simpler, and it serves as an extra check that the 2433fda4c61SEric Biggers * metadata we're writing is valid before actually enabling verity. 2443fda4c61SEric Biggers */ 2453fda4c61SEric Biggers vi = fsverity_create_info(inode, desc, desc_size); 2463fda4c61SEric Biggers if (IS_ERR(vi)) { 2473fda4c61SEric Biggers err = PTR_ERR(vi); 2483fda4c61SEric Biggers goto rollback; 2493fda4c61SEric Biggers } 2503fda4c61SEric Biggers 251432434c9SEric Biggers if (arg->sig_size) 252432434c9SEric Biggers pr_debug("Storing a %u-byte PKCS#7 signature alongside the file\n", 253432434c9SEric Biggers arg->sig_size); 254432434c9SEric Biggers 2553fda4c61SEric Biggers /* 2563fda4c61SEric Biggers * Tell the filesystem to finish enabling verity on the file. 2573fda4c61SEric Biggers * Serialized with ->begin_enable_verity() by the inode lock. 2583fda4c61SEric Biggers */ 2593fda4c61SEric Biggers inode_lock(inode); 2603fda4c61SEric Biggers err = vops->end_enable_verity(filp, desc, desc_size, params.tree_size); 2613fda4c61SEric Biggers inode_unlock(inode); 2623fda4c61SEric Biggers if (err) { 2633fda4c61SEric Biggers fsverity_err(inode, "%ps() failed with err %d", 2643fda4c61SEric Biggers vops->end_enable_verity, err); 2653fda4c61SEric Biggers fsverity_free_info(vi); 2663fda4c61SEric Biggers } else if (WARN_ON(!IS_VERITY(inode))) { 2673fda4c61SEric Biggers err = -EINVAL; 2683fda4c61SEric Biggers fsverity_free_info(vi); 2693fda4c61SEric Biggers } else { 2703fda4c61SEric Biggers /* Successfully enabled verity */ 2713fda4c61SEric Biggers 2723fda4c61SEric Biggers /* 2733fda4c61SEric Biggers * Readers can start using ->i_verity_info immediately, so it 2743fda4c61SEric Biggers * can't be rolled back once set. So don't set it until just 2753fda4c61SEric Biggers * after the filesystem has successfully enabled verity. 2763fda4c61SEric Biggers */ 2773fda4c61SEric Biggers fsverity_set_info(inode, vi); 2783fda4c61SEric Biggers } 2793fda4c61SEric Biggers out: 2803fda4c61SEric Biggers kfree(params.hashstate); 2813fda4c61SEric Biggers kfree(desc); 2823fda4c61SEric Biggers return err; 2833fda4c61SEric Biggers 2843fda4c61SEric Biggers rollback: 2853fda4c61SEric Biggers inode_lock(inode); 2863fda4c61SEric Biggers (void)vops->end_enable_verity(filp, NULL, 0, params.tree_size); 2873fda4c61SEric Biggers inode_unlock(inode); 2883fda4c61SEric Biggers goto out; 2893fda4c61SEric Biggers } 2903fda4c61SEric Biggers 2913fda4c61SEric Biggers /** 2923fda4c61SEric Biggers * fsverity_ioctl_enable() - enable verity on a file 2933fda4c61SEric Biggers * 2943fda4c61SEric Biggers * Enable fs-verity on a file. See the "FS_IOC_ENABLE_VERITY" section of 2953fda4c61SEric Biggers * Documentation/filesystems/fsverity.rst for the documentation. 2963fda4c61SEric Biggers * 2973fda4c61SEric Biggers * Return: 0 on success, -errno on failure 2983fda4c61SEric Biggers */ 2993fda4c61SEric Biggers int fsverity_ioctl_enable(struct file *filp, const void __user *uarg) 3003fda4c61SEric Biggers { 3013fda4c61SEric Biggers struct inode *inode = file_inode(filp); 3023fda4c61SEric Biggers struct fsverity_enable_arg arg; 3033fda4c61SEric Biggers int err; 3043fda4c61SEric Biggers 3053fda4c61SEric Biggers if (copy_from_user(&arg, uarg, sizeof(arg))) 3063fda4c61SEric Biggers return -EFAULT; 3073fda4c61SEric Biggers 3083fda4c61SEric Biggers if (arg.version != 1) 3093fda4c61SEric Biggers return -EINVAL; 3103fda4c61SEric Biggers 3113fda4c61SEric Biggers if (arg.__reserved1 || 3123fda4c61SEric Biggers memchr_inv(arg.__reserved2, 0, sizeof(arg.__reserved2))) 3133fda4c61SEric Biggers return -EINVAL; 3143fda4c61SEric Biggers 3153fda4c61SEric Biggers if (arg.block_size != PAGE_SIZE) 3163fda4c61SEric Biggers return -EINVAL; 3173fda4c61SEric Biggers 3183fda4c61SEric Biggers if (arg.salt_size > FIELD_SIZEOF(struct fsverity_descriptor, salt)) 3193fda4c61SEric Biggers return -EMSGSIZE; 3203fda4c61SEric Biggers 321432434c9SEric Biggers if (arg.sig_size > FS_VERITY_MAX_SIGNATURE_SIZE) 322432434c9SEric Biggers return -EMSGSIZE; 3233fda4c61SEric Biggers 3243fda4c61SEric Biggers /* 3253fda4c61SEric Biggers * Require a regular file with write access. But the actual fd must 3263fda4c61SEric Biggers * still be readonly so that we can lock out all writers. This is 3273fda4c61SEric Biggers * needed to guarantee that no writable fds exist to the file once it 3283fda4c61SEric Biggers * has verity enabled, and to stabilize the data being hashed. 3293fda4c61SEric Biggers */ 3303fda4c61SEric Biggers 3313fda4c61SEric Biggers err = inode_permission(inode, MAY_WRITE); 3323fda4c61SEric Biggers if (err) 3333fda4c61SEric Biggers return err; 3343fda4c61SEric Biggers 3353fda4c61SEric Biggers if (IS_APPEND(inode)) 3363fda4c61SEric Biggers return -EPERM; 3373fda4c61SEric Biggers 3383fda4c61SEric Biggers if (S_ISDIR(inode->i_mode)) 3393fda4c61SEric Biggers return -EISDIR; 3403fda4c61SEric Biggers 3413fda4c61SEric Biggers if (!S_ISREG(inode->i_mode)) 3423fda4c61SEric Biggers return -EINVAL; 3433fda4c61SEric Biggers 3443fda4c61SEric Biggers err = mnt_want_write_file(filp); 3453fda4c61SEric Biggers if (err) /* -EROFS */ 3463fda4c61SEric Biggers return err; 3473fda4c61SEric Biggers 3483fda4c61SEric Biggers err = deny_write_access(filp); 3493fda4c61SEric Biggers if (err) /* -ETXTBSY */ 3503fda4c61SEric Biggers goto out_drop_write; 3513fda4c61SEric Biggers 3523fda4c61SEric Biggers err = enable_verity(filp, &arg); 3533fda4c61SEric Biggers if (err) 3543fda4c61SEric Biggers goto out_allow_write_access; 3553fda4c61SEric Biggers 3563fda4c61SEric Biggers /* 3573fda4c61SEric Biggers * Some pages of the file may have been evicted from pagecache after 3583fda4c61SEric Biggers * being used in the Merkle tree construction, then read into pagecache 3593fda4c61SEric Biggers * again by another process reading from the file concurrently. Since 3603fda4c61SEric Biggers * these pages didn't undergo verification against the file measurement 3613fda4c61SEric Biggers * which fs-verity now claims to be enforcing, we have to wipe the 3623fda4c61SEric Biggers * pagecache to ensure that all future reads are verified. 3633fda4c61SEric Biggers */ 3643fda4c61SEric Biggers filemap_write_and_wait(inode->i_mapping); 3653fda4c61SEric Biggers invalidate_inode_pages2(inode->i_mapping); 3663fda4c61SEric Biggers 3673fda4c61SEric Biggers /* 3683fda4c61SEric Biggers * allow_write_access() is needed to pair with deny_write_access(). 3693fda4c61SEric Biggers * Regardless, the filesystem won't allow writing to verity files. 3703fda4c61SEric Biggers */ 3713fda4c61SEric Biggers out_allow_write_access: 3723fda4c61SEric Biggers allow_write_access(filp); 3733fda4c61SEric Biggers out_drop_write: 3743fda4c61SEric Biggers mnt_drop_write_file(filp); 3753fda4c61SEric Biggers return err; 3763fda4c61SEric Biggers } 3773fda4c61SEric Biggers EXPORT_SYMBOL_GPL(fsverity_ioctl_enable); 378