linux/fs/verity/open.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * fs/verity/open.c: 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        const 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
 106        /* Compute the starting block of each level */
 107        offset = 0;
 108        for (level = (int)params->num_levels - 1; level >= 0; level--) {
 109                blocks = params->level_start[level];
 110                params->level_start[level] = offset;
 111                pr_debug("Level %d is %llu blocks starting at index %llu\n",
 112                         level, blocks, offset);
 113                offset += blocks;
 114        }
 115
 116        params->tree_size = offset << log_blocksize;
 117        return 0;
 118
 119out_err:
 120        kfree(params->hashstate);
 121        memset(params, 0, sizeof(*params));
 122        return err;
 123}
 124
 125/*
 126 * Compute the file measurement by hashing the fsverity_descriptor excluding the
 127 * signature and with the sig_size field set to 0.
 128 */
 129static int compute_file_measurement(const struct fsverity_hash_alg *hash_alg,
 130                                    struct fsverity_descriptor *desc,
 131                                    u8 *measurement)
 132{
 133        __le32 sig_size = desc->sig_size;
 134        int err;
 135
 136        desc->sig_size = 0;
 137        err = fsverity_hash_buffer(hash_alg, desc, sizeof(*desc), measurement);
 138        desc->sig_size = sig_size;
 139
 140        return err;
 141}
 142
 143/*
 144 * Validate the given fsverity_descriptor and create a new fsverity_info from
 145 * it.  The signature (if present) is also checked.
 146 */
 147struct fsverity_info *fsverity_create_info(const struct inode *inode,
 148                                           void *_desc, size_t desc_size)
 149{
 150        struct fsverity_descriptor *desc = _desc;
 151        struct fsverity_info *vi;
 152        int err;
 153
 154        if (desc_size < sizeof(*desc)) {
 155                fsverity_err(inode, "Unrecognized descriptor size: %zu bytes",
 156                             desc_size);
 157                return ERR_PTR(-EINVAL);
 158        }
 159
 160        if (desc->version != 1) {
 161                fsverity_err(inode, "Unrecognized descriptor version: %u",
 162                             desc->version);
 163                return ERR_PTR(-EINVAL);
 164        }
 165
 166        if (memchr_inv(desc->__reserved, 0, sizeof(desc->__reserved))) {
 167                fsverity_err(inode, "Reserved bits set in descriptor");
 168                return ERR_PTR(-EINVAL);
 169        }
 170
 171        if (desc->salt_size > sizeof(desc->salt)) {
 172                fsverity_err(inode, "Invalid salt_size: %u", desc->salt_size);
 173                return ERR_PTR(-EINVAL);
 174        }
 175
 176        if (le64_to_cpu(desc->data_size) != inode->i_size) {
 177                fsverity_err(inode,
 178                             "Wrong data_size: %llu (desc) != %lld (inode)",
 179                             le64_to_cpu(desc->data_size), inode->i_size);
 180                return ERR_PTR(-EINVAL);
 181        }
 182
 183        vi = kmem_cache_zalloc(fsverity_info_cachep, GFP_KERNEL);
 184        if (!vi)
 185                return ERR_PTR(-ENOMEM);
 186        vi->inode = inode;
 187
 188        err = fsverity_init_merkle_tree_params(&vi->tree_params, inode,
 189                                               desc->hash_algorithm,
 190                                               desc->log_blocksize,
 191                                               desc->salt, desc->salt_size);
 192        if (err) {
 193                fsverity_err(inode,
 194                             "Error %d initializing Merkle tree parameters",
 195                             err);
 196                goto out;
 197        }
 198
 199        memcpy(vi->root_hash, desc->root_hash, vi->tree_params.digest_size);
 200
 201        err = compute_file_measurement(vi->tree_params.hash_alg, desc,
 202                                       vi->measurement);
 203        if (err) {
 204                fsverity_err(inode, "Error %d computing file measurement", err);
 205                goto out;
 206        }
 207        pr_debug("Computed file measurement: %s:%*phN\n",
 208                 vi->tree_params.hash_alg->name,
 209                 vi->tree_params.digest_size, vi->measurement);
 210
 211        err = fsverity_verify_signature(vi, desc, desc_size);
 212out:
 213        if (err) {
 214                fsverity_free_info(vi);
 215                vi = ERR_PTR(err);
 216        }
 217        return vi;
 218}
 219
 220void fsverity_set_info(struct inode *inode, struct fsverity_info *vi)
 221{
 222        /*
 223         * Multiple processes may race to set ->i_verity_info, so use cmpxchg.
 224         * This pairs with the READ_ONCE() in fsverity_get_info().
 225         */
 226        if (cmpxchg(&inode->i_verity_info, NULL, vi) != NULL)
 227                fsverity_free_info(vi);
 228}
 229
 230void fsverity_free_info(struct fsverity_info *vi)
 231{
 232        if (!vi)
 233                return;
 234        kfree(vi->tree_params.hashstate);
 235        kmem_cache_free(fsverity_info_cachep, vi);
 236}
 237
 238/* Ensure the inode has an ->i_verity_info */
 239static int ensure_verity_info(struct inode *inode)
 240{
 241        struct fsverity_info *vi = fsverity_get_info(inode);
 242        struct fsverity_descriptor *desc;
 243        int res;
 244
 245        if (vi)
 246                return 0;
 247
 248        res = inode->i_sb->s_vop->get_verity_descriptor(inode, NULL, 0);
 249        if (res < 0) {
 250                fsverity_err(inode,
 251                             "Error %d getting verity descriptor size", res);
 252                return res;
 253        }
 254        if (res > FS_VERITY_MAX_DESCRIPTOR_SIZE) {
 255                fsverity_err(inode, "Verity descriptor is too large (%d bytes)",
 256                             res);
 257                return -EMSGSIZE;
 258        }
 259        desc = kmalloc(res, GFP_KERNEL);
 260        if (!desc)
 261                return -ENOMEM;
 262        res = inode->i_sb->s_vop->get_verity_descriptor(inode, desc, res);
 263        if (res < 0) {
 264                fsverity_err(inode, "Error %d reading verity descriptor", res);
 265                goto out_free_desc;
 266        }
 267
 268        vi = fsverity_create_info(inode, desc, res);
 269        if (IS_ERR(vi)) {
 270                res = PTR_ERR(vi);
 271                goto out_free_desc;
 272        }
 273
 274        fsverity_set_info(inode, vi);
 275        res = 0;
 276out_free_desc:
 277        kfree(desc);
 278        return res;
 279}
 280
 281/**
 282 * fsverity_file_open() - prepare to open a verity file
 283 * @inode: the inode being opened
 284 * @filp: the struct file being set up
 285 *
 286 * When opening a verity file, deny the open if it is for writing.  Otherwise,
 287 * set up the inode's ->i_verity_info if not already done.
 288 *
 289 * When combined with fscrypt, this must be called after fscrypt_file_open().
 290 * Otherwise, we won't have the key set up to decrypt the verity metadata.
 291 *
 292 * Return: 0 on success, -errno on failure
 293 */
 294int fsverity_file_open(struct inode *inode, struct file *filp)
 295{
 296        if (!IS_VERITY(inode))
 297                return 0;
 298
 299        if (filp->f_mode & FMODE_WRITE) {
 300                pr_debug("Denying opening verity file (ino %lu) for write\n",
 301                         inode->i_ino);
 302                return -EPERM;
 303        }
 304
 305        return ensure_verity_info(inode);
 306}
 307EXPORT_SYMBOL_GPL(fsverity_file_open);
 308
 309/**
 310 * fsverity_prepare_setattr() - prepare to change a verity inode's attributes
 311 * @dentry: dentry through which the inode is being changed
 312 * @attr: attributes to change
 313 *
 314 * Verity files are immutable, so deny truncates.  This isn't covered by the
 315 * open-time check because sys_truncate() takes a path, not a file descriptor.
 316 *
 317 * Return: 0 on success, -errno on failure
 318 */
 319int fsverity_prepare_setattr(struct dentry *dentry, struct iattr *attr)
 320{
 321        if (IS_VERITY(d_inode(dentry)) && (attr->ia_valid & ATTR_SIZE)) {
 322                pr_debug("Denying truncate of verity file (ino %lu)\n",
 323                         d_inode(dentry)->i_ino);
 324                return -EPERM;
 325        }
 326        return 0;
 327}
 328EXPORT_SYMBOL_GPL(fsverity_prepare_setattr);
 329
 330/**
 331 * fsverity_cleanup_inode() - free the inode's verity info, if present
 332 *
 333 * Filesystems must call this on inode eviction to free ->i_verity_info.
 334 */
 335void fsverity_cleanup_inode(struct inode *inode)
 336{
 337        fsverity_free_info(inode->i_verity_info);
 338        inode->i_verity_info = NULL;
 339}
 340EXPORT_SYMBOL_GPL(fsverity_cleanup_inode);
 341
 342int __init fsverity_init_info_cache(void)
 343{
 344        fsverity_info_cachep = KMEM_CACHE_USERCOPY(fsverity_info,
 345                                                   SLAB_RECLAIM_ACCOUNT,
 346                                                   measurement);
 347        if (!fsverity_info_cachep)
 348                return -ENOMEM;
 349        return 0;
 350}
 351
 352void __init fsverity_exit_info_cache(void)
 353{
 354        kmem_cache_destroy(fsverity_info_cachep);
 355        fsverity_info_cachep = NULL;
 356}
 357