On Sun, Jul 09, 2023 at 02:53:36PM -0400, Sweet Tea Dorminy wrote: > If a filesystem uses extent-based encryption, then the offset within a > file is not a constant which can be used for calculating an IV. > For instance, the same extent could be blocks 0-8 in one file, and > blocks 100-108 in another file. Instead, the block offset within the > extent must be used instead. > > Update all uses of logical block offset within the file to use logical > block offset within the extent, if applicable. > > Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@xxxxxxxxxx> > --- > fs/crypto/crypto.c | 3 ++- > fs/crypto/inline_crypt.c | 24 +++++++++++++++++------- > 2 files changed, 19 insertions(+), 8 deletions(-) > > diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c > index 1b7e375b1c6b..d75f1b3f5795 100644 > --- a/fs/crypto/crypto.c > +++ b/fs/crypto/crypto.c > @@ -107,8 +107,9 @@ int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw, > struct skcipher_request *req = NULL; > DECLARE_CRYPTO_WAIT(wait); > struct scatterlist dst, src; > + u64 ci_offset = 0; > struct fscrypt_info *ci = > - fscrypt_get_lblk_info(inode, lblk_num, NULL, NULL); > + fscrypt_get_lblk_info(inode, lblk_num, &ci_offset, NULL); > struct crypto_skcipher *tfm = ci->ci_enc_key->tfm; > int res = 0; > > diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c > index 885a2ec3d711..b3e7a5291d22 100644 > --- a/fs/crypto/inline_crypt.c > +++ b/fs/crypto/inline_crypt.c > @@ -267,12 +267,15 @@ void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode, > { > const struct fscrypt_info *ci; > u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE]; > + u64 ci_offset = 0; > > if (!fscrypt_inode_uses_inline_crypto(inode)) > return; > - ci = fscrypt_get_lblk_info(inode, first_lblk, NULL, NULL); > + ci = fscrypt_get_lblk_info(inode, first_lblk, &ci_offset, NULL); > + if (!ci) > + return; > > - fscrypt_generate_dun(ci, first_lblk, dun); > + fscrypt_generate_dun(ci, ci_offset, dun); > bio_crypt_set_ctx(bio, ci->ci_enc_key->blk_key, dun, gfp_mask); > } > EXPORT_SYMBOL_GPL(fscrypt_set_bio_crypt_ctx); > @@ -350,22 +353,23 @@ bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode, > const struct bio_crypt_ctx *bc = bio->bi_crypt_context; > u64 next_dun[BLK_CRYPTO_DUN_ARRAY_SIZE]; > struct fscrypt_info *ci; > + u64 ci_offset = 0; > > if (!!bc != fscrypt_inode_uses_inline_crypto(inode)) > return false; > if (!bc) > return true; > > - ci = fscrypt_get_lblk_info(inode, next_lblk, NULL, NULL); > + ci = fscrypt_get_lblk_info(inode, next_lblk, &ci_offset, NULL); > /* > * Comparing the key pointers is good enough, as all I/O for each key > * uses the same pointer. I.e., there's currently no need to support > * merging requests where the keys are the same but the pointers differ. > */ > - if (bc->bc_key != ci->ci_enc_key->blk_key) > + if (!ci || bc->bc_key != ci->ci_enc_key->blk_key) > return false; > This seems like an unrelated change, we weren't checking !ci before and the behavior hasn't changed with the new code. Thanks, Josef