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 = ((u64)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 * Create a new fsverity_info from the given fsverity_descriptor (with optional
 146 * appended signature), and check the signature if present.  The
 147 * fsverity_descriptor must have already undergone basic validation.
 148 */
 149struct fsverity_info *fsverity_create_info(const struct inode *inode,
 150                                           struct fsverity_descriptor *desc,
 151                                           size_t desc_size)
 152{
 153        struct fsverity_info *vi;
 154        int err;
 155
 156        vi = kmem_cache_zalloc(fsverity_info_cachep, GFP_KERNEL);
 157        if (!vi)
 158                return ERR_PTR(-ENOMEM);
 159        vi->inode = inode;
 160
 161        err = fsverity_init_merkle_tree_params(&vi->tree_params, inode,
 162                                               desc->hash_algorithm,
 163                                               desc->log_blocksize,
 164                                               desc->salt, desc->salt_size);
 165        if (err) {
 166                fsverity_err(inode,
 167                             "Error %d initializing Merkle tree parameters",
 168                             err);
 169                goto out;
 170        }
 171
 172        memcpy(vi->root_hash, desc->root_hash, vi->tree_params.digest_size);
 173
 174        err = compute_file_digest(vi->tree_params.hash_alg, desc,
 175                                  vi->file_digest);
 176        if (err) {
 177                fsverity_err(inode, "Error %d computing file digest", err);
 178                goto out;
 179        }
 180        pr_debug("Computed file digest: %s:%*phN\n",
 181                 vi->tree_params.hash_alg->name,
 182                 vi->tree_params.digest_size, vi->file_digest);
 183
 184        err = fsverity_verify_signature(vi, desc->signature,
 185                                        le32_to_cpu(desc->sig_size));
 186out:
 187        if (err) {
 188                fsverity_free_info(vi);
 189                vi = ERR_PTR(err);
 190        }
 191        return vi;
 192}
 193
 194void fsverity_set_info(struct inode *inode, struct fsverity_info *vi)
 195{
 196        /*
 197         * Multiple tasks may race to set ->i_verity_info, so use
 198         * cmpxchg_release().  This pairs with the smp_load_acquire() in
 199         * fsverity_get_info().  I.e., here we publish ->i_verity_info with a
 200         * RELEASE barrier so that other tasks can ACQUIRE it.
 201         */
 202        if (cmpxchg_release(&inode->i_verity_info, NULL, vi) != NULL) {
 203                /* Lost the race, so free the fsverity_info we allocated. */
 204                fsverity_free_info(vi);
 205                /*
 206                 * Afterwards, the caller may access ->i_verity_info directly,
 207                 * so make sure to ACQUIRE the winning fsverity_info.
 208                 */
 209                (void)fsverity_get_info(inode);
 210        }
 211}
 212
 213void fsverity_free_info(struct fsverity_info *vi)
 214{
 215        if (!vi)
 216                return;
 217        kfree(vi->tree_params.hashstate);
 218        kmem_cache_free(fsverity_info_cachep, vi);
 219}
 220
 221static bool validate_fsverity_descriptor(struct inode *inode,
 222                                         const struct fsverity_descriptor *desc,
 223                                         size_t desc_size)
 224{
 225        if (desc_size < sizeof(*desc)) {
 226                fsverity_err(inode, "Unrecognized descriptor size: %zu bytes",
 227                             desc_size);
 228                return false;
 229        }
 230
 231        if (desc->version != 1) {
 232                fsverity_err(inode, "Unrecognized descriptor version: %u",
 233                             desc->version);
 234                return false;
 235        }
 236
 237        if (memchr_inv(desc->__reserved, 0, sizeof(desc->__reserved))) {
 238                fsverity_err(inode, "Reserved bits set in descriptor");
 239                return false;
 240        }
 241
 242        if (desc->salt_size > sizeof(desc->salt)) {
 243                fsverity_err(inode, "Invalid salt_size: %u", desc->salt_size);
 244                return false;
 245        }
 246
 247        if (le64_to_cpu(desc->data_size) != inode->i_size) {
 248                fsverity_err(inode,
 249                             "Wrong data_size: %llu (desc) != %lld (inode)",
 250                             le64_to_cpu(desc->data_size), inode->i_size);
 251                return false;
 252        }
 253
 254        if (le32_to_cpu(desc->sig_size) > desc_size - sizeof(*desc)) {
 255                fsverity_err(inode, "Signature overflows verity descriptor");
 256                return false;
 257        }
 258
 259        return true;
 260}
 261
 262/*
 263 * Read the inode's fsverity_descriptor (with optional appended signature) from
 264 * the filesystem, and do basic validation of it.
 265 */
 266int fsverity_get_descriptor(struct inode *inode,
 267                            struct fsverity_descriptor **desc_ret,
 268                            size_t *desc_size_ret)
 269{
 270        int res;
 271        struct fsverity_descriptor *desc;
 272
 273        res = inode->i_sb->s_vop->get_verity_descriptor(inode, NULL, 0);
 274        if (res < 0) {
 275                fsverity_err(inode,
 276                             "Error %d getting verity descriptor size", res);
 277                return res;
 278        }
 279        if (res > FS_VERITY_MAX_DESCRIPTOR_SIZE) {
 280                fsverity_err(inode, "Verity descriptor is too large (%d bytes)",
 281                             res);
 282                return -EMSGSIZE;
 283        }
 284        desc = kmalloc(res, GFP_KERNEL);
 285        if (!desc)
 286                return -ENOMEM;
 287        res = inode->i_sb->s_vop->get_verity_descriptor(inode, desc, res);
 288        if (res < 0) {
 289                fsverity_err(inode, "Error %d reading verity descriptor", res);
 290                kfree(desc);
 291                return res;
 292        }
 293
 294        if (!validate_fsverity_descriptor(inode, desc, res)) {
 295                kfree(desc);
 296                return -EINVAL;
 297        }
 298
 299        *desc_ret = desc;
 300        *desc_size_ret = res;
 301        return 0;
 302}
 303
 304/* Ensure the inode has an ->i_verity_info */
 305static int ensure_verity_info(struct inode *inode)
 306{
 307        struct fsverity_info *vi = fsverity_get_info(inode);
 308        struct fsverity_descriptor *desc;
 309        size_t desc_size;
 310        int err;
 311
 312        if (vi)
 313                return 0;
 314
 315        err = fsverity_get_descriptor(inode, &desc, &desc_size);
 316        if (err)
 317                return err;
 318
 319        vi = fsverity_create_info(inode, desc, desc_size);
 320        if (IS_ERR(vi)) {
 321                err = PTR_ERR(vi);
 322                goto out_free_desc;
 323        }
 324
 325        fsverity_set_info(inode, vi);
 326        err = 0;
 327out_free_desc:
 328        kfree(desc);
 329        return err;
 330}
 331
 332/**
 333 * fsverity_file_open() - prepare to open a verity file
 334 * @inode: the inode being opened
 335 * @filp: the struct file being set up
 336 *
 337 * When opening a verity file, deny the open if it is for writing.  Otherwise,
 338 * set up the inode's ->i_verity_info if not already done.
 339 *
 340 * When combined with fscrypt, this must be called after fscrypt_file_open().
 341 * Otherwise, we won't have the key set up to decrypt the verity metadata.
 342 *
 343 * Return: 0 on success, -errno on failure
 344 */
 345int fsverity_file_open(struct inode *inode, struct file *filp)
 346{
 347        if (!IS_VERITY(inode))
 348                return 0;
 349
 350        if (filp->f_mode & FMODE_WRITE) {
 351                pr_debug("Denying opening verity file (ino %lu) for write\n",
 352                         inode->i_ino);
 353                return -EPERM;
 354        }
 355
 356        return ensure_verity_info(inode);
 357}
 358EXPORT_SYMBOL_GPL(fsverity_file_open);
 359
 360/**
 361 * fsverity_prepare_setattr() - prepare to change a verity inode's attributes
 362 * @dentry: dentry through which the inode is being changed
 363 * @attr: attributes to change
 364 *
 365 * Verity files are immutable, so deny truncates.  This isn't covered by the
 366 * open-time check because sys_truncate() takes a path, not a file descriptor.
 367 *
 368 * Return: 0 on success, -errno on failure
 369 */
 370int fsverity_prepare_setattr(struct dentry *dentry, struct iattr *attr)
 371{
 372        if (IS_VERITY(d_inode(dentry)) && (attr->ia_valid & ATTR_SIZE)) {
 373                pr_debug("Denying truncate of verity file (ino %lu)\n",
 374                         d_inode(dentry)->i_ino);
 375                return -EPERM;
 376        }
 377        return 0;
 378}
 379EXPORT_SYMBOL_GPL(fsverity_prepare_setattr);
 380
 381/**
 382 * fsverity_cleanup_inode() - free the inode's verity info, if present
 383 * @inode: an inode being evicted
 384 *
 385 * Filesystems must call this on inode eviction to free ->i_verity_info.
 386 */
 387void fsverity_cleanup_inode(struct inode *inode)
 388{
 389        fsverity_free_info(inode->i_verity_info);
 390        inode->i_verity_info = NULL;
 391}
 392EXPORT_SYMBOL_GPL(fsverity_cleanup_inode);
 393
 394int __init fsverity_init_info_cache(void)
 395{
 396        fsverity_info_cachep = KMEM_CACHE_USERCOPY(fsverity_info,
 397                                                   SLAB_RECLAIM_ACCOUNT,
 398                                                   file_digest);
 399        if (!fsverity_info_cachep)
 400                return -ENOMEM;
 401        return 0;
 402}
 403
 404void __init fsverity_exit_info_cache(void)
 405{
 406        kmem_cache_destroy(fsverity_info_cachep);
 407        fsverity_info_cachep = NULL;
 408}
 409