linux/fs/verity/open.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Opening fs-verity files
   4 *
   5 * Copyright 2019 Google LLC
   6 */
   7
   8#include "fsverity_private.h"
   9
  10#include <linux/slab.h>
  11
  12static struct kmem_cache *fsverity_info_cachep;
  13
  14/**
  15 * fsverity_init_merkle_tree_params() - initialize Merkle tree parameters
  16 * @params: the parameters struct to initialize
  17 * @inode: the inode for which the Merkle tree is being built
  18 * @hash_algorithm: number of hash algorithm to use
  19 * @log_blocksize: log base 2 of block size to use
  20 * @salt: pointer to salt (optional)
  21 * @salt_size: size of salt, possibly 0
  22 *
  23 * Validate the hash algorithm and block size, then compute the tree topology
  24 * (num levels, num blocks in each level, etc.) and initialize @params.
  25 *
  26 * Return: 0 on success, -errno on failure
  27 */
  28int fsverity_init_merkle_tree_params(struct merkle_tree_params *params,
  29                                     const struct inode *inode,
  30                                     unsigned int hash_algorithm,
  31                                     unsigned int log_blocksize,
  32                                     const u8 *salt, size_t salt_size)
  33{
  34        struct fsverity_hash_alg *hash_alg;
  35        int err;
  36        u64 blocks;
  37        u64 offset;
  38        int level;
  39
  40        memset(params, 0, sizeof(*params));
  41
  42        hash_alg = fsverity_get_hash_alg(inode, hash_algorithm);
  43        if (IS_ERR(hash_alg))
  44                return PTR_ERR(hash_alg);
  45        params->hash_alg = hash_alg;
  46        params->digest_size = hash_alg->digest_size;
  47
  48        params->hashstate = fsverity_prepare_hash_state(hash_alg, salt,
  49                                                        salt_size);
  50        if (IS_ERR(params->hashstate)) {
  51                err = PTR_ERR(params->hashstate);
  52                params->hashstate = NULL;
  53                fsverity_err(inode, "Error %d preparing hash state", err);
  54                goto out_err;
  55        }
  56
  57        if (log_blocksize != PAGE_SHIFT) {
  58                fsverity_warn(inode, "Unsupported log_blocksize: %u",
  59                              log_blocksize);
  60                err = -EINVAL;
  61                goto out_err;
  62        }
  63        params->log_blocksize = log_blocksize;
  64        params->block_size = 1 << log_blocksize;
  65
  66        if (WARN_ON(!is_power_of_2(params->digest_size))) {
  67                err = -EINVAL;
  68                goto out_err;
  69        }
  70        if (params->block_size < 2 * params->digest_size) {
  71                fsverity_warn(inode,
  72                              "Merkle tree block size (%u) too small for hash algorithm \"%s\"",
  73                              params->block_size, hash_alg->name);
  74                err = -EINVAL;
  75                goto out_err;
  76        }
  77        params->log_arity = params->log_blocksize - ilog2(params->digest_size);
  78        params->hashes_per_block = 1 << params->log_arity;
  79
  80        pr_debug("Merkle tree uses %s with %u-byte blocks (%u hashes/block), salt=%*phN\n",
  81                 hash_alg->name, params->block_size, params->hashes_per_block,
  82                 (int)salt_size, salt);
  83
  84        /*
  85         * Compute the number of levels in the Merkle tree and create a map from
  86         * level to the starting block of that level.  Level 'num_levels - 1' is
  87         * the root and is stored first.  Level 0 is the level directly "above"
  88         * the data blocks and is stored last.
  89         */
  90
  91        /* Compute number of levels and the number of blocks in each level */
  92        blocks = (inode->i_size + params->block_size - 1) >> log_blocksize;
  93        pr_debug("Data is %lld bytes (%llu blocks)\n", inode->i_size, blocks);
  94        while (blocks > 1) {
  95                if (params->num_levels >= FS_VERITY_MAX_LEVELS) {
  96                        fsverity_err(inode, "Too many levels in Merkle tree");
  97                        err = -EINVAL;
  98                        goto out_err;
  99                }
 100                blocks = (blocks + params->hashes_per_block - 1) >>
 101                         params->log_arity;
 102                /* temporarily using level_start[] to store blocks in level */
 103                params->level_start[params->num_levels++] = blocks;
 104        }
 105        params->level0_blocks = params->level_start[0];
 106
 107        /* Compute the starting block of each level */
 108        offset = 0;
 109        for (level = (int)params->num_levels - 1; level >= 0; level--) {
 110                blocks = params->level_start[level];
 111                params->level_start[level] = offset;
 112                pr_debug("Level %d is %llu blocks starting at index %llu\n",
 113                         level, blocks, offset);
 114                offset += blocks;
 115        }
 116
 117        params->tree_size = offset << log_blocksize;
 118        return 0;
 119
 120out_err:
 121        kfree(params->hashstate);
 122        memset(params, 0, sizeof(*params));
 123        return err;
 124}
 125
 126/*
 127 * Compute the file digest by hashing the fsverity_descriptor excluding the
 128 * signature and with the sig_size field set to 0.
 129 */
 130static int compute_file_digest(struct fsverity_hash_alg *hash_alg,
 131                               struct fsverity_descriptor *desc,
 132                               u8 *file_digest)
 133{
 134        __le32 sig_size = desc->sig_size;
 135        int err;
 136
 137        desc->sig_size = 0;
 138        err = fsverity_hash_buffer(hash_alg, desc, sizeof(*desc), file_digest);
 139        desc->sig_size = sig_size;
 140
 141        return err;
 142}
 143
 144/*
 145 * Validate the given fsverity_descriptor and create a new fsverity_info from
 146 * it.  The signature (if present) is also checked.
 147 */
 148struct fsverity_info *fsverity_create_info(const struct inode *inode,
 149                                           void *_desc, size_t desc_size)
 150{
 151        struct fsverity_descriptor *desc = _desc;
 152        struct fsverity_info *vi;
 153        int err;
 154
 155        if (desc_size < sizeof(*desc)) {
 156                fsverity_err(inode, "Unrecognized descriptor size: %zu bytes",
 157                             desc_size);
 158                return ERR_PTR(-EINVAL);
 159        }
 160
 161        if (desc->version != 1) {
 162                fsverity_err(inode, "Unrecognized descriptor version: %u",
 163                             desc->version);
 164                return ERR_PTR(-EINVAL);
 165        }
 166
 167        if (memchr_inv(desc->__reserved, 0, sizeof(desc->__reserved))) {
 168                fsverity_err(inode, "Reserved bits set in descriptor");
 169                return ERR_PTR(-EINVAL);
 170        }
 171
 172        if (desc->salt_size > sizeof(desc->salt)) {
 173                fsverity_err(inode, "Invalid salt_size: %u", desc->salt_size);
 174                return ERR_PTR(-EINVAL);
 175        }
 176
 177        if (le64_to_cpu(desc->data_size) != inode->i_size) {
 178                fsverity_err(inode,
 179                             "Wrong data_size: %llu (desc) != %lld (inode)",
 180                             le64_to_cpu(desc->data_size), inode->i_size);
 181                return ERR_PTR(-EINVAL);
 182        }
 183
 184        vi = kmem_cache_zalloc(fsverity_info_cachep, GFP_KERNEL);
 185        if (!vi)
 186                return ERR_PTR(-ENOMEM);
 187        vi->inode = inode;
 188
 189        err = fsverity_init_merkle_tree_params(&vi->tree_params, inode,
 190                                               desc->hash_algorithm,
 191                                               desc->log_blocksize,
 192                                               desc->salt, desc->salt_size);
 193        if (err) {
 194                fsverity_err(inode,
 195                             "Error %d initializing Merkle tree parameters",
 196                             err);
 197                goto out;
 198        }
 199
 200        memcpy(vi->root_hash, desc->root_hash, vi->tree_params.digest_size);
 201
 202        err = compute_file_digest(vi->tree_params.hash_alg, desc,
 203                                  vi->file_digest);
 204        if (err) {
 205                fsverity_err(inode, "Error %d computing file digest", err);
 206                goto out;
 207        }
 208        pr_debug("Computed file digest: %s:%*phN\n",
 209                 vi->tree_params.hash_alg->name,
 210                 vi->tree_params.digest_size, vi->file_digest);
 211
 212        err = fsverity_verify_signature(vi, desc, desc_size);
 213out:
 214        if (err) {
 215                fsverity_free_info(vi);
 216                vi = ERR_PTR(err);
 217        }
 218        return vi;
 219}
 220
 221void fsverity_set_info(struct inode *inode, struct fsverity_info *vi)
 222{
 223        /*
 224         * Multiple tasks may race to set ->i_verity_info, so use
 225         * cmpxchg_release().  This pairs with the smp_load_acquire() in
 226         * fsverity_get_info().  I.e., here we publish ->i_verity_info with a
 227         * RELEASE barrier so that other tasks can ACQUIRE it.
 228         */
 229        if (cmpxchg_release(&inode->i_verity_info, NULL, vi) != NULL) {
 230                /* Lost the race, so free the fsverity_info we allocated. */
 231                fsverity_free_info(vi);
 232                /*
 233                 * Afterwards, the caller may access ->i_verity_info directly,
 234                 * so make sure to ACQUIRE the winning fsverity_info.
 235                 */
 236                (void)fsverity_get_info(inode);
 237        }
 238}
 239
 240void fsverity_free_info(struct fsverity_info *vi)
 241{
 242        if (!vi)
 243                return;
 244        kfree(vi->tree_params.hashstate);
 245        kmem_cache_free(fsverity_info_cachep, vi);
 246}
 247
 248/* Ensure the inode has an ->i_verity_info */
 249static int ensure_verity_info(struct inode *inode)
 250{
 251        struct fsverity_info *vi = fsverity_get_info(inode);
 252        struct fsverity_descriptor *desc;
 253        int res;
 254
 255        if (vi)
 256                return 0;
 257
 258        res = inode->i_sb->s_vop->get_verity_descriptor(inode, NULL, 0);
 259        if (res < 0) {
 260                fsverity_err(inode,
 261                             "Error %d getting verity descriptor size", res);
 262                return res;
 263        }
 264        if (res > FS_VERITY_MAX_DESCRIPTOR_SIZE) {
 265                fsverity_err(inode, "Verity descriptor is too large (%d bytes)",
 266                             res);
 267                return -EMSGSIZE;
 268        }
 269        desc = kmalloc(res, GFP_KERNEL);
 270        if (!desc)
 271                return -ENOMEM;
 272        res = inode->i_sb->s_vop->get_verity_descriptor(inode, desc, res);
 273        if (res < 0) {
 274                fsverity_err(inode, "Error %d reading verity descriptor", res);
 275                goto out_free_desc;
 276        }
 277
 278        vi = fsverity_create_info(inode, desc, res);
 279        if (IS_ERR(vi)) {
 280                res = PTR_ERR(vi);
 281                goto out_free_desc;
 282        }
 283
 284        fsverity_set_info(inode, vi);
 285        res = 0;
 286out_free_desc:
 287        kfree(desc);
 288        return res;
 289}
 290
 291/**
 292 * fsverity_file_open() - prepare to open a verity file
 293 * @inode: the inode being opened
 294 * @filp: the struct file being set up
 295 *
 296 * When opening a verity file, deny the open if it is for writing.  Otherwise,
 297 * set up the inode's ->i_verity_info if not already done.
 298 *
 299 * When combined with fscrypt, this must be called after fscrypt_file_open().
 300 * Otherwise, we won't have the key set up to decrypt the verity metadata.
 301 *
 302 * Return: 0 on success, -errno on failure
 303 */
 304int fsverity_file_open(struct inode *inode, struct file *filp)
 305{
 306        if (!IS_VERITY(inode))
 307                return 0;
 308
 309        if (filp->f_mode & FMODE_WRITE) {
 310                pr_debug("Denying opening verity file (ino %lu) for write\n",
 311                         inode->i_ino);
 312                return -EPERM;
 313        }
 314
 315        return ensure_verity_info(inode);
 316}
 317EXPORT_SYMBOL_GPL(fsverity_file_open);
 318
 319/**
 320 * fsverity_prepare_setattr() - prepare to change a verity inode's attributes
 321 * @dentry: dentry through which the inode is being changed
 322 * @attr: attributes to change
 323 *
 324 * Verity files are immutable, so deny truncates.  This isn't covered by the
 325 * open-time check because sys_truncate() takes a path, not a file descriptor.
 326 *
 327 * Return: 0 on success, -errno on failure
 328 */
 329int fsverity_prepare_setattr(struct dentry *dentry, struct iattr *attr)
 330{
 331        if (IS_VERITY(d_inode(dentry)) && (attr->ia_valid & ATTR_SIZE)) {
 332                pr_debug("Denying truncate of verity file (ino %lu)\n",
 333                         d_inode(dentry)->i_ino);
 334                return -EPERM;
 335        }
 336        return 0;
 337}
 338EXPORT_SYMBOL_GPL(fsverity_prepare_setattr);
 339
 340/**
 341 * fsverity_cleanup_inode() - free the inode's verity info, if present
 342 * @inode: an inode being evicted
 343 *
 344 * Filesystems must call this on inode eviction to free ->i_verity_info.
 345 */
 346void fsverity_cleanup_inode(struct inode *inode)
 347{
 348        fsverity_free_info(inode->i_verity_info);
 349        inode->i_verity_info = NULL;
 350}
 351EXPORT_SYMBOL_GPL(fsverity_cleanup_inode);
 352
 353int __init fsverity_init_info_cache(void)
 354{
 355        fsverity_info_cachep = KMEM_CACHE_USERCOPY(fsverity_info,
 356                                                   SLAB_RECLAIM_ACCOUNT,
 357                                                   file_digest);
 358        if (!fsverity_info_cachep)
 359                return -ENOMEM;
 360        return 0;
 361}
 362
 363void __init fsverity_exit_info_cache(void)
 364{
 365        kmem_cache_destroy(fsverity_info_cachep);
 366        fsverity_info_cachep = NULL;
 367}
 368