Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 26 Apr 2023 15:37:51 +0000 (08:37 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 26 Apr 2023 15:37:51 +0000 (08:37 -0700)
Pull fscrypt updates from Eric Biggers:
 "A few cleanups for fs/crypto/, and another patch to prepare for the
  upcoming CephFS encryption support"

* tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/linux:
  fscrypt: optimize fscrypt_initialize()
  fscrypt: use WARN_ON_ONCE instead of WARN_ON
  fscrypt: new helper function - fscrypt_prepare_lookup_partial()
  fs/buffer.c: use b_folio for fscrypt work

fs/buffer.c
fs/crypto/bio.c
fs/crypto/crypto.c
fs/crypto/fname.c
fs/crypto/fscrypt_private.h
fs/crypto/hkdf.c
fs/crypto/hooks.c
fs/crypto/keyring.c
fs/crypto/keysetup.c
fs/crypto/policy.c
include/linux/fscrypt.h

index 10390f53f3f529321dada7eec6593a27d0054ca4..737e3eff6259014cbd4ef79087c7183d0a7c6981 100644 (file)
@@ -331,8 +331,8 @@ static void decrypt_bh(struct work_struct *work)
        struct buffer_head *bh = ctx->bh;
        int err;
 
-       err = fscrypt_decrypt_pagecache_blocks(page_folio(bh->b_page),
-                                              bh->b_size, bh_offset(bh));
+       err = fscrypt_decrypt_pagecache_blocks(bh->b_folio, bh->b_size,
+                                              bh_offset(bh));
        if (err == 0 && need_fsverity(bh)) {
                /*
                 * We use different work queues for decryption and for verity
index d57d0a020f71c70279a5acea8ca15f750e7f4eae..62e1a3dd83574c3c16476adc961730640dbfd928 100644 (file)
@@ -69,7 +69,7 @@ static int fscrypt_zeroout_range_inline_crypt(const struct inode *inode,
                                        pblk << (blockbits - SECTOR_SHIFT);
                }
                ret = bio_add_page(bio, ZERO_PAGE(0), bytes_this_page, 0);
-               if (WARN_ON(ret != bytes_this_page)) {
+               if (WARN_ON_ONCE(ret != bytes_this_page)) {
                        err = -EIO;
                        goto out;
                }
@@ -147,7 +147,7 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
                        break;
        }
        nr_pages = i;
-       if (WARN_ON(nr_pages <= 0))
+       if (WARN_ON_ONCE(nr_pages <= 0))
                return -EINVAL;
 
        /* This always succeeds since __GFP_DIRECT_RECLAIM is set. */
@@ -170,7 +170,7 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
                        offset += blocksize;
                        if (offset == PAGE_SIZE || len == 0) {
                                ret = bio_add_page(bio, pages[i++], offset, 0);
-                               if (WARN_ON(ret != offset)) {
+                               if (WARN_ON_ONCE(ret != offset)) {
                                        err = -EIO;
                                        goto out;
                                }
index bf642479269a542b97157177b5c1bbf80e7665da..6a837e4b80dcb3a052508d7e64bca409956236d1 100644 (file)
@@ -308,19 +308,24 @@ EXPORT_SYMBOL(fscrypt_decrypt_block_inplace);
 
 /**
  * fscrypt_initialize() - allocate major buffers for fs encryption.
- * @cop_flags:  fscrypt operations flags
+ * @sb: the filesystem superblock
  *
  * We only call this when we start accessing encrypted files, since it
  * results in memory getting allocated that wouldn't otherwise be used.
  *
  * Return: 0 on success; -errno on failure
  */
-int fscrypt_initialize(unsigned int cop_flags)
+int fscrypt_initialize(struct super_block *sb)
 {
        int err = 0;
+       mempool_t *pool;
+
+       /* pairs with smp_store_release() below */
+       if (likely(smp_load_acquire(&fscrypt_bounce_page_pool)))
+               return 0;
 
        /* No need to allocate a bounce page pool if this FS won't use it. */
-       if (cop_flags & FS_CFLG_OWN_PAGES)
+       if (sb->s_cop->flags & FS_CFLG_OWN_PAGES)
                return 0;
 
        mutex_lock(&fscrypt_init_mutex);
@@ -328,11 +333,11 @@ int fscrypt_initialize(unsigned int cop_flags)
                goto out_unlock;
 
        err = -ENOMEM;
-       fscrypt_bounce_page_pool =
-               mempool_create_page_pool(num_prealloc_crypto_pages, 0);
-       if (!fscrypt_bounce_page_pool)
+       pool = mempool_create_page_pool(num_prealloc_crypto_pages, 0);
+       if (!pool)
                goto out_unlock;
-
+       /* pairs with smp_load_acquire() above */
+       smp_store_release(&fscrypt_bounce_page_pool, pool);
        err = 0;
 out_unlock:
        mutex_unlock(&fscrypt_init_mutex);
index 12bd61d20f69403e6779b11d42999fd4ee95bd0f..6eae3f12ad503d3de766f63f0b18d41b65816d9d 100644 (file)
@@ -110,7 +110,7 @@ int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
         * Copy the filename to the output buffer for encrypting in-place and
         * pad it with the needed number of NUL bytes.
         */
-       if (WARN_ON(olen < iname->len))
+       if (WARN_ON_ONCE(olen < iname->len))
                return -ENOBUFS;
        memcpy(out, iname->name, iname->len);
        memset(out + iname->len, 0, olen - iname->len);
@@ -570,7 +570,7 @@ u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name)
 {
        const struct fscrypt_info *ci = dir->i_crypt_info;
 
-       WARN_ON(!ci->ci_dirhash_key_initialized);
+       WARN_ON_ONCE(!ci->ci_dirhash_key_initialized);
 
        return siphash(name->name, name->len, &ci->ci_dirhash_key);
 }
index 0fec2dfc36ebe0dfb51cebfa22a4c92e76f92dc7..7ab5a7b7eef8c3dd366c3ef24742f01cd5018205 100644 (file)
@@ -101,7 +101,7 @@ static inline const u8 *fscrypt_context_nonce(const union fscrypt_context *ctx)
        case FSCRYPT_CONTEXT_V2:
                return ctx->v2.nonce;
        }
-       WARN_ON(1);
+       WARN_ON_ONCE(1);
        return NULL;
 }
 
@@ -264,7 +264,7 @@ typedef enum {
 
 /* crypto.c */
 extern struct kmem_cache *fscrypt_info_cachep;
-int fscrypt_initialize(unsigned int cop_flags);
+int fscrypt_initialize(struct super_block *sb);
 int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw,
                        u64 lblk_num, struct page *src_page,
                        struct page *dest_page, unsigned int len,
@@ -386,7 +386,7 @@ fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key,
                                 const u8 *raw_key,
                                 const struct fscrypt_info *ci)
 {
-       WARN_ON(1);
+       WARN_ON_ONCE(1);
        return -EOPNOTSUPP;
 }
 
index 7607d18b35fc0749ae7ed74b8a1d6970a24b4075..5a384dad2c72f36af28657b5983b45bf9f70207a 100644 (file)
@@ -79,7 +79,7 @@ int fscrypt_init_hkdf(struct fscrypt_hkdf *hkdf, const u8 *master_key,
                return PTR_ERR(hmac_tfm);
        }
 
-       if (WARN_ON(crypto_shash_digestsize(hmac_tfm) != sizeof(prk))) {
+       if (WARN_ON_ONCE(crypto_shash_digestsize(hmac_tfm) != sizeof(prk))) {
                err = -EINVAL;
                goto err_free_tfm;
        }
@@ -125,7 +125,7 @@ int fscrypt_hkdf_expand(const struct fscrypt_hkdf *hkdf, u8 context,
        u8 counter = 1;
        u8 tmp[HKDF_HASHLEN];
 
-       if (WARN_ON(okmlen > 255 * HKDF_HASHLEN))
+       if (WARN_ON_ONCE(okmlen > 255 * HKDF_HASHLEN))
                return -EINVAL;
 
        desc->tfm = hkdf->hmac_tfm;
index 7b8c5a1104b5867e292c4c2a31d11c93d1925d30..9e786ae66a13483b3d3463d65edef70a9160e569 100644 (file)
@@ -111,6 +111,36 @@ int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry,
 }
 EXPORT_SYMBOL_GPL(__fscrypt_prepare_lookup);
 
+/**
+ * fscrypt_prepare_lookup_partial() - prepare lookup without filename setup
+ * @dir: the encrypted directory being searched
+ * @dentry: the dentry being looked up in @dir
+ *
+ * This function should be used by the ->lookup and ->atomic_open methods of
+ * filesystems that handle filename encryption and no-key name encoding
+ * themselves and thus can't use fscrypt_prepare_lookup().  Like
+ * fscrypt_prepare_lookup(), this will try to set up the directory's encryption
+ * key and will set DCACHE_NOKEY_NAME on the dentry if the key is unavailable.
+ * However, this function doesn't set up a struct fscrypt_name for the filename.
+ *
+ * Return: 0 on success; -errno on error.  Note that the encryption key being
+ *        unavailable is not considered an error.  It is also not an error if
+ *        the encryption policy is unsupported by this kernel; that is treated
+ *        like the key being unavailable, so that files can still be deleted.
+ */
+int fscrypt_prepare_lookup_partial(struct inode *dir, struct dentry *dentry)
+{
+       int err = fscrypt_get_encryption_info(dir, true);
+
+       if (!err && !fscrypt_has_encryption_key(dir)) {
+               spin_lock(&dentry->d_lock);
+               dentry->d_flags |= DCACHE_NOKEY_NAME;
+               spin_unlock(&dentry->d_lock);
+       }
+       return err;
+}
+EXPORT_SYMBOL_GPL(fscrypt_prepare_lookup_partial);
+
 int __fscrypt_prepare_readdir(struct inode *dir)
 {
        return fscrypt_get_encryption_info(dir, true);
@@ -315,7 +345,7 @@ const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
        int err;
 
        /* This is for encrypted symlinks only */
-       if (WARN_ON(!IS_ENCRYPTED(inode)))
+       if (WARN_ON_ONCE(!IS_ENCRYPTED(inode)))
                return ERR_PTR(-EINVAL);
 
        /* If the decrypted target is already cached, just return it. */
index 13d336a6cc5da5675fa322d3d793c13a56291848..7cbb1fd872accadf435d7153ef74d1ff801f757b 100644 (file)
@@ -73,7 +73,7 @@ void fscrypt_put_master_key(struct fscrypt_master_key *mk)
         * fscrypt_master_key struct itself after an RCU grace period ensures
         * that concurrent keyring lookups can no longer find it.
         */
-       WARN_ON(refcount_read(&mk->mk_active_refs) != 0);
+       WARN_ON_ONCE(refcount_read(&mk->mk_active_refs) != 0);
        key_put(mk->mk_users);
        mk->mk_users = NULL;
        call_rcu(&mk->mk_rcu_head, fscrypt_free_master_key);
@@ -92,7 +92,7 @@ void fscrypt_put_master_key_activeref(struct super_block *sb,
         * destroying any subkeys embedded in it.
         */
 
-       if (WARN_ON(!sb->s_master_keys))
+       if (WARN_ON_ONCE(!sb->s_master_keys))
                return;
        spin_lock(&sb->s_master_keys->lock);
        hlist_del_rcu(&mk->mk_node);
@@ -102,8 +102,8 @@ void fscrypt_put_master_key_activeref(struct super_block *sb,
         * ->mk_active_refs == 0 implies that ->mk_secret is not present and
         * that ->mk_decrypted_inodes is empty.
         */
-       WARN_ON(is_master_key_secret_present(&mk->mk_secret));
-       WARN_ON(!list_empty(&mk->mk_decrypted_inodes));
+       WARN_ON_ONCE(is_master_key_secret_present(&mk->mk_secret));
+       WARN_ON_ONCE(!list_empty(&mk->mk_decrypted_inodes));
 
        for (i = 0; i <= FSCRYPT_MODE_MAX; i++) {
                fscrypt_destroy_prepared_key(
@@ -237,9 +237,9 @@ void fscrypt_destroy_keyring(struct super_block *sb)
                         * with ->mk_secret.  There should be no structural refs
                         * beyond the one associated with the active ref.
                         */
-                       WARN_ON(refcount_read(&mk->mk_active_refs) != 1);
-                       WARN_ON(refcount_read(&mk->mk_struct_refs) != 1);
-                       WARN_ON(!is_master_key_secret_present(&mk->mk_secret));
+                       WARN_ON_ONCE(refcount_read(&mk->mk_active_refs) != 1);
+                       WARN_ON_ONCE(refcount_read(&mk->mk_struct_refs) != 1);
+                       WARN_ON_ONCE(!is_master_key_secret_present(&mk->mk_secret));
                        wipe_master_key_secret(&mk->mk_secret);
                        fscrypt_put_master_key_activeref(sb, mk);
                }
index aa94fba9d17e7761de39360d2c344de232bfc7cc..361f41ef46c787d8a317e536e0bf72fe638294dc 100644 (file)
@@ -125,7 +125,7 @@ fscrypt_allocate_skcipher(struct fscrypt_mode *mode, const u8 *raw_key,
                pr_info("fscrypt: %s using implementation \"%s\"\n",
                        mode->friendly_name, crypto_skcipher_driver_name(tfm));
        }
-       if (WARN_ON(crypto_skcipher_ivsize(tfm) != mode->ivsize)) {
+       if (WARN_ON_ONCE(crypto_skcipher_ivsize(tfm) != mode->ivsize)) {
                err = -EINVAL;
                goto err_free_tfm;
        }
@@ -199,7 +199,7 @@ static int setup_per_mode_enc_key(struct fscrypt_info *ci,
        unsigned int hkdf_infolen = 0;
        int err;
 
-       if (WARN_ON(mode_num > FSCRYPT_MODE_MAX))
+       if (WARN_ON_ONCE(mode_num > FSCRYPT_MODE_MAX))
                return -EINVAL;
 
        prep_key = &keys[mode_num];
@@ -282,8 +282,8 @@ int fscrypt_derive_dirhash_key(struct fscrypt_info *ci,
 void fscrypt_hash_inode_number(struct fscrypt_info *ci,
                               const struct fscrypt_master_key *mk)
 {
-       WARN_ON(ci->ci_inode->i_ino == 0);
-       WARN_ON(!mk->mk_ino_hash_key_initialized);
+       WARN_ON_ONCE(ci->ci_inode->i_ino == 0);
+       WARN_ON_ONCE(!mk->mk_ino_hash_key_initialized);
 
        ci->ci_hashed_ino = (u32)siphash_1u64(ci->ci_inode->i_ino,
                                              &mk->mk_ino_hash_key);
@@ -503,7 +503,7 @@ static int setup_file_encryption_key(struct fscrypt_info *ci,
                err = fscrypt_setup_v2_file_key(ci, mk, need_dirhash_key);
                break;
        default:
-               WARN_ON(1);
+               WARN_ON_ONCE(1);
                err = -EINVAL;
                break;
        }
@@ -560,7 +560,7 @@ fscrypt_setup_encryption_info(struct inode *inode,
        struct fscrypt_master_key *mk = NULL;
        int res;
 
-       res = fscrypt_initialize(inode->i_sb->s_cop->flags);
+       res = fscrypt_initialize(inode->i_sb);
        if (res)
                return res;
 
@@ -577,7 +577,7 @@ fscrypt_setup_encryption_info(struct inode *inode,
                res = PTR_ERR(mode);
                goto out;
        }
-       WARN_ON(mode->ivsize > FSCRYPT_MAX_IV_SIZE);
+       WARN_ON_ONCE(mode->ivsize > FSCRYPT_MAX_IV_SIZE);
        crypt_info->ci_mode = mode;
 
        res = setup_file_encryption_key(crypt_info, need_dirhash_key, &mk);
index 3b5fcb6402eaefeb7397dcbdec3542d654ff8b07..f4456ecb3f87768478a496ffbe4c67318719ea83 100644 (file)
@@ -48,7 +48,7 @@ int fscrypt_policy_to_key_spec(const union fscrypt_policy *policy,
                       FSCRYPT_KEY_IDENTIFIER_SIZE);
                return 0;
        default:
-               WARN_ON(1);
+               WARN_ON_ONCE(1);
                return -EINVAL;
        }
 }
@@ -463,7 +463,7 @@ static int set_encryption_policy(struct inode *inode,
                                     current->comm, current->pid);
                break;
        default:
-               WARN_ON(1);
+               WARN_ON_ONCE(1);
                return -EINVAL;
        }
 
index e0a49c3125ebc22ada8092c88c5009d2dadad429..a69f1302051d3c37b23a198dc0457b9081f05488 100644 (file)
@@ -359,6 +359,7 @@ int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry,
                             unsigned int flags);
 int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry,
                             struct fscrypt_name *fname);
+int fscrypt_prepare_lookup_partial(struct inode *dir, struct dentry *dentry);
 int __fscrypt_prepare_readdir(struct inode *dir);
 int __fscrypt_prepare_setattr(struct dentry *dentry, struct iattr *attr);
 int fscrypt_prepare_setflags(struct inode *inode,
@@ -673,6 +674,12 @@ static inline int __fscrypt_prepare_lookup(struct inode *dir,
        return -EOPNOTSUPP;
 }
 
+static inline int fscrypt_prepare_lookup_partial(struct inode *dir,
+                                                struct dentry *dentry)
+{
+       return -EOPNOTSUPP;
+}
+
 static inline int __fscrypt_prepare_readdir(struct inode *dir)
 {
        return -EOPNOTSUPP;