Loading fs/crypto/crypto.c +51 −32 Original line number Diff line number Diff line Loading @@ -88,7 +88,7 @@ EXPORT_SYMBOL(fscrypt_release_ctx); * Return: An allocated and initialized encryption context on success; error * value or NULL otherwise. */ struct fscrypt_ctx *fscrypt_get_ctx(struct inode *inode, gfp_t gfp_flags) struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode, gfp_t gfp_flags) { struct fscrypt_ctx *ctx = NULL; struct fscrypt_info *ci = inode->i_crypt_info; Loading Loading @@ -146,9 +146,10 @@ typedef enum { FS_ENCRYPT, } fscrypt_direction_t; static int do_page_crypto(struct inode *inode, static int do_page_crypto(const struct inode *inode, fscrypt_direction_t rw, pgoff_t index, struct page *src_page, struct page *dest_page, unsigned int src_len, unsigned int src_offset, gfp_t gfp_flags) { struct { Loading Loading @@ -179,10 +180,10 @@ static int do_page_crypto(struct inode *inode, memset(xts_tweak.padding, 0, sizeof(xts_tweak.padding)); sg_init_table(&dst, 1); sg_set_page(&dst, dest_page, PAGE_SIZE, 0); sg_set_page(&dst, dest_page, src_len, src_offset); sg_init_table(&src, 1); sg_set_page(&src, src_page, PAGE_SIZE, 0); skcipher_request_set_crypt(req, &src, &dst, PAGE_SIZE, &xts_tweak); sg_set_page(&src, src_page, src_len, src_offset); skcipher_request_set_crypt(req, &src, &dst, src_len, &xts_tweak); if (rw == FS_DECRYPT) res = crypto_skcipher_decrypt(req); else Loading Loading @@ -215,10 +216,15 @@ static struct page *alloc_bounce_page(struct fscrypt_ctx *ctx, gfp_t gfp_flags) * fscypt_encrypt_page() - Encrypts a page * @inode: The inode for which the encryption should take place * @plaintext_page: The page to encrypt. Must be locked. * @plaintext_len: Length of plaintext within page * @plaintext_offset: Offset of plaintext within page * @index: Index for encryption. This is mainly the page index, but * but might be different for multiple calls on same page. * @gfp_flags: The gfp flag for memory allocation * * Allocates a ciphertext page and encrypts plaintext_page into it using the ctx * encryption context. * Encrypts plaintext_page using the ctx encryption context. If * the filesystem supports it, encryption is performed in-place, otherwise a * new ciphertext_page is allocated and returned. * * Called on the page write path. The caller must call * fscrypt_restore_control_page() on the returned ciphertext page to Loading @@ -227,35 +233,44 @@ static struct page *alloc_bounce_page(struct fscrypt_ctx *ctx, gfp_t gfp_flags) * Return: An allocated page with the encrypted content on success. Else, an * error value or NULL. */ struct page *fscrypt_encrypt_page(struct inode *inode, struct page *plaintext_page, gfp_t gfp_flags) struct page *fscrypt_encrypt_page(const struct inode *inode, struct page *plaintext_page, unsigned int plaintext_len, unsigned int plaintext_offset, pgoff_t index, gfp_t gfp_flags) { struct fscrypt_ctx *ctx; struct page *ciphertext_page = NULL; struct page *ciphertext_page = plaintext_page; int err; BUG_ON(!PageLocked(plaintext_page)); BUG_ON(plaintext_len % FS_CRYPTO_BLOCK_SIZE != 0); ctx = fscrypt_get_ctx(inode, gfp_flags); if (IS_ERR(ctx)) return (struct page *)ctx; if (!(inode->i_sb->s_cop->flags & FS_CFLG_INPLACE_ENCRYPTION)) { /* The encryption operation will require a bounce page. */ ciphertext_page = alloc_bounce_page(ctx, gfp_flags); if (IS_ERR(ciphertext_page)) goto errout; } ctx->w.control_page = plaintext_page; err = do_page_crypto(inode, FS_ENCRYPT, plaintext_page->index, err = do_page_crypto(inode, FS_ENCRYPT, index, plaintext_page, ciphertext_page, plaintext_len, plaintext_offset, gfp_flags); if (err) { ciphertext_page = ERR_PTR(err); goto errout; } if (!(inode->i_sb->s_cop->flags & FS_CFLG_INPLACE_ENCRYPTION)) { SetPagePrivate(ciphertext_page); set_page_private(ciphertext_page, (unsigned long)ctx); lock_page(ciphertext_page); } return ciphertext_page; errout: Loading @@ -265,8 +280,12 @@ struct page *fscrypt_encrypt_page(struct inode *inode, EXPORT_SYMBOL(fscrypt_encrypt_page); /** * f2crypt_decrypt_page() - Decrypts a page in-place * fscrypt_decrypt_page() - Decrypts a page in-place * @inode: Encrypted inode to decrypt. * @page: The page to decrypt. Must be locked. * @len: Number of bytes in @page to be decrypted. * @offs: Start of data in @page. * @index: Index for encryption. * * Decrypts page in-place using the ctx encryption context. * Loading @@ -274,16 +293,15 @@ EXPORT_SYMBOL(fscrypt_encrypt_page); * * Return: Zero on success, non-zero otherwise. */ int fscrypt_decrypt_page(struct page *page) int fscrypt_decrypt_page(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, pgoff_t index) { BUG_ON(!PageLocked(page)); return do_page_crypto(page->mapping->host, FS_DECRYPT, page->index, page, page, GFP_NOFS); return do_page_crypto(inode, FS_DECRYPT, page->index, page, page, len, offs, GFP_NOFS); } EXPORT_SYMBOL(fscrypt_decrypt_page); int fscrypt_zeroout_range(struct inode *inode, pgoff_t lblk, int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, sector_t pblk, unsigned int len) { struct fscrypt_ctx *ctx; Loading @@ -306,7 +324,7 @@ int fscrypt_zeroout_range(struct inode *inode, pgoff_t lblk, while (len--) { err = do_page_crypto(inode, FS_ENCRYPT, lblk, ZERO_PAGE(0), ciphertext_page, GFP_NOFS); PAGE_SIZE, 0, GFP_NOFS); if (err) goto errout; Loading Loading @@ -414,7 +432,8 @@ static void completion_pages(struct work_struct *work) bio_for_each_segment_all(bv, bio, i) { struct page *page = bv->bv_page; int ret = fscrypt_decrypt_page(page); int ret = fscrypt_decrypt_page(page->mapping->host, page, PAGE_SIZE, 0, page->index); if (ret) { WARN_ON_ONCE(1); Loading fs/crypto/fname.c +23 −34 Original line number Diff line number Diff line Loading @@ -39,65 +39,54 @@ static void fname_crypt_complete(struct crypto_async_request *req, int res) static int fname_encrypt(struct inode *inode, const struct qstr *iname, struct fscrypt_str *oname) { u32 ciphertext_len; struct skcipher_request *req = NULL; DECLARE_FS_COMPLETION_RESULT(ecr); struct fscrypt_info *ci = inode->i_crypt_info; struct crypto_skcipher *tfm = ci->ci_ctfm; int res = 0; char iv[FS_CRYPTO_BLOCK_SIZE]; struct scatterlist src_sg, dst_sg; struct scatterlist sg; int padding = 4 << (ci->ci_flags & FS_POLICY_FLAGS_PAD_MASK); char *workbuf, buf[32], *alloc_buf = NULL; unsigned lim; unsigned int lim; unsigned int cryptlen; lim = inode->i_sb->s_cop->max_namelen(inode); if (iname->len <= 0 || iname->len > lim) return -EIO; ciphertext_len = max(iname->len, (u32)FS_CRYPTO_BLOCK_SIZE); ciphertext_len = round_up(ciphertext_len, padding); ciphertext_len = min(ciphertext_len, lim); /* * Copy the filename to the output buffer for encrypting in-place and * pad it with the needed number of NUL bytes. */ cryptlen = max_t(unsigned int, iname->len, FS_CRYPTO_BLOCK_SIZE); cryptlen = round_up(cryptlen, padding); cryptlen = min(cryptlen, lim); memcpy(oname->name, iname->name, iname->len); memset(oname->name + iname->len, 0, cryptlen - iname->len); if (ciphertext_len <= sizeof(buf)) { workbuf = buf; } else { alloc_buf = kmalloc(ciphertext_len, GFP_NOFS); if (!alloc_buf) return -ENOMEM; workbuf = alloc_buf; } /* Initialize the IV */ memset(iv, 0, FS_CRYPTO_BLOCK_SIZE); /* Allocate request */ /* Set up the encryption request */ req = skcipher_request_alloc(tfm, GFP_NOFS); if (!req) { printk_ratelimited(KERN_ERR "%s: crypto_request_alloc() failed\n", __func__); kfree(alloc_buf); "%s: skcipher_request_alloc() failed\n", __func__); return -ENOMEM; } skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, fname_crypt_complete, &ecr); sg_init_one(&sg, oname->name, cryptlen); skcipher_request_set_crypt(req, &sg, &sg, cryptlen, iv); /* Copy the input */ memcpy(workbuf, iname->name, iname->len); if (iname->len < ciphertext_len) memset(workbuf + iname->len, 0, ciphertext_len - iname->len); /* Initialize IV */ memset(iv, 0, FS_CRYPTO_BLOCK_SIZE); /* Create encryption request */ sg_init_one(&src_sg, workbuf, ciphertext_len); sg_init_one(&dst_sg, oname->name, ciphertext_len); skcipher_request_set_crypt(req, &src_sg, &dst_sg, ciphertext_len, iv); /* Do the encryption */ res = crypto_skcipher_encrypt(req); if (res == -EINPROGRESS || res == -EBUSY) { /* Request is being completed asynchronously; wait for it */ wait_for_completion(&ecr.completion); res = ecr.res; } kfree(alloc_buf); skcipher_request_free(req); if (res < 0) { printk_ratelimited(KERN_ERR Loading @@ -105,7 +94,7 @@ static int fname_encrypt(struct inode *inode, return res; } oname->len = ciphertext_len; oname->len = cryptlen; return 0; } Loading Loading @@ -220,7 +209,7 @@ static int digest_decode(const char *src, int len, char *dst) return cp - dst; } u32 fscrypt_fname_encrypted_size(struct inode *inode, u32 ilen) u32 fscrypt_fname_encrypted_size(const struct inode *inode, u32 ilen) { int padding = 32; struct fscrypt_info *ci = inode->i_crypt_info; Loading @@ -238,7 +227,7 @@ EXPORT_SYMBOL(fscrypt_fname_encrypted_size); * Allocates an output buffer that is sufficient for the crypto operation * specified by the context and the direction. */ int fscrypt_fname_alloc_buffer(struct inode *inode, int fscrypt_fname_alloc_buffer(const struct inode *inode, u32 ilen, struct fscrypt_str *crypto_str) { unsigned int olen = fscrypt_fname_encrypted_size(inode, ilen); Loading fs/crypto/keyinfo.c +13 −3 Original line number Diff line number Diff line Loading @@ -185,7 +185,7 @@ int get_crypt_info(struct inode *inode) struct crypto_skcipher *ctfm; const char *cipher_str; int keysize; u8 raw_key[FS_MAX_KEY_SIZE]; u8 *raw_key = NULL; int res; res = fscrypt_initialize(); Loading Loading @@ -238,6 +238,15 @@ int get_crypt_info(struct inode *inode) if (res) goto out; /* * This cannot be a stack buffer because it is passed to the scatterlist * crypto API as part of key derivation. */ res = -ENOMEM; raw_key = kmalloc(FS_MAX_KEY_SIZE, GFP_NOFS); if (!raw_key) goto out; if (fscrypt_dummy_context_enabled(inode)) { memset(raw_key, 0x42, FS_AES_256_XTS_KEY_SIZE); goto got_key; Loading Loading @@ -276,7 +285,8 @@ int get_crypt_info(struct inode *inode) if (res) goto out; memzero_explicit(raw_key, sizeof(raw_key)); kzfree(raw_key); raw_key = NULL; if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) != NULL) { put_crypt_info(crypt_info); goto retry; Loading @@ -287,7 +297,7 @@ int get_crypt_info(struct inode *inode) if (res == -ENOKEY) res = 0; put_crypt_info(crypt_info); memzero_explicit(raw_key, sizeof(raw_key)); kzfree(raw_key); return res; } Loading fs/ext4/inode.c +5 −2 Original line number Diff line number Diff line Loading @@ -1169,7 +1169,8 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len, if (unlikely(err)) page_zero_new_buffers(page, from, to); else if (decrypt) err = fscrypt_decrypt_page(page); err = fscrypt_decrypt_page(page->mapping->host, page, PAGE_SIZE, 0, page->index); return err; } #endif Loading Loading @@ -3746,7 +3747,9 @@ static int __ext4_block_zero_page_range(handle_t *handle, /* We expect the key to be set. */ BUG_ON(!fscrypt_has_encryption_key(inode)); BUG_ON(blocksize != PAGE_SIZE); WARN_ON_ONCE(fscrypt_decrypt_page(page)); BUG_ON(!PageLocked(page)); WARN_ON_ONCE(fscrypt_decrypt_page(page->mapping->host, page, PAGE_SIZE, 0, page->index)); } } if (ext4_should_journal_data(inode)) { Loading fs/ext4/page-io.c +2 −1 Original line number Diff line number Diff line Loading @@ -470,7 +470,8 @@ int ext4_bio_write_page(struct ext4_io_submit *io, gfp_t gfp_flags = GFP_NOFS; retry_encrypt: data_page = fscrypt_encrypt_page(inode, page, gfp_flags); data_page = fscrypt_encrypt_page(inode, page, PAGE_SIZE, 0, page->index, gfp_flags); if (IS_ERR(data_page)) { ret = PTR_ERR(data_page); if (ret == -ENOMEM && wbc->sync_mode == WB_SYNC_ALL) { Loading Loading
fs/crypto/crypto.c +51 −32 Original line number Diff line number Diff line Loading @@ -88,7 +88,7 @@ EXPORT_SYMBOL(fscrypt_release_ctx); * Return: An allocated and initialized encryption context on success; error * value or NULL otherwise. */ struct fscrypt_ctx *fscrypt_get_ctx(struct inode *inode, gfp_t gfp_flags) struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode, gfp_t gfp_flags) { struct fscrypt_ctx *ctx = NULL; struct fscrypt_info *ci = inode->i_crypt_info; Loading Loading @@ -146,9 +146,10 @@ typedef enum { FS_ENCRYPT, } fscrypt_direction_t; static int do_page_crypto(struct inode *inode, static int do_page_crypto(const struct inode *inode, fscrypt_direction_t rw, pgoff_t index, struct page *src_page, struct page *dest_page, unsigned int src_len, unsigned int src_offset, gfp_t gfp_flags) { struct { Loading Loading @@ -179,10 +180,10 @@ static int do_page_crypto(struct inode *inode, memset(xts_tweak.padding, 0, sizeof(xts_tweak.padding)); sg_init_table(&dst, 1); sg_set_page(&dst, dest_page, PAGE_SIZE, 0); sg_set_page(&dst, dest_page, src_len, src_offset); sg_init_table(&src, 1); sg_set_page(&src, src_page, PAGE_SIZE, 0); skcipher_request_set_crypt(req, &src, &dst, PAGE_SIZE, &xts_tweak); sg_set_page(&src, src_page, src_len, src_offset); skcipher_request_set_crypt(req, &src, &dst, src_len, &xts_tweak); if (rw == FS_DECRYPT) res = crypto_skcipher_decrypt(req); else Loading Loading @@ -215,10 +216,15 @@ static struct page *alloc_bounce_page(struct fscrypt_ctx *ctx, gfp_t gfp_flags) * fscypt_encrypt_page() - Encrypts a page * @inode: The inode for which the encryption should take place * @plaintext_page: The page to encrypt. Must be locked. * @plaintext_len: Length of plaintext within page * @plaintext_offset: Offset of plaintext within page * @index: Index for encryption. This is mainly the page index, but * but might be different for multiple calls on same page. * @gfp_flags: The gfp flag for memory allocation * * Allocates a ciphertext page and encrypts plaintext_page into it using the ctx * encryption context. * Encrypts plaintext_page using the ctx encryption context. If * the filesystem supports it, encryption is performed in-place, otherwise a * new ciphertext_page is allocated and returned. * * Called on the page write path. The caller must call * fscrypt_restore_control_page() on the returned ciphertext page to Loading @@ -227,35 +233,44 @@ static struct page *alloc_bounce_page(struct fscrypt_ctx *ctx, gfp_t gfp_flags) * Return: An allocated page with the encrypted content on success. Else, an * error value or NULL. */ struct page *fscrypt_encrypt_page(struct inode *inode, struct page *plaintext_page, gfp_t gfp_flags) struct page *fscrypt_encrypt_page(const struct inode *inode, struct page *plaintext_page, unsigned int plaintext_len, unsigned int plaintext_offset, pgoff_t index, gfp_t gfp_flags) { struct fscrypt_ctx *ctx; struct page *ciphertext_page = NULL; struct page *ciphertext_page = plaintext_page; int err; BUG_ON(!PageLocked(plaintext_page)); BUG_ON(plaintext_len % FS_CRYPTO_BLOCK_SIZE != 0); ctx = fscrypt_get_ctx(inode, gfp_flags); if (IS_ERR(ctx)) return (struct page *)ctx; if (!(inode->i_sb->s_cop->flags & FS_CFLG_INPLACE_ENCRYPTION)) { /* The encryption operation will require a bounce page. */ ciphertext_page = alloc_bounce_page(ctx, gfp_flags); if (IS_ERR(ciphertext_page)) goto errout; } ctx->w.control_page = plaintext_page; err = do_page_crypto(inode, FS_ENCRYPT, plaintext_page->index, err = do_page_crypto(inode, FS_ENCRYPT, index, plaintext_page, ciphertext_page, plaintext_len, plaintext_offset, gfp_flags); if (err) { ciphertext_page = ERR_PTR(err); goto errout; } if (!(inode->i_sb->s_cop->flags & FS_CFLG_INPLACE_ENCRYPTION)) { SetPagePrivate(ciphertext_page); set_page_private(ciphertext_page, (unsigned long)ctx); lock_page(ciphertext_page); } return ciphertext_page; errout: Loading @@ -265,8 +280,12 @@ struct page *fscrypt_encrypt_page(struct inode *inode, EXPORT_SYMBOL(fscrypt_encrypt_page); /** * f2crypt_decrypt_page() - Decrypts a page in-place * fscrypt_decrypt_page() - Decrypts a page in-place * @inode: Encrypted inode to decrypt. * @page: The page to decrypt. Must be locked. * @len: Number of bytes in @page to be decrypted. * @offs: Start of data in @page. * @index: Index for encryption. * * Decrypts page in-place using the ctx encryption context. * Loading @@ -274,16 +293,15 @@ EXPORT_SYMBOL(fscrypt_encrypt_page); * * Return: Zero on success, non-zero otherwise. */ int fscrypt_decrypt_page(struct page *page) int fscrypt_decrypt_page(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, pgoff_t index) { BUG_ON(!PageLocked(page)); return do_page_crypto(page->mapping->host, FS_DECRYPT, page->index, page, page, GFP_NOFS); return do_page_crypto(inode, FS_DECRYPT, page->index, page, page, len, offs, GFP_NOFS); } EXPORT_SYMBOL(fscrypt_decrypt_page); int fscrypt_zeroout_range(struct inode *inode, pgoff_t lblk, int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, sector_t pblk, unsigned int len) { struct fscrypt_ctx *ctx; Loading @@ -306,7 +324,7 @@ int fscrypt_zeroout_range(struct inode *inode, pgoff_t lblk, while (len--) { err = do_page_crypto(inode, FS_ENCRYPT, lblk, ZERO_PAGE(0), ciphertext_page, GFP_NOFS); PAGE_SIZE, 0, GFP_NOFS); if (err) goto errout; Loading Loading @@ -414,7 +432,8 @@ static void completion_pages(struct work_struct *work) bio_for_each_segment_all(bv, bio, i) { struct page *page = bv->bv_page; int ret = fscrypt_decrypt_page(page); int ret = fscrypt_decrypt_page(page->mapping->host, page, PAGE_SIZE, 0, page->index); if (ret) { WARN_ON_ONCE(1); Loading
fs/crypto/fname.c +23 −34 Original line number Diff line number Diff line Loading @@ -39,65 +39,54 @@ static void fname_crypt_complete(struct crypto_async_request *req, int res) static int fname_encrypt(struct inode *inode, const struct qstr *iname, struct fscrypt_str *oname) { u32 ciphertext_len; struct skcipher_request *req = NULL; DECLARE_FS_COMPLETION_RESULT(ecr); struct fscrypt_info *ci = inode->i_crypt_info; struct crypto_skcipher *tfm = ci->ci_ctfm; int res = 0; char iv[FS_CRYPTO_BLOCK_SIZE]; struct scatterlist src_sg, dst_sg; struct scatterlist sg; int padding = 4 << (ci->ci_flags & FS_POLICY_FLAGS_PAD_MASK); char *workbuf, buf[32], *alloc_buf = NULL; unsigned lim; unsigned int lim; unsigned int cryptlen; lim = inode->i_sb->s_cop->max_namelen(inode); if (iname->len <= 0 || iname->len > lim) return -EIO; ciphertext_len = max(iname->len, (u32)FS_CRYPTO_BLOCK_SIZE); ciphertext_len = round_up(ciphertext_len, padding); ciphertext_len = min(ciphertext_len, lim); /* * Copy the filename to the output buffer for encrypting in-place and * pad it with the needed number of NUL bytes. */ cryptlen = max_t(unsigned int, iname->len, FS_CRYPTO_BLOCK_SIZE); cryptlen = round_up(cryptlen, padding); cryptlen = min(cryptlen, lim); memcpy(oname->name, iname->name, iname->len); memset(oname->name + iname->len, 0, cryptlen - iname->len); if (ciphertext_len <= sizeof(buf)) { workbuf = buf; } else { alloc_buf = kmalloc(ciphertext_len, GFP_NOFS); if (!alloc_buf) return -ENOMEM; workbuf = alloc_buf; } /* Initialize the IV */ memset(iv, 0, FS_CRYPTO_BLOCK_SIZE); /* Allocate request */ /* Set up the encryption request */ req = skcipher_request_alloc(tfm, GFP_NOFS); if (!req) { printk_ratelimited(KERN_ERR "%s: crypto_request_alloc() failed\n", __func__); kfree(alloc_buf); "%s: skcipher_request_alloc() failed\n", __func__); return -ENOMEM; } skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP, fname_crypt_complete, &ecr); sg_init_one(&sg, oname->name, cryptlen); skcipher_request_set_crypt(req, &sg, &sg, cryptlen, iv); /* Copy the input */ memcpy(workbuf, iname->name, iname->len); if (iname->len < ciphertext_len) memset(workbuf + iname->len, 0, ciphertext_len - iname->len); /* Initialize IV */ memset(iv, 0, FS_CRYPTO_BLOCK_SIZE); /* Create encryption request */ sg_init_one(&src_sg, workbuf, ciphertext_len); sg_init_one(&dst_sg, oname->name, ciphertext_len); skcipher_request_set_crypt(req, &src_sg, &dst_sg, ciphertext_len, iv); /* Do the encryption */ res = crypto_skcipher_encrypt(req); if (res == -EINPROGRESS || res == -EBUSY) { /* Request is being completed asynchronously; wait for it */ wait_for_completion(&ecr.completion); res = ecr.res; } kfree(alloc_buf); skcipher_request_free(req); if (res < 0) { printk_ratelimited(KERN_ERR Loading @@ -105,7 +94,7 @@ static int fname_encrypt(struct inode *inode, return res; } oname->len = ciphertext_len; oname->len = cryptlen; return 0; } Loading Loading @@ -220,7 +209,7 @@ static int digest_decode(const char *src, int len, char *dst) return cp - dst; } u32 fscrypt_fname_encrypted_size(struct inode *inode, u32 ilen) u32 fscrypt_fname_encrypted_size(const struct inode *inode, u32 ilen) { int padding = 32; struct fscrypt_info *ci = inode->i_crypt_info; Loading @@ -238,7 +227,7 @@ EXPORT_SYMBOL(fscrypt_fname_encrypted_size); * Allocates an output buffer that is sufficient for the crypto operation * specified by the context and the direction. */ int fscrypt_fname_alloc_buffer(struct inode *inode, int fscrypt_fname_alloc_buffer(const struct inode *inode, u32 ilen, struct fscrypt_str *crypto_str) { unsigned int olen = fscrypt_fname_encrypted_size(inode, ilen); Loading
fs/crypto/keyinfo.c +13 −3 Original line number Diff line number Diff line Loading @@ -185,7 +185,7 @@ int get_crypt_info(struct inode *inode) struct crypto_skcipher *ctfm; const char *cipher_str; int keysize; u8 raw_key[FS_MAX_KEY_SIZE]; u8 *raw_key = NULL; int res; res = fscrypt_initialize(); Loading Loading @@ -238,6 +238,15 @@ int get_crypt_info(struct inode *inode) if (res) goto out; /* * This cannot be a stack buffer because it is passed to the scatterlist * crypto API as part of key derivation. */ res = -ENOMEM; raw_key = kmalloc(FS_MAX_KEY_SIZE, GFP_NOFS); if (!raw_key) goto out; if (fscrypt_dummy_context_enabled(inode)) { memset(raw_key, 0x42, FS_AES_256_XTS_KEY_SIZE); goto got_key; Loading Loading @@ -276,7 +285,8 @@ int get_crypt_info(struct inode *inode) if (res) goto out; memzero_explicit(raw_key, sizeof(raw_key)); kzfree(raw_key); raw_key = NULL; if (cmpxchg(&inode->i_crypt_info, NULL, crypt_info) != NULL) { put_crypt_info(crypt_info); goto retry; Loading @@ -287,7 +297,7 @@ int get_crypt_info(struct inode *inode) if (res == -ENOKEY) res = 0; put_crypt_info(crypt_info); memzero_explicit(raw_key, sizeof(raw_key)); kzfree(raw_key); return res; } Loading
fs/ext4/inode.c +5 −2 Original line number Diff line number Diff line Loading @@ -1169,7 +1169,8 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len, if (unlikely(err)) page_zero_new_buffers(page, from, to); else if (decrypt) err = fscrypt_decrypt_page(page); err = fscrypt_decrypt_page(page->mapping->host, page, PAGE_SIZE, 0, page->index); return err; } #endif Loading Loading @@ -3746,7 +3747,9 @@ static int __ext4_block_zero_page_range(handle_t *handle, /* We expect the key to be set. */ BUG_ON(!fscrypt_has_encryption_key(inode)); BUG_ON(blocksize != PAGE_SIZE); WARN_ON_ONCE(fscrypt_decrypt_page(page)); BUG_ON(!PageLocked(page)); WARN_ON_ONCE(fscrypt_decrypt_page(page->mapping->host, page, PAGE_SIZE, 0, page->index)); } } if (ext4_should_journal_data(inode)) { Loading
fs/ext4/page-io.c +2 −1 Original line number Diff line number Diff line Loading @@ -470,7 +470,8 @@ int ext4_bio_write_page(struct ext4_io_submit *io, gfp_t gfp_flags = GFP_NOFS; retry_encrypt: data_page = fscrypt_encrypt_page(inode, page, gfp_flags); data_page = fscrypt_encrypt_page(inode, page, PAGE_SIZE, 0, page->index, gfp_flags); if (IS_ERR(data_page)) { ret = PTR_ERR(data_page); if (ret == -ENOMEM && wbc->sync_mode == WB_SYNC_ALL) { Loading