09c434b8a0047 (Thomas Gleixner 2019-05-19 13:08:20 +0100 1) // SPDX-License-Identifier: GPL-2.0-only
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 2) /*
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 3) * This contains encryption functions for per-file encryption.
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 4) *
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 5) * Copyright (C) 2015, Google, Inc.
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 6) * Copyright (C) 2015, Motorola Mobility
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 7) *
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 8) * Written by Michael Halcrow, 2014.
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 9) *
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 10) * Filename encryption additions
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 11) * Uday Savagaonkar, 2014
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 12) * Encryption policy handling additions
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 13) * Ildar Muslukhov, 2014
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 14) * Add fscrypt_pullback_bio_page()
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 15) * Jaegeuk Kim, 2015.
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 16) *
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 17) * This has not yet undergone a rigorous security audit.
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 18) *
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 19) * The usage of AES-XTS should conform to recommendations in NIST
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 20) * Special Publication 800-38E and IEEE P1619/D16.
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 21) */
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 22)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 23) #include <linux/pagemap.h>
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 24) #include <linux/mempool.h>
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 25) #include <linux/module.h>
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 26) #include <linux/scatterlist.h>
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 27) #include <linux/ratelimit.h>
a575784c6c13b (Eric Biggers 2018-01-05 10:45:00 -0800 28) #include <crypto/skcipher.h>
cc4e0df038ddb (Theodore Ts'o 2016-11-26 22:05:18 -0500 29) #include "fscrypt_private.h"
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 30)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 31) static unsigned int num_prealloc_crypto_pages = 32;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 32)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 33) module_param(num_prealloc_crypto_pages, uint, 0444);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 34) MODULE_PARM_DESC(num_prealloc_crypto_pages,
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 35) "Number of crypto pages to preallocate");
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 36)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 37) static mempool_t *fscrypt_bounce_page_pool = NULL;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 38)
0cb8dae4a0df2 (Eric Biggers 2018-04-18 11:09:47 -0700 39) static struct workqueue_struct *fscrypt_read_workqueue;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 40) static DEFINE_MUTEX(fscrypt_init_mutex);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 41)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 42) struct kmem_cache *fscrypt_info_cachep;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 43)
0cb8dae4a0df2 (Eric Biggers 2018-04-18 11:09:47 -0700 44) void fscrypt_enqueue_decrypt_work(struct work_struct *work)
0cb8dae4a0df2 (Eric Biggers 2018-04-18 11:09:47 -0700 45) {
0cb8dae4a0df2 (Eric Biggers 2018-04-18 11:09:47 -0700 46) queue_work(fscrypt_read_workqueue, work);
0cb8dae4a0df2 (Eric Biggers 2018-04-18 11:09:47 -0700 47) }
0cb8dae4a0df2 (Eric Biggers 2018-04-18 11:09:47 -0700 48) EXPORT_SYMBOL(fscrypt_enqueue_decrypt_work);
0cb8dae4a0df2 (Eric Biggers 2018-04-18 11:09:47 -0700 49)
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 50) struct page *fscrypt_alloc_bounce_page(gfp_t gfp_flags)
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 51) {
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 52) return mempool_alloc(fscrypt_bounce_page_pool, gfp_flags);
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 53) }
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 54)
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 55) /**
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 56) * fscrypt_free_bounce_page() - free a ciphertext bounce page
d2fe97545a1e2 (Eric Biggers 2020-05-11 12:13:56 -0700 57) * @bounce_page: the bounce page to free, or NULL
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 58) *
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 59) * Free a bounce page that was allocated by fscrypt_encrypt_pagecache_blocks(),
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 60) * or by fscrypt_alloc_bounce_page() directly.
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 61) */
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 62) void fscrypt_free_bounce_page(struct page *bounce_page)
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 63) {
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 64) if (!bounce_page)
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 65) return;
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 66) set_page_private(bounce_page, (unsigned long)NULL);
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 67) ClearPagePrivate(bounce_page);
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 68) mempool_free(bounce_page, fscrypt_bounce_page_pool);
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 69) }
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 70) EXPORT_SYMBOL(fscrypt_free_bounce_page);
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 71)
8094c3ceb21ad (Eric Biggers 2019-01-06 08:36:21 -0500 72) void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num,
8094c3ceb21ad (Eric Biggers 2019-01-06 08:36:21 -0500 73) const struct fscrypt_info *ci)
8094c3ceb21ad (Eric Biggers 2019-01-06 08:36:21 -0500 74) {
b103fb7653fff (Eric Biggers 2019-10-24 14:54:36 -0700 75) u8 flags = fscrypt_policy_flags(&ci->ci_policy);
b103fb7653fff (Eric Biggers 2019-10-24 14:54:36 -0700 76)
8094c3ceb21ad (Eric Biggers 2019-01-06 08:36:21 -0500 77) memset(iv, 0, ci->ci_mode->ivsize);
8094c3ceb21ad (Eric Biggers 2019-01-06 08:36:21 -0500 78)
b103fb7653fff (Eric Biggers 2019-10-24 14:54:36 -0700 79) if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) {
e3b1078bedd32 (Eric Biggers 2020-05-15 13:41:41 -0700 80) WARN_ON_ONCE(lblk_num > U32_MAX);
e3b1078bedd32 (Eric Biggers 2020-05-15 13:41:41 -0700 81) WARN_ON_ONCE(ci->ci_inode->i_ino > U32_MAX);
b103fb7653fff (Eric Biggers 2019-10-24 14:54:36 -0700 82) lblk_num |= (u64)ci->ci_inode->i_ino << 32;
e3b1078bedd32 (Eric Biggers 2020-05-15 13:41:41 -0700 83) } else if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) {
e3b1078bedd32 (Eric Biggers 2020-05-15 13:41:41 -0700 84) WARN_ON_ONCE(lblk_num > U32_MAX);
e3b1078bedd32 (Eric Biggers 2020-05-15 13:41:41 -0700 85) lblk_num = (u32)(ci->ci_hashed_ino + lblk_num);
b103fb7653fff (Eric Biggers 2019-10-24 14:54:36 -0700 86) } else if (flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) {
1d6217a4f9905 (Eric Biggers 2020-07-08 14:57:22 -0700 87) memcpy(iv->nonce, ci->ci_nonce, FSCRYPT_FILE_NONCE_SIZE);
b103fb7653fff (Eric Biggers 2019-10-24 14:54:36 -0700 88) }
b103fb7653fff (Eric Biggers 2019-10-24 14:54:36 -0700 89) iv->lblk_num = cpu_to_le64(lblk_num);
8094c3ceb21ad (Eric Biggers 2019-01-06 08:36:21 -0500 90) }
8094c3ceb21ad (Eric Biggers 2019-01-06 08:36:21 -0500 91)
f47fcbb2b578b (Eric Biggers 2019-05-20 09:29:41 -0700 92) /* Encrypt or decrypt a single filesystem block of file contents */
f47fcbb2b578b (Eric Biggers 2019-05-20 09:29:41 -0700 93) int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw,
f47fcbb2b578b (Eric Biggers 2019-05-20 09:29:41 -0700 94) u64 lblk_num, struct page *src_page,
f47fcbb2b578b (Eric Biggers 2019-05-20 09:29:41 -0700 95) struct page *dest_page, unsigned int len,
f47fcbb2b578b (Eric Biggers 2019-05-20 09:29:41 -0700 96) unsigned int offs, gfp_t gfp_flags)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 97) {
8094c3ceb21ad (Eric Biggers 2019-01-06 08:36:21 -0500 98) union fscrypt_iv iv;
d407574e79482 (Linus Torvalds 2016-03-21 11:03:02 -0700 99) struct skcipher_request *req = NULL;
d0082e1a7c8df (Gilad Ben-Yossef 2017-10-18 08:00:44 +0100 100) DECLARE_CRYPTO_WAIT(wait);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 101) struct scatterlist dst, src;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 102) struct fscrypt_info *ci = inode->i_crypt_info;
5fee36095cda4 (Satya Tangirala 2020-07-02 01:56:05 +0000 103) struct crypto_skcipher *tfm = ci->ci_enc_key.tfm;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 104) int res = 0;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 105)
eeacfdc68a104 (Eric Biggers 2019-05-20 09:29:42 -0700 106) if (WARN_ON_ONCE(len <= 0))
eeacfdc68a104 (Eric Biggers 2019-05-20 09:29:42 -0700 107) return -EINVAL;
eeacfdc68a104 (Eric Biggers 2019-05-20 09:29:42 -0700 108) if (WARN_ON_ONCE(len % FS_CRYPTO_BLOCK_SIZE != 0))
eeacfdc68a104 (Eric Biggers 2019-05-20 09:29:42 -0700 109) return -EINVAL;
1400451f04f2f (David Gstir 2016-12-06 23:53:55 +0100 110)
8094c3ceb21ad (Eric Biggers 2019-01-06 08:36:21 -0500 111) fscrypt_generate_iv(&iv, lblk_num, ci);
b7e7cf7a66a27 (Daniel Walter 2017-06-19 09:27:58 +0200 112)
b32e4482aadfd (Jaegeuk Kim 2016-04-11 15:51:57 -0700 113) req = skcipher_request_alloc(tfm, gfp_flags);
c90fd77562479 (Eric Biggers 2018-04-30 15:51:38 -0700 114) if (!req)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 115) return -ENOMEM;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 116)
d407574e79482 (Linus Torvalds 2016-03-21 11:03:02 -0700 117) skcipher_request_set_callback(
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 118) req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
d0082e1a7c8df (Gilad Ben-Yossef 2017-10-18 08:00:44 +0100 119) crypto_req_done, &wait);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 120)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 121) sg_init_table(&dst, 1);
1400451f04f2f (David Gstir 2016-12-06 23:53:55 +0100 122) sg_set_page(&dst, dest_page, len, offs);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 123) sg_init_table(&src, 1);
1400451f04f2f (David Gstir 2016-12-06 23:53:55 +0100 124) sg_set_page(&src, src_page, len, offs);
b7e7cf7a66a27 (Daniel Walter 2017-06-19 09:27:58 +0200 125) skcipher_request_set_crypt(req, &src, &dst, len, &iv);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 126) if (rw == FS_DECRYPT)
d0082e1a7c8df (Gilad Ben-Yossef 2017-10-18 08:00:44 +0100 127) res = crypto_wait_req(crypto_skcipher_decrypt(req), &wait);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 128) else
d0082e1a7c8df (Gilad Ben-Yossef 2017-10-18 08:00:44 +0100 129) res = crypto_wait_req(crypto_skcipher_encrypt(req), &wait);
d407574e79482 (Linus Torvalds 2016-03-21 11:03:02 -0700 130) skcipher_request_free(req);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 131) if (res) {
886da8b39cf27 (Eric Biggers 2019-07-24 11:07:58 -0700 132) fscrypt_err(inode, "%scryption failed for block %llu: %d",
886da8b39cf27 (Eric Biggers 2019-07-24 11:07:58 -0700 133) (rw == FS_DECRYPT ? "De" : "En"), lblk_num, res);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 134) return res;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 135) }
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 136) return 0;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 137) }
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 138)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 139) /**
d2fe97545a1e2 (Eric Biggers 2020-05-11 12:13:56 -0700 140) * fscrypt_encrypt_pagecache_blocks() - Encrypt filesystem blocks from a
d2fe97545a1e2 (Eric Biggers 2020-05-11 12:13:56 -0700 141) * pagecache page
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 142) * @page: The locked pagecache page containing the block(s) to encrypt
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 143) * @len: Total size of the block(s) to encrypt. Must be a nonzero
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 144) * multiple of the filesystem's block size.
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 145) * @offs: Byte offset within @page of the first block to encrypt. Must be
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 146) * a multiple of the filesystem's block size.
2d8f7f119b0b2 (Eric Biggers 2019-12-31 12:10:26 -0600 147) * @gfp_flags: Memory allocation flags. See details below.
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 148) *
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 149) * A new bounce page is allocated, and the specified block(s) are encrypted into
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 150) * it. In the bounce page, the ciphertext block(s) will be located at the same
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 151) * offsets at which the plaintext block(s) were located in the source page; any
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 152) * other parts of the bounce page will be left uninitialized. However, normally
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 153) * blocksize == PAGE_SIZE and the whole page is encrypted at once.
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 154) *
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 155) * This is for use by the filesystem's ->writepages() method.
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 156) *
2d8f7f119b0b2 (Eric Biggers 2019-12-31 12:10:26 -0600 157) * The bounce page allocation is mempool-backed, so it will always succeed when
2d8f7f119b0b2 (Eric Biggers 2019-12-31 12:10:26 -0600 158) * @gfp_flags includes __GFP_DIRECT_RECLAIM, e.g. when it's GFP_NOFS. However,
2d8f7f119b0b2 (Eric Biggers 2019-12-31 12:10:26 -0600 159) * only the first page of each bio can be allocated this way. To prevent
2d8f7f119b0b2 (Eric Biggers 2019-12-31 12:10:26 -0600 160) * deadlocks, for any additional pages a mask like GFP_NOWAIT must be used.
2d8f7f119b0b2 (Eric Biggers 2019-12-31 12:10:26 -0600 161) *
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 162) * Return: the new encrypted bounce page on success; an ERR_PTR() on failure
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 163) */
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 164) struct page *fscrypt_encrypt_pagecache_blocks(struct page *page,
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 165) unsigned int len,
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 166) unsigned int offs,
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 167) gfp_t gfp_flags)
7821d4dd4589c (David Gstir 2016-11-13 22:20:46 +0100 168)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 169) {
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 170) const struct inode *inode = page->mapping->host;
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 171) const unsigned int blockbits = inode->i_blkbits;
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 172) const unsigned int blocksize = 1 << blockbits;
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 173) struct page *ciphertext_page;
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 174) u64 lblk_num = ((u64)page->index << (PAGE_SHIFT - blockbits)) +
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 175) (offs >> blockbits);
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 176) unsigned int i;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 177) int err;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 178)
eeacfdc68a104 (Eric Biggers 2019-05-20 09:29:42 -0700 179) if (WARN_ON_ONCE(!PageLocked(page)))
eeacfdc68a104 (Eric Biggers 2019-05-20 09:29:42 -0700 180) return ERR_PTR(-EINVAL);
bd7b8290388dd (David Gstir 2016-12-06 23:53:56 +0100 181)
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 182) if (WARN_ON_ONCE(len <= 0 || !IS_ALIGNED(len | offs, blocksize)))
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 183) return ERR_PTR(-EINVAL);
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 184)
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 185) ciphertext_page = fscrypt_alloc_bounce_page(gfp_flags);
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 186) if (!ciphertext_page)
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 187) return ERR_PTR(-ENOMEM);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 188)
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 189) for (i = offs; i < offs + len; i += blocksize, lblk_num++) {
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 190) err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num,
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 191) page, ciphertext_page,
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 192) blocksize, i, gfp_flags);
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 193) if (err) {
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 194) fscrypt_free_bounce_page(ciphertext_page);
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 195) return ERR_PTR(err);
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 196) }
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 197) }
9e532772b4e36 (David Gstir 2016-12-06 23:53:54 +0100 198) SetPagePrivate(ciphertext_page);
d2d0727b1654e (Eric Biggers 2019-05-20 09:29:39 -0700 199) set_page_private(ciphertext_page, (unsigned long)page);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 200) return ciphertext_page;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 201) }
53bc1d854c64c (Eric Biggers 2019-05-20 09:29:44 -0700 202) EXPORT_SYMBOL(fscrypt_encrypt_pagecache_blocks);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 203)
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 204) /**
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 205) * fscrypt_encrypt_block_inplace() - Encrypt a filesystem block in-place
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 206) * @inode: The inode to which this block belongs
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 207) * @page: The page containing the block to encrypt
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 208) * @len: Size of block to encrypt. Doesn't need to be a multiple of the
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 209) * fs block size, but must be a multiple of FS_CRYPTO_BLOCK_SIZE.
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 210) * @offs: Byte offset within @page at which the block to encrypt begins
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 211) * @lblk_num: Filesystem logical block number of the block, i.e. the 0-based
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 212) * number of the block within the file
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 213) * @gfp_flags: Memory allocation flags
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 214) *
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 215) * Encrypt a possibly-compressed filesystem block that is located in an
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 216) * arbitrary page, not necessarily in the original pagecache page. The @inode
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 217) * and @lblk_num must be specified, as they can't be determined from @page.
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 218) *
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 219) * Return: 0 on success; -errno on failure
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 220) */
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 221) int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page,
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 222) unsigned int len, unsigned int offs,
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 223) u64 lblk_num, gfp_t gfp_flags)
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 224) {
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 225) return fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num, page, page,
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 226) len, offs, gfp_flags);
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 227) }
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 228) EXPORT_SYMBOL(fscrypt_encrypt_block_inplace);
03569f2fb8e73 (Eric Biggers 2019-05-20 09:29:43 -0700 229)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 230) /**
d2fe97545a1e2 (Eric Biggers 2020-05-11 12:13:56 -0700 231) * fscrypt_decrypt_pagecache_blocks() - Decrypt filesystem blocks in a
d2fe97545a1e2 (Eric Biggers 2020-05-11 12:13:56 -0700 232) * pagecache page
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 233) * @page: The locked pagecache page containing the block(s) to decrypt
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 234) * @len: Total size of the block(s) to decrypt. Must be a nonzero
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 235) * multiple of the filesystem's block size.
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 236) * @offs: Byte offset within @page of the first block to decrypt. Must be
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 237) * a multiple of the filesystem's block size.
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 238) *
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 239) * The specified block(s) are decrypted in-place within the pagecache page,
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 240) * which must still be locked and not uptodate. Normally, blocksize ==
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 241) * PAGE_SIZE and the whole page is decrypted at once.
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 242) *
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 243) * This is for use by the filesystem's ->readpages() method.
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 244) *
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 245) * Return: 0 on success; -errno on failure
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 246) */
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 247) int fscrypt_decrypt_pagecache_blocks(struct page *page, unsigned int len,
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 248) unsigned int offs)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 249) {
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 250) const struct inode *inode = page->mapping->host;
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 251) const unsigned int blockbits = inode->i_blkbits;
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 252) const unsigned int blocksize = 1 << blockbits;
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 253) u64 lblk_num = ((u64)page->index << (PAGE_SHIFT - blockbits)) +
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 254) (offs >> blockbits);
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 255) unsigned int i;
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 256) int err;
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 257)
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 258) if (WARN_ON_ONCE(!PageLocked(page)))
eeacfdc68a104 (Eric Biggers 2019-05-20 09:29:42 -0700 259) return -EINVAL;
bd7b8290388dd (David Gstir 2016-12-06 23:53:56 +0100 260)
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 261) if (WARN_ON_ONCE(len <= 0 || !IS_ALIGNED(len | offs, blocksize)))
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 262) return -EINVAL;
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 263)
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 264) for (i = offs; i < offs + len; i += blocksize, lblk_num++) {
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 265) err = fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page,
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 266) page, blocksize, i, GFP_NOFS);
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 267) if (err)
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 268) return err;
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 269) }
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 270) return 0;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 271) }
aa8bc1ac6ef32 (Eric Biggers 2019-05-20 09:29:47 -0700 272) EXPORT_SYMBOL(fscrypt_decrypt_pagecache_blocks);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 273)
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 274) /**
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 275) * fscrypt_decrypt_block_inplace() - Decrypt a filesystem block in-place
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 276) * @inode: The inode to which this block belongs
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 277) * @page: The page containing the block to decrypt
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 278) * @len: Size of block to decrypt. Doesn't need to be a multiple of the
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 279) * fs block size, but must be a multiple of FS_CRYPTO_BLOCK_SIZE.
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 280) * @offs: Byte offset within @page at which the block to decrypt begins
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 281) * @lblk_num: Filesystem logical block number of the block, i.e. the 0-based
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 282) * number of the block within the file
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 283) *
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 284) * Decrypt a possibly-compressed filesystem block that is located in an
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 285) * arbitrary page, not necessarily in the original pagecache page. The @inode
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 286) * and @lblk_num must be specified, as they can't be determined from @page.
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 287) *
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 288) * Return: 0 on success; -errno on failure
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 289) */
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 290) int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page,
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 291) unsigned int len, unsigned int offs,
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 292) u64 lblk_num)
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 293) {
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 294) return fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page, page,
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 295) len, offs, GFP_NOFS);
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 296) }
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 297) EXPORT_SYMBOL(fscrypt_decrypt_block_inplace);
41adbcb7267b0 (Eric Biggers 2019-05-20 09:29:46 -0700 298)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 299) /**
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 300) * fscrypt_initialize() - allocate major buffers for fs encryption.
f32d7ac20a586 (David Gstir 2016-12-06 23:53:57 +0100 301) * @cop_flags: fscrypt operations flags
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 302) *
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 303) * We only call this when we start accessing encrypted files, since it
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 304) * results in memory getting allocated that wouldn't otherwise be used.
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 305) *
1565bdad59e97 (Eric Biggers 2019-10-09 16:34:17 -0700 306) * Return: 0 on success; -errno on failure
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 307) */
f32d7ac20a586 (David Gstir 2016-12-06 23:53:57 +0100 308) int fscrypt_initialize(unsigned int cop_flags)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 309) {
1565bdad59e97 (Eric Biggers 2019-10-09 16:34:17 -0700 310) int err = 0;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 311)
a0b3bc855374c (Eric Biggers 2017-10-29 06:30:19 -0400 312) /* No need to allocate a bounce page pool if this FS won't use it. */
a0b3bc855374c (Eric Biggers 2017-10-29 06:30:19 -0400 313) if (cop_flags & FS_CFLG_OWN_PAGES)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 314) return 0;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 315)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 316) mutex_lock(&fscrypt_init_mutex);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 317) if (fscrypt_bounce_page_pool)
1565bdad59e97 (Eric Biggers 2019-10-09 16:34:17 -0700 318) goto out_unlock;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 319)
1565bdad59e97 (Eric Biggers 2019-10-09 16:34:17 -0700 320) err = -ENOMEM;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 321) fscrypt_bounce_page_pool =
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 322) mempool_create_page_pool(num_prealloc_crypto_pages, 0);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 323) if (!fscrypt_bounce_page_pool)
1565bdad59e97 (Eric Biggers 2019-10-09 16:34:17 -0700 324) goto out_unlock;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 325)
1565bdad59e97 (Eric Biggers 2019-10-09 16:34:17 -0700 326) err = 0;
1565bdad59e97 (Eric Biggers 2019-10-09 16:34:17 -0700 327) out_unlock:
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 328) mutex_unlock(&fscrypt_init_mutex);
1565bdad59e97 (Eric Biggers 2019-10-09 16:34:17 -0700 329) return err;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 330) }
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 331)
886da8b39cf27 (Eric Biggers 2019-07-24 11:07:58 -0700 332) void fscrypt_msg(const struct inode *inode, const char *level,
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 333) const char *fmt, ...)
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 334) {
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 335) static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 336) DEFAULT_RATELIMIT_BURST);
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 337) struct va_format vaf;
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 338) va_list args;
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 339)
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 340) if (!__ratelimit(&rs))
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 341) return;
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 342)
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 343) va_start(args, fmt);
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 344) vaf.fmt = fmt;
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 345) vaf.va = &args;
ae9ff8ad81b13 (Eric Biggers 2020-09-16 21:11:29 -0700 346) if (inode && inode->i_ino)
886da8b39cf27 (Eric Biggers 2019-07-24 11:07:58 -0700 347) printk("%sfscrypt (%s, inode %lu): %pV\n",
886da8b39cf27 (Eric Biggers 2019-07-24 11:07:58 -0700 348) level, inode->i_sb->s_id, inode->i_ino, &vaf);
ae9ff8ad81b13 (Eric Biggers 2020-09-16 21:11:29 -0700 349) else if (inode)
ae9ff8ad81b13 (Eric Biggers 2020-09-16 21:11:29 -0700 350) printk("%sfscrypt (%s): %pV\n", level, inode->i_sb->s_id, &vaf);
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 351) else
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 352) printk("%sfscrypt: %pV\n", level, &vaf);
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 353) va_end(args);
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 354) }
544d08fde258b (Eric Biggers 2018-04-30 15:51:47 -0700 355)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 356) /**
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 357) * fscrypt_init() - Set up for fs encryption.
d2fe97545a1e2 (Eric Biggers 2020-05-11 12:13:56 -0700 358) *
d2fe97545a1e2 (Eric Biggers 2020-05-11 12:13:56 -0700 359) * Return: 0 on success; -errno on failure
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 360) */
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 361) static int __init fscrypt_init(void)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 362) {
22d94f493bfb4 (Eric Biggers 2019-08-04 19:35:46 -0700 363) int err = -ENOMEM;
22d94f493bfb4 (Eric Biggers 2019-08-04 19:35:46 -0700 364)
36dd26e0c8d42 (Eric Biggers 2018-04-20 16:30:02 -0700 365) /*
36dd26e0c8d42 (Eric Biggers 2018-04-20 16:30:02 -0700 366) * Use an unbound workqueue to allow bios to be decrypted in parallel
36dd26e0c8d42 (Eric Biggers 2018-04-20 16:30:02 -0700 367) * even when they happen to complete on the same CPU. This sacrifices
36dd26e0c8d42 (Eric Biggers 2018-04-20 16:30:02 -0700 368) * locality, but it's worthwhile since decryption is CPU-intensive.
36dd26e0c8d42 (Eric Biggers 2018-04-20 16:30:02 -0700 369) *
36dd26e0c8d42 (Eric Biggers 2018-04-20 16:30:02 -0700 370) * Also use a high-priority workqueue to prioritize decryption work,
36dd26e0c8d42 (Eric Biggers 2018-04-20 16:30:02 -0700 371) * which blocks reads from completing, over regular application tasks.
36dd26e0c8d42 (Eric Biggers 2018-04-20 16:30:02 -0700 372) */
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 373) fscrypt_read_workqueue = alloc_workqueue("fscrypt_read_queue",
36dd26e0c8d42 (Eric Biggers 2018-04-20 16:30:02 -0700 374) WQ_UNBOUND | WQ_HIGHPRI,
36dd26e0c8d42 (Eric Biggers 2018-04-20 16:30:02 -0700 375) num_online_cpus());
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 376) if (!fscrypt_read_workqueue)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 377) goto fail;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 378)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 379) fscrypt_info_cachep = KMEM_CACHE(fscrypt_info, SLAB_RECLAIM_ACCOUNT);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 380) if (!fscrypt_info_cachep)
1565bdad59e97 (Eric Biggers 2019-10-09 16:34:17 -0700 381) goto fail_free_queue;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 382)
22d94f493bfb4 (Eric Biggers 2019-08-04 19:35:46 -0700 383) err = fscrypt_init_keyring();
22d94f493bfb4 (Eric Biggers 2019-08-04 19:35:46 -0700 384) if (err)
22d94f493bfb4 (Eric Biggers 2019-08-04 19:35:46 -0700 385) goto fail_free_info;
22d94f493bfb4 (Eric Biggers 2019-08-04 19:35:46 -0700 386)
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 387) return 0;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 388)
22d94f493bfb4 (Eric Biggers 2019-08-04 19:35:46 -0700 389) fail_free_info:
22d94f493bfb4 (Eric Biggers 2019-08-04 19:35:46 -0700 390) kmem_cache_destroy(fscrypt_info_cachep);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 391) fail_free_queue:
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 392) destroy_workqueue(fscrypt_read_workqueue);
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 393) fail:
22d94f493bfb4 (Eric Biggers 2019-08-04 19:35:46 -0700 394) return err;
0b81d07790726 (Jaegeuk Kim 2015-05-15 16:26:10 -0700 395) }
75798f85f2bad (Eric Biggers 2019-07-24 11:07:57 -0700 396) late_initcall(fscrypt_init)