0001
0002
0003
0004
0005
0006
0007
0008 #include "fsverity_private.h"
0009
0010 #include <linux/slab.h>
0011
0012 static struct kmem_cache *fsverity_info_cachep;
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 int fsverity_init_merkle_tree_params(struct merkle_tree_params *params,
0029 const struct inode *inode,
0030 unsigned int hash_algorithm,
0031 unsigned int log_blocksize,
0032 const u8 *salt, size_t salt_size)
0033 {
0034 struct fsverity_hash_alg *hash_alg;
0035 int err;
0036 u64 blocks;
0037 u64 offset;
0038 int level;
0039
0040 memset(params, 0, sizeof(*params));
0041
0042 hash_alg = fsverity_get_hash_alg(inode, hash_algorithm);
0043 if (IS_ERR(hash_alg))
0044 return PTR_ERR(hash_alg);
0045 params->hash_alg = hash_alg;
0046 params->digest_size = hash_alg->digest_size;
0047
0048 params->hashstate = fsverity_prepare_hash_state(hash_alg, salt,
0049 salt_size);
0050 if (IS_ERR(params->hashstate)) {
0051 err = PTR_ERR(params->hashstate);
0052 params->hashstate = NULL;
0053 fsverity_err(inode, "Error %d preparing hash state", err);
0054 goto out_err;
0055 }
0056
0057 if (log_blocksize != PAGE_SHIFT) {
0058 fsverity_warn(inode, "Unsupported log_blocksize: %u",
0059 log_blocksize);
0060 err = -EINVAL;
0061 goto out_err;
0062 }
0063 params->log_blocksize = log_blocksize;
0064 params->block_size = 1 << log_blocksize;
0065
0066 if (WARN_ON(!is_power_of_2(params->digest_size))) {
0067 err = -EINVAL;
0068 goto out_err;
0069 }
0070 if (params->block_size < 2 * params->digest_size) {
0071 fsverity_warn(inode,
0072 "Merkle tree block size (%u) too small for hash algorithm \"%s\"",
0073 params->block_size, hash_alg->name);
0074 err = -EINVAL;
0075 goto out_err;
0076 }
0077 params->log_arity = params->log_blocksize - ilog2(params->digest_size);
0078 params->hashes_per_block = 1 << params->log_arity;
0079
0080 pr_debug("Merkle tree uses %s with %u-byte blocks (%u hashes/block), salt=%*phN\n",
0081 hash_alg->name, params->block_size, params->hashes_per_block,
0082 (int)salt_size, salt);
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 blocks = ((u64)inode->i_size + params->block_size - 1) >> log_blocksize;
0093 pr_debug("Data is %lld bytes (%llu blocks)\n", inode->i_size, blocks);
0094 while (blocks > 1) {
0095 if (params->num_levels >= FS_VERITY_MAX_LEVELS) {
0096 fsverity_err(inode, "Too many levels in Merkle tree");
0097 err = -EINVAL;
0098 goto out_err;
0099 }
0100 blocks = (blocks + params->hashes_per_block - 1) >>
0101 params->log_arity;
0102
0103 params->level_start[params->num_levels++] = blocks;
0104 }
0105 params->level0_blocks = params->level_start[0];
0106
0107
0108 offset = 0;
0109 for (level = (int)params->num_levels - 1; level >= 0; level--) {
0110 blocks = params->level_start[level];
0111 params->level_start[level] = offset;
0112 pr_debug("Level %d is %llu blocks starting at index %llu\n",
0113 level, blocks, offset);
0114 offset += blocks;
0115 }
0116
0117 params->tree_size = offset << log_blocksize;
0118 return 0;
0119
0120 out_err:
0121 kfree(params->hashstate);
0122 memset(params, 0, sizeof(*params));
0123 return err;
0124 }
0125
0126
0127
0128
0129
0130 static int compute_file_digest(struct fsverity_hash_alg *hash_alg,
0131 struct fsverity_descriptor *desc,
0132 u8 *file_digest)
0133 {
0134 __le32 sig_size = desc->sig_size;
0135 int err;
0136
0137 desc->sig_size = 0;
0138 err = fsverity_hash_buffer(hash_alg, desc, sizeof(*desc), file_digest);
0139 desc->sig_size = sig_size;
0140
0141 return err;
0142 }
0143
0144
0145
0146
0147
0148
0149 struct fsverity_info *fsverity_create_info(const struct inode *inode,
0150 struct fsverity_descriptor *desc)
0151 {
0152 struct fsverity_info *vi;
0153 int err;
0154
0155 vi = kmem_cache_zalloc(fsverity_info_cachep, GFP_KERNEL);
0156 if (!vi)
0157 return ERR_PTR(-ENOMEM);
0158 vi->inode = inode;
0159
0160 err = fsverity_init_merkle_tree_params(&vi->tree_params, inode,
0161 desc->hash_algorithm,
0162 desc->log_blocksize,
0163 desc->salt, desc->salt_size);
0164 if (err) {
0165 fsverity_err(inode,
0166 "Error %d initializing Merkle tree parameters",
0167 err);
0168 goto out;
0169 }
0170
0171 memcpy(vi->root_hash, desc->root_hash, vi->tree_params.digest_size);
0172
0173 err = compute_file_digest(vi->tree_params.hash_alg, desc,
0174 vi->file_digest);
0175 if (err) {
0176 fsverity_err(inode, "Error %d computing file digest", err);
0177 goto out;
0178 }
0179 pr_debug("Computed file digest: %s:%*phN\n",
0180 vi->tree_params.hash_alg->name,
0181 vi->tree_params.digest_size, vi->file_digest);
0182
0183 err = fsverity_verify_signature(vi, desc->signature,
0184 le32_to_cpu(desc->sig_size));
0185 out:
0186 if (err) {
0187 fsverity_free_info(vi);
0188 vi = ERR_PTR(err);
0189 }
0190 return vi;
0191 }
0192
0193 void fsverity_set_info(struct inode *inode, struct fsverity_info *vi)
0194 {
0195
0196
0197
0198
0199
0200
0201 if (cmpxchg_release(&inode->i_verity_info, NULL, vi) != NULL) {
0202
0203 fsverity_free_info(vi);
0204
0205
0206
0207
0208 (void)fsverity_get_info(inode);
0209 }
0210 }
0211
0212 void fsverity_free_info(struct fsverity_info *vi)
0213 {
0214 if (!vi)
0215 return;
0216 kfree(vi->tree_params.hashstate);
0217 kmem_cache_free(fsverity_info_cachep, vi);
0218 }
0219
0220 static bool validate_fsverity_descriptor(struct inode *inode,
0221 const struct fsverity_descriptor *desc,
0222 size_t desc_size)
0223 {
0224 if (desc_size < sizeof(*desc)) {
0225 fsverity_err(inode, "Unrecognized descriptor size: %zu bytes",
0226 desc_size);
0227 return false;
0228 }
0229
0230 if (desc->version != 1) {
0231 fsverity_err(inode, "Unrecognized descriptor version: %u",
0232 desc->version);
0233 return false;
0234 }
0235
0236 if (memchr_inv(desc->__reserved, 0, sizeof(desc->__reserved))) {
0237 fsverity_err(inode, "Reserved bits set in descriptor");
0238 return false;
0239 }
0240
0241 if (desc->salt_size > sizeof(desc->salt)) {
0242 fsverity_err(inode, "Invalid salt_size: %u", desc->salt_size);
0243 return false;
0244 }
0245
0246 if (le64_to_cpu(desc->data_size) != inode->i_size) {
0247 fsverity_err(inode,
0248 "Wrong data_size: %llu (desc) != %lld (inode)",
0249 le64_to_cpu(desc->data_size), inode->i_size);
0250 return false;
0251 }
0252
0253 if (le32_to_cpu(desc->sig_size) > desc_size - sizeof(*desc)) {
0254 fsverity_err(inode, "Signature overflows verity descriptor");
0255 return false;
0256 }
0257
0258 return true;
0259 }
0260
0261
0262
0263
0264
0265 int fsverity_get_descriptor(struct inode *inode,
0266 struct fsverity_descriptor **desc_ret)
0267 {
0268 int res;
0269 struct fsverity_descriptor *desc;
0270
0271 res = inode->i_sb->s_vop->get_verity_descriptor(inode, NULL, 0);
0272 if (res < 0) {
0273 fsverity_err(inode,
0274 "Error %d getting verity descriptor size", res);
0275 return res;
0276 }
0277 if (res > FS_VERITY_MAX_DESCRIPTOR_SIZE) {
0278 fsverity_err(inode, "Verity descriptor is too large (%d bytes)",
0279 res);
0280 return -EMSGSIZE;
0281 }
0282 desc = kmalloc(res, GFP_KERNEL);
0283 if (!desc)
0284 return -ENOMEM;
0285 res = inode->i_sb->s_vop->get_verity_descriptor(inode, desc, res);
0286 if (res < 0) {
0287 fsverity_err(inode, "Error %d reading verity descriptor", res);
0288 kfree(desc);
0289 return res;
0290 }
0291
0292 if (!validate_fsverity_descriptor(inode, desc, res)) {
0293 kfree(desc);
0294 return -EINVAL;
0295 }
0296
0297 *desc_ret = desc;
0298 return 0;
0299 }
0300
0301
0302 static int ensure_verity_info(struct inode *inode)
0303 {
0304 struct fsverity_info *vi = fsverity_get_info(inode);
0305 struct fsverity_descriptor *desc;
0306 int err;
0307
0308 if (vi)
0309 return 0;
0310
0311 err = fsverity_get_descriptor(inode, &desc);
0312 if (err)
0313 return err;
0314
0315 vi = fsverity_create_info(inode, desc);
0316 if (IS_ERR(vi)) {
0317 err = PTR_ERR(vi);
0318 goto out_free_desc;
0319 }
0320
0321 fsverity_set_info(inode, vi);
0322 err = 0;
0323 out_free_desc:
0324 kfree(desc);
0325 return err;
0326 }
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341 int fsverity_file_open(struct inode *inode, struct file *filp)
0342 {
0343 if (!IS_VERITY(inode))
0344 return 0;
0345
0346 if (filp->f_mode & FMODE_WRITE) {
0347 pr_debug("Denying opening verity file (ino %lu) for write\n",
0348 inode->i_ino);
0349 return -EPERM;
0350 }
0351
0352 return ensure_verity_info(inode);
0353 }
0354 EXPORT_SYMBOL_GPL(fsverity_file_open);
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366 int fsverity_prepare_setattr(struct dentry *dentry, struct iattr *attr)
0367 {
0368 if (IS_VERITY(d_inode(dentry)) && (attr->ia_valid & ATTR_SIZE)) {
0369 pr_debug("Denying truncate of verity file (ino %lu)\n",
0370 d_inode(dentry)->i_ino);
0371 return -EPERM;
0372 }
0373 return 0;
0374 }
0375 EXPORT_SYMBOL_GPL(fsverity_prepare_setattr);
0376
0377
0378
0379
0380
0381
0382
0383 void fsverity_cleanup_inode(struct inode *inode)
0384 {
0385 fsverity_free_info(inode->i_verity_info);
0386 inode->i_verity_info = NULL;
0387 }
0388 EXPORT_SYMBOL_GPL(fsverity_cleanup_inode);
0389
0390 int __init fsverity_init_info_cache(void)
0391 {
0392 fsverity_info_cachep = KMEM_CACHE_USERCOPY(fsverity_info,
0393 SLAB_RECLAIM_ACCOUNT,
0394 file_digest);
0395 if (!fsverity_info_cachep)
0396 return -ENOMEM;
0397 return 0;
0398 }
0399
0400 void __init fsverity_exit_info_cache(void)
0401 {
0402 kmem_cache_destroy(fsverity_info_cachep);
0403 fsverity_info_cachep = NULL;
0404 }