2018-12-04 09:57:07

by Chandan Rajendra

[permalink] [raw]
Subject: [PATCH V2 0/7] Remove fs specific fscrypt and fsverity build config options

In order to have a common code base for fscrypt & fsverity "post read"
processing across filesystems which implement fscrypt/fsverity, this
commit removes filesystem specific build config option
(CONFIG_EXT4_FS_ENCRYPTION, CONFIG_EXT4_FS_VERITY,
CONFIG_F2FS_FS_ENCRYPTION, CONFIG_F2FS_FS_VERITY and
CONFIG_UBIFS_FS_ENCRYPTION) and replaces it with build options
(CONFIG_FS_ENCRYPTION and CONFIG_FS_VERITY) whose values affect all
the filesystems making use of fscrypt and fsverity.

PS: Since I have access to only to x86 and ppc64le machines, I haven't tested the
defconfig files for other architectures.

Changelog:
V1 -> V2:
1. Address the following review comments provided by Eric Biggers,
- In ext4_should_use_dax(), Use ext4_test_inode_flag() to check for
fscrypt/fsverity status of an inode.
- Update documentation associated with fscrypt & fsverity to refer to
CONFIG_FS_ENCRYPTION and CONFIG_FS_VERITY build flags.
- Remove filesystem specific fscrypt build configuration from defconfig
files.
- Provide a list of supported filesystems for CONFIG_FS_ENCRYPTION and
CONFIG_FS_VERITY build flags.
- Update comment describing S_VERITY flag.
2. Remove UBIFS specific encryption build option and make use of the generic
CONFIG_FS_ENCRYPTION flag.

RFC -> V1:
1. Add a new patch to implement S_VERITY/IS_VERITY().
2. Split code that replaces filesystem specific routines with generic
IS_ENCRYPTED() and IS_VERITY() calls into separate patches.

Chandan Rajendra (7):
ext4: use IS_ENCRYPTED() to check encryption status
f2fs: use IS_ENCRYPTED() to check encryption status
fscrypt: remove filesystem specific build config option
Add S_VERITY and IS_VERITY()
ext4: use IS_VERITY() to check inode's fsverity status
f2fs: use IS_VERITY() to check inode's fsverity status
fsverity: Remove filesystem specific build config option

Documentation/filesystems/fscrypt.rst | 4 +-
Documentation/filesystems/fsverity.rst | 4 +-
arch/mips/configs/generic_defconfig | 2 +-
arch/nds32/configs/defconfig | 2 +-
arch/s390/configs/debug_defconfig | 2 +-
arch/s390/configs/performance_defconfig | 2 +-
fs/crypto/Kconfig | 5 +-
fs/ext4/Kconfig | 35 --
fs/ext4/dir.c | 10 +-
fs/ext4/ext4.h | 23 +-
fs/ext4/ext4_jbd2.h | 2 +-
fs/ext4/extents.c | 4 +-
fs/ext4/file.c | 2 +-
fs/ext4/ialloc.c | 2 +-
fs/ext4/inode.c | 32 +-
fs/ext4/ioctl.c | 4 +-
fs/ext4/move_extent.c | 3 +-
fs/ext4/namei.c | 18 +-
fs/ext4/page-io.c | 8 +-
fs/ext4/readpage.c | 10 +-
fs/ext4/super.c | 13 +-
fs/ext4/sysfs.c | 8 +-
fs/f2fs/Kconfig | 31 --
fs/f2fs/data.c | 6 +-
fs/f2fs/dir.c | 10 +-
fs/f2fs/f2fs.h | 9 +-
fs/f2fs/file.c | 16 +-
fs/f2fs/inode.c | 4 +-
fs/f2fs/namei.c | 6 +-
fs/f2fs/super.c | 14 +-
fs/f2fs/sysfs.c | 8 +-
fs/ubifs/Kconfig | 11 -
fs/ubifs/Makefile | 2 +-
fs/ubifs/ioctl.c | 4 +-
fs/ubifs/sb.c | 2 +-
fs/ubifs/super.c | 2 +-
fs/ubifs/ubifs.h | 5 +-
fs/verity/Kconfig | 3 +-
include/linux/fs.h | 10 +-
include/linux/fscrypt.h | 416 +++++++++++++++++++++++-
include/linux/fscrypt_notsupp.h | 231 -------------
include/linux/fscrypt_supp.h | 204 ------------
include/linux/fsverity.h | 3 +-
43 files changed, 532 insertions(+), 660 deletions(-)
delete mode 100644 include/linux/fscrypt_notsupp.h
delete mode 100644 include/linux/fscrypt_supp.h

--
2.19.1


2018-12-04 09:57:51

by Chandan Rajendra

[permalink] [raw]
Subject: [PATCH V2 6/7] f2fs: use IS_VERITY() to check inode's fsverity status

This commit now uses IS_VERITY() macro to check if fsverity is
enabled on an inode.

Acked-by: Chao Yu <[email protected]>
Signed-off-by: Chandan Rajendra <[email protected]>
---
fs/f2fs/file.c | 6 +++---
fs/f2fs/inode.c | 4 +++-
2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 6c7ad15000b9..2eb4821d95d1 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -491,7 +491,7 @@ static int f2fs_file_open(struct inode *inode, struct file *filp)
if (err)
return err;

- if (f2fs_verity_file(inode)) {
+ if (IS_VERITY(inode)) {
err = fsverity_file_open(inode, filp);
if (err)
return err;
@@ -701,7 +701,7 @@ int f2fs_getattr(const struct path *path, struct kstat *stat,
struct f2fs_inode *ri;
unsigned int flags;

- if (f2fs_verity_file(inode)) {
+ if (IS_VERITY(inode)) {
/*
* For fs-verity we need to override i_size with the original
* data i_size. This requires I/O to the file which with
@@ -800,7 +800,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
if (err)
return err;

- if (f2fs_verity_file(inode)) {
+ if (IS_VERITY(inode)) {
err = fsverity_prepare_setattr(dentry, attr);
if (err)
return err;
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index ddef483ad689..02806feed64c 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -45,9 +45,11 @@ void f2fs_set_inode_flags(struct inode *inode)
new_fl |= S_DIRSYNC;
if (f2fs_encrypted_inode(inode))
new_fl |= S_ENCRYPTED;
+ if (f2fs_verity_file(inode))
+ new_fl |= S_VERITY;
inode_set_flags(inode, new_fl,
S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|
- S_ENCRYPTED);
+ S_ENCRYPTED|S_VERITY);
}

static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri)
--
2.19.1

2018-12-08 07:07:27

by Chandan Rajendra

[permalink] [raw]
Subject: Re: [PATCH V2 3/7] fscrypt: remove filesystem specific build config option

On Wednesday, December 5, 2018 5:13:21 AM IST Eric Biggers wrote:
> Hi Chandan,
>
> On Tue, Dec 04, 2018 at 03:26:46PM +0530, Chandan Rajendra wrote:
> > In order to have a common code base for fscrypt "post read" processing
> > for all filesystems which support encryption, this commit removes
> > filesystem specific build config option (e.g. CONFIG_EXT4_FS_ENCRYPTION)
> > and replaces it with a build option (i.e. CONFIG_FS_ENCRYPTION) whose
> > value affects all the filesystems making use of fscrypt.
> >
> > Signed-off-by: Chandan Rajendra <[email protected]>
> [...]
> > -config F2FS_FS_ENCRYPTION
> > - bool "F2FS Encryption"
> > - depends on F2FS_FS
> > - depends on F2FS_FS_XATTR
> > - select FS_ENCRYPTION
> > - help
> > - Enable encryption of f2fs files and directories. This
> > - feature is similar to ecryptfs, but it is more memory
> > - efficient since it avoids caching the encrypted and
> > - decrypted pages in the page cache.
> > -
> [...]
> > -config UBIFS_FS_ENCRYPTION
> > - bool "UBIFS Encryption"
> > - depends on UBIFS_FS && UBIFS_FS_XATTR && BLOCK
> > - select FS_ENCRYPTION
> > - default n
> > - help
> > - Enable encryption of UBIFS files and directories. This
> > - feature is similar to ecryptfs, but it is more memory
> > - efficient since it avoids caching the encrypted and
> > - decrypted pages in the page cache.
>
> Will it cause problems that now f2fs encryption can be "enabled" without
> F2FS_FS_XATTR, and ubifs encryption without UBIFS_FS_XATTR && BLOCK?
>
> Otherwise I think this patch looks fine. I'm a bit concerned about the bloat
> from making FS_ENCRYPTION non-modular, but given that it will make sharing I/O
> code much easier, it's probably worthwhile.
>
> It would help to strip down the dependencies of FS_ENCRYPTION to just the stuff
> needed for just AES-256-XTS and AES-256-CTS. I already sent out a patch a
> couple months ago (https://patchwork.kernel.org/patch/10589319/) to remove
> CONFIG_CTR which isn't used at all; I'll remind Ted to apply that. But we could
> also drop CONFIG_SHA256, which is only needed for AES-128-CBC contents
> encryption. If we do that, it should be a separate patch, though.

Hi Eric,

fscrypt_valid_enc_modes() allows FS_ENCRYPTION_MODE_AES_128_CBC to be used for
encryption of file's contents. This is consistent with what you had mentioned
above.

static inline bool fscrypt_valid_enc_modes(u32 contents_mode,
u32 filenames_mode)
{
if (contents_mode == FS_ENCRYPTION_MODE_AES_128_CBC &&
filenames_mode == FS_ENCRYPTION_MODE_AES_128_CTS)
return true;

if (contents_mode == FS_ENCRYPTION_MODE_AES_256_XTS &&
filenames_mode == FS_ENCRYPTION_MODE_AES_256_CTS)
return true;

return false;
}

Hence FS_ENCRYPTION does need to have AES-128-CBC and by extension SHA256 code
compiled in right?

--
chandan

2018-12-04 23:43:23

by Eric Biggers

[permalink] [raw]
Subject: Re: [PATCH V2 3/7] fscrypt: remove filesystem specific build config option

Hi Chandan,

On Tue, Dec 04, 2018 at 03:26:46PM +0530, Chandan Rajendra wrote:
> In order to have a common code base for fscrypt "post read" processing
> for all filesystems which support encryption, this commit removes
> filesystem specific build config option (e.g. CONFIG_EXT4_FS_ENCRYPTION)
> and replaces it with a build option (i.e. CONFIG_FS_ENCRYPTION) whose
> value affects all the filesystems making use of fscrypt.
>
> Signed-off-by: Chandan Rajendra <[email protected]>
[...]
> -config F2FS_FS_ENCRYPTION
> - bool "F2FS Encryption"
> - depends on F2FS_FS
> - depends on F2FS_FS_XATTR
> - select FS_ENCRYPTION
> - help
> - Enable encryption of f2fs files and directories. This
> - feature is similar to ecryptfs, but it is more memory
> - efficient since it avoids caching the encrypted and
> - decrypted pages in the page cache.
> -
[...]
> -config UBIFS_FS_ENCRYPTION
> - bool "UBIFS Encryption"
> - depends on UBIFS_FS && UBIFS_FS_XATTR && BLOCK
> - select FS_ENCRYPTION
> - default n
> - help
> - Enable encryption of UBIFS files and directories. This
> - feature is similar to ecryptfs, but it is more memory
> - efficient since it avoids caching the encrypted and
> - decrypted pages in the page cache.

Will it cause problems that now f2fs encryption can be "enabled" without
F2FS_FS_XATTR, and ubifs encryption without UBIFS_FS_XATTR && BLOCK?

Otherwise I think this patch looks fine. I'm a bit concerned about the bloat
from making FS_ENCRYPTION non-modular, but given that it will make sharing I/O
code much easier, it's probably worthwhile.

It would help to strip down the dependencies of FS_ENCRYPTION to just the stuff
needed for just AES-256-XTS and AES-256-CTS. I already sent out a patch a
couple months ago (https://patchwork.kernel.org/patch/10589319/) to remove
CONFIG_CTR which isn't used at all; I'll remind Ted to apply that. But we could
also drop CONFIG_SHA256, which is only needed for AES-128-CBC contents
encryption. If we do that, it should be a separate patch, though.

Thanks,

- Eric

2018-12-04 09:57:20

by Chandan Rajendra

[permalink] [raw]
Subject: [PATCH V2 2/7] f2fs: use IS_ENCRYPTED() to check encryption status

This commit removes the f2fs specific f2fs_encrypted_inode() and makes
use of the generic IS_ENCRYPTED() macro to check for the encryption
status of an inode.

Acked-by: Chao Yu <[email protected]>
Signed-off-by: Chandan Rajendra <[email protected]>
---
fs/f2fs/data.c | 4 ++--
fs/f2fs/dir.c | 10 +++++-----
fs/f2fs/file.c | 10 +++++-----
fs/f2fs/namei.c | 6 +++---
4 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 09d9fc1676a7..844ec573263e 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1491,7 +1491,7 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
}

if (size) {
- if (f2fs_encrypted_inode(inode))
+ if (IS_ENCRYPTED(inode))
flags |= FIEMAP_EXTENT_DATA_ENCRYPTED;

ret = fiemap_fill_next_extent(fieinfo, logical,
@@ -1764,7 +1764,7 @@ static inline bool check_inplace_update_policy(struct inode *inode,
if (policy & (0x1 << F2FS_IPU_ASYNC) &&
fio && fio->op == REQ_OP_WRITE &&
!(fio->op_flags & REQ_SYNC) &&
- !f2fs_encrypted_inode(inode))
+ !IS_ENCRYPTED(inode))
return true;

/* this is only set during fdatasync */
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index bacc667950b6..cf9e2564388d 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -385,7 +385,7 @@ struct page *f2fs_init_inode_metadata(struct inode *inode, struct inode *dir,
if (err)
goto put_error;

- if ((f2fs_encrypted_inode(dir) || dummy_encrypt) &&
+ if ((IS_ENCRYPTED(dir) || dummy_encrypt) &&
f2fs_may_encrypt(inode)) {
err = fscrypt_inherit_context(dir, inode, page, false);
if (err)
@@ -399,7 +399,7 @@ struct page *f2fs_init_inode_metadata(struct inode *inode, struct inode *dir,

if (new_name) {
init_dent_inode(new_name, page);
- if (f2fs_encrypted_inode(dir))
+ if (IS_ENCRYPTED(dir))
file_set_enc_name(inode);
}

@@ -808,7 +808,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
de_name.name = d->filename[bit_pos];
de_name.len = le16_to_cpu(de->name_len);

- if (f2fs_encrypted_inode(d->inode)) {
+ if (IS_ENCRYPTED(d->inode)) {
int save_len = fstr->len;

err = fscrypt_fname_disk_to_usr(d->inode,
@@ -852,7 +852,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
struct fscrypt_str fstr = FSTR_INIT(NULL, 0);
int err = 0;

- if (f2fs_encrypted_inode(inode)) {
+ if (IS_ENCRYPTED(inode)) {
err = fscrypt_get_encryption_info(inode);
if (err && err != -ENOKEY)
goto out;
@@ -914,7 +914,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)

static int f2fs_dir_open(struct inode *inode, struct file *filp)
{
- if (f2fs_encrypted_inode(inode))
+ if (IS_ENCRYPTED(inode))
return fscrypt_get_encryption_info(inode) ? -EACCES : 0;
return 0;
}
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 87794b2a45ff..6c7ad15000b9 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -585,7 +585,7 @@ static int truncate_partial_data_page(struct inode *inode, u64 from,
zero_user(page, offset, PAGE_SIZE - offset);

/* An encrypted inode should have a key and truncate the last page. */
- f2fs_bug_on(F2FS_I_SB(inode), cache_only && f2fs_encrypted_inode(inode));
+ f2fs_bug_on(F2FS_I_SB(inode), cache_only && IS_ENCRYPTED(inode));
if (!cache_only)
set_page_dirty(page);
f2fs_put_page(page, 1);
@@ -730,7 +730,7 @@ int f2fs_getattr(const struct path *path, struct kstat *stat,
stat->attributes |= STATX_ATTR_APPEND;
if (flags & F2FS_COMPR_FL)
stat->attributes |= STATX_ATTR_COMPRESSED;
- if (f2fs_encrypted_inode(inode))
+ if (IS_ENCRYPTED(inode))
stat->attributes |= STATX_ATTR_ENCRYPTED;
if (flags & F2FS_IMMUTABLE_FL)
stat->attributes |= STATX_ATTR_IMMUTABLE;
@@ -1587,7 +1587,7 @@ static long f2fs_fallocate(struct file *file, int mode,
if (!S_ISREG(inode->i_mode))
return -EINVAL;

- if (f2fs_encrypted_inode(inode) &&
+ if (IS_ENCRYPTED(inode) &&
(mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE)))
return -EOPNOTSUPP;

@@ -1671,7 +1671,7 @@ static int f2fs_ioc_getflags(struct file *filp, unsigned long arg)
struct f2fs_inode_info *fi = F2FS_I(inode);
unsigned int flags = fi->i_flags;

- if (f2fs_encrypted_inode(inode))
+ if (IS_ENCRYPTED(inode))
flags |= F2FS_ENCRYPT_FL;
if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode))
flags |= F2FS_INLINE_DATA_FL;
@@ -2430,7 +2430,7 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in,
if (!S_ISREG(src->i_mode) || !S_ISREG(dst->i_mode))
return -EINVAL;

- if (f2fs_encrypted_inode(src) || f2fs_encrypted_inode(dst))
+ if (IS_ENCRYPTED(src) || IS_ENCRYPTED(dst))
return -EOPNOTSUPP;

if (src == dst) {
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index 99299ede7429..6ae37e0cf6e3 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -75,7 +75,7 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
set_inode_flag(inode, FI_NEW_INODE);

/* If the directory encrypted, then we should encrypt the inode. */
- if ((f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
+ if ((IS_ENCRYPTED(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
f2fs_may_encrypt(inode))
f2fs_set_encrypted_inode(inode);

@@ -476,7 +476,7 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
if (err)
goto out_iput;
}
- if (f2fs_encrypted_inode(dir) &&
+ if (IS_ENCRYPTED(dir) &&
(S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
!fscrypt_has_permitted_context(dir, inode)) {
f2fs_msg(inode->i_sb, KERN_WARNING,
@@ -803,7 +803,7 @@ static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
if (unlikely(f2fs_cp_error(sbi)))
return -EIO;

- if (f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) {
+ if (IS_ENCRYPTED(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) {
int err = fscrypt_get_encryption_info(dir);
if (err)
return err;
--
2.19.1

2018-12-04 23:55:14

by Eric Biggers

[permalink] [raw]
Subject: Re: [PATCH V2 5/7] ext4: use IS_VERITY() to check inode's fsverity status

On Tue, Dec 04, 2018 at 03:26:48PM +0530, Chandan Rajendra wrote:
> This commit now uses IS_VERITY() macro to check if fsverity is
> enabled on an inode.
>
> Signed-off-by: Chandan Rajendra <[email protected]>
> ---
> fs/ext4/ext4.h | 9 ---------
> fs/ext4/file.c | 2 +-
> fs/ext4/inode.c | 10 ++++++----
> fs/ext4/readpage.c | 2 +-
> fs/ext4/super.c | 1 +
> 5 files changed, 9 insertions(+), 15 deletions(-)
>
> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> index db21df885186..64bf9fb7ef18 100644
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -2296,15 +2296,6 @@ extern unsigned ext4_free_clusters_after_init(struct super_block *sb,
> struct ext4_group_desc *gdp);
> ext4_fsblk_t ext4_inode_to_goal_block(struct inode *);
>
> -static inline bool ext4_verity_inode(struct inode *inode)
> -{
> -#ifdef CONFIG_EXT4_FS_VERITY
> - return ext4_test_inode_flag(inode, EXT4_INODE_VERITY);
> -#else
> - return false;
> -#endif
> -}
> -
> #ifdef CONFIG_FS_ENCRYPTION
> static inline int ext4_fname_setup_filename(struct inode *dir,
> const struct qstr *iname,
> diff --git a/fs/ext4/file.c b/fs/ext4/file.c
> index cb4b69ef01a2..30fbd663354f 100644
> --- a/fs/ext4/file.c
> +++ b/fs/ext4/file.c
> @@ -444,7 +444,7 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
> if (ret)
> return ret;
>
> - if (ext4_verity_inode(inode)) {
> + if (IS_VERITY(inode)) {
> ret = fsverity_file_open(inode, filp);
> if (ret)
> return ret;
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 09d8857b0e3c..79d14d8bbbf4 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -3884,7 +3884,7 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
> return 0;
> #endif
>
> - if (ext4_verity_inode(inode))
> + if (IS_VERITY(inode))
> return 0;
>
> /*
> @@ -4726,7 +4726,7 @@ static bool ext4_should_use_dax(struct inode *inode)
> return false;
> if (ext4_test_inode_flag(inode, EXT4_INODE_ENCRYPT))
> return false;
> - if (ext4_verity_inode(inode))
> + if (ext4_test_inode_flag(inode, EXT4_INODE_VERITY))
> return false;
> return true;
> }
> @@ -4750,9 +4750,11 @@ void ext4_set_inode_flags(struct inode *inode)
> new_fl |= S_DAX;
> if (flags & EXT4_ENCRYPT_FL)
> new_fl |= S_ENCRYPTED;
> + if (flags & EXT4_VERITY_FL)
> + new_fl |= S_VERITY;
> inode_set_flags(inode, new_fl,
> S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX|
> - S_ENCRYPTED);
> + S_ENCRYPTED|S_VERITY);
> }
>
> static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode,
> @@ -5510,7 +5512,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
> if (error)
> return error;
>
> - if (ext4_verity_inode(inode)) {
> + if (IS_VERITY(inode)) {
> error = fsverity_prepare_setattr(dentry, attr);
> if (error)
> return error;
> diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
> index 7252f0a60cdb..2c037df629dd 100644
> --- a/fs/ext4/readpage.c
> +++ b/fs/ext4/readpage.c
> @@ -206,7 +206,7 @@ static void mpage_end_io(struct bio *bio)
> static inline loff_t ext4_readpage_limit(struct inode *inode)
> {
> #ifdef CONFIG_EXT4_FS_VERITY
> - if (ext4_verity_inode(inode)) {
> + if (IS_VERITY(inode)) {
> if (inode->i_verity_info)
> /* limit to end of metadata region */
> return fsverity_full_i_size(inode);
> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> index 16fb483a6f4a..35ed3c48f8d2 100644
> --- a/fs/ext4/super.c
> +++ b/fs/ext4/super.c
> @@ -1344,6 +1344,7 @@ static int ext4_set_verity(struct inode *inode, loff_t data_i_size)
> err = ext4_reserve_inode_write(handle, inode, &iloc);
> if (err == 0) {
> ext4_set_inode_flag(inode, EXT4_INODE_VERITY);
> + ext4_set_inode_flags(inode);
> EXT4_I(inode)->i_disksize = data_i_size;
> err = ext4_mark_iloc_dirty(handle, inode, &iloc);
> }
> --
> 2.19.1
>

Reviewed-by: Eric Biggers <[email protected]>

Note: we should also move the IS_VERITY() check into fsverity_file_open() and
fsverity_prepare_setattr(), to be like fscrypt_file_open() and
fscrypt_prepare_setattr(). But starting with just this is fine.

- Eric

2018-12-05 00:08:34

by Eric Biggers

[permalink] [raw]
Subject: Re: [PATCH V2 7/7] fsverity: Remove filesystem specific build config option

Hi Chandan,

On Tue, Dec 04, 2018 at 03:26:50PM +0530, Chandan Rajendra wrote:
> In order to have a common code base for fsverity "post read" processing
> for all filesystems which support fsverity, this commit removes
> filesystem specific build config option (e.g. CONFIG_EXT4_FS_VERITY)
> and replaces it with a build option (i.e. CONFIG_FS_VERITY) whose
> value affects all the filesystems making use of fsverity.
>
> Signed-off-by: Chandan Rajendra <[email protected]>
> ---
> Documentation/filesystems/fsverity.rst | 4 ++--
> fs/ext4/Kconfig | 20 --------------------
> fs/ext4/ext4.h | 2 --
> fs/ext4/readpage.c | 4 ++--
> fs/ext4/super.c | 6 +++---
> fs/ext4/sysfs.c | 4 ++--
> fs/f2fs/Kconfig | 20 --------------------
> fs/f2fs/data.c | 2 +-
> fs/f2fs/f2fs.h | 2 --
> fs/f2fs/super.c | 6 +++---
> fs/f2fs/sysfs.c | 4 ++--
> fs/verity/Kconfig | 3 ++-
> include/linux/fs.h | 4 ++--
> include/linux/fsverity.h | 3 +--
> 14 files changed, 20 insertions(+), 64 deletions(-)
>
[...]
> diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h
> index c30c4f6ed411..f37132c640ee 100644
> --- a/include/linux/fsverity.h
> +++ b/include/linux/fsverity.h
> @@ -19,8 +19,7 @@ struct fsverity_operations {
> int (*get_metadata_end)(struct inode *inode, loff_t *metadata_end_ret);
> };
>
> -#if __FS_HAS_VERITY
> -
> +#ifdef CONFIG_FS_VERITY
> /* ioctl.c */
> extern int fsverity_ioctl_enable(struct file *filp, const void __user *arg);
> extern int fsverity_ioctl_measure(struct file *filp, void __user *arg);
> --
> 2.19.1
>

Can you grep for __FS_HAS_VERITY? It's still mentioned twice in comments for
this #ifdef (these should be changed to CONFIG_FS_VERITY), and it's still
defined in fs/verity/fsverity_private.h (that one should be removed).

Thanks,

- Eric

2018-12-04 09:57:15

by Chandan Rajendra

[permalink] [raw]
Subject: [PATCH V2 1/7] ext4: use IS_ENCRYPTED() to check encryption status

This commit removes the ext4 specific ext4_encrypted_inode() and makes
use of the generic IS_ENCRYPTED() macro to check for the encryption
status of an inode.

Signed-off-by: Chandan Rajendra <[email protected]>
---
fs/ext4/dir.c | 8 ++++----
fs/ext4/ext4.h | 5 -----
fs/ext4/ext4_jbd2.h | 2 +-
fs/ext4/extents.c | 4 ++--
fs/ext4/ialloc.c | 2 +-
fs/ext4/inode.c | 14 +++++++-------
fs/ext4/move_extent.c | 3 +--
fs/ext4/namei.c | 8 ++++----
fs/ext4/page-io.c | 2 +-
fs/ext4/readpage.c | 2 +-
10 files changed, 22 insertions(+), 28 deletions(-)

diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index f93f9881ec18..fb7a64ea5679 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -111,7 +111,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
int dir_has_error = 0;
struct fscrypt_str fstr = FSTR_INIT(NULL, 0);

- if (ext4_encrypted_inode(inode)) {
+ if (IS_ENCRYPTED(inode)) {
err = fscrypt_get_encryption_info(inode);
if (err && err != -ENOKEY)
return err;
@@ -138,7 +138,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
return err;
}

- if (ext4_encrypted_inode(inode)) {
+ if (IS_ENCRYPTED(inode)) {
err = fscrypt_fname_alloc_buffer(inode, EXT4_NAME_LEN, &fstr);
if (err < 0)
return err;
@@ -245,7 +245,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
offset += ext4_rec_len_from_disk(de->rec_len,
sb->s_blocksize);
if (le32_to_cpu(de->inode)) {
- if (!ext4_encrypted_inode(inode)) {
+ if (!IS_ENCRYPTED(inode)) {
if (!dir_emit(ctx, de->name,
de->name_len,
le32_to_cpu(de->inode),
@@ -613,7 +613,7 @@ static int ext4_dx_readdir(struct file *file, struct dir_context *ctx)

static int ext4_dir_open(struct inode * inode, struct file * filp)
{
- if (ext4_encrypted_inode(inode))
+ if (IS_ENCRYPTED(inode))
return fscrypt_get_encryption_info(inode) ? -EACCES : 0;
return 0;
}
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 80957f9d3cbe..2ae6ab88f218 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2297,11 +2297,6 @@ extern unsigned ext4_free_clusters_after_init(struct super_block *sb,
struct ext4_group_desc *gdp);
ext4_fsblk_t ext4_inode_to_goal_block(struct inode *);

-static inline bool ext4_encrypted_inode(struct inode *inode)
-{
- return ext4_test_inode_flag(inode, EXT4_INODE_ENCRYPT);
-}
-
static inline bool ext4_verity_inode(struct inode *inode)
{
#ifdef CONFIG_EXT4_FS_VERITY
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
index 15b6dd733780..a1ac7e9245ec 100644
--- a/fs/ext4/ext4_jbd2.h
+++ b/fs/ext4/ext4_jbd2.h
@@ -411,7 +411,7 @@ static inline int ext4_inode_journal_mode(struct inode *inode)
(ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) &&
!test_opt(inode->i_sb, DELALLOC))) {
/* We do not support data journalling for encrypted data */
- if (S_ISREG(inode->i_mode) && ext4_encrypted_inode(inode))
+ if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode))
return EXT4_INODE_ORDERED_DATA_MODE; /* ordered */
return EXT4_INODE_JOURNAL_DATA_MODE; /* journal data */
}
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 240b6dea5441..79d986dbf5af 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -3631,7 +3631,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
max_zeroout = sbi->s_extent_max_zeroout_kb >>
(inode->i_sb->s_blocksize_bits - 10);

- if (ext4_encrypted_inode(inode))
+ if (IS_ENCRYPTED(inode))
max_zeroout = 0;

/*
@@ -4818,7 +4818,7 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
* leave it disabled for encrypted inodes for now. This is a
* bug we should fix....
*/
- if (ext4_encrypted_inode(inode) &&
+ if (IS_ENCRYPTED(inode) &&
(mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE |
FALLOC_FL_ZERO_RANGE)))
return -EOPNOTSUPP;
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 2addcb8730e1..3002f110eb4f 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -771,7 +771,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
if (unlikely(ext4_forced_shutdown(sbi)))
return ERR_PTR(-EIO);

- if ((ext4_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
+ if ((IS_ENCRYPTED(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) &&
!(i_flags & EXT4_EA_INODE_FL)) {
err = fscrypt_get_encryption_info(dir);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index d7019f5dca6f..ef835bd46155 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -415,7 +415,7 @@ int ext4_issue_zeroout(struct inode *inode, ext4_lblk_t lblk, ext4_fsblk_t pblk,
{
int ret;

- if (ext4_encrypted_inode(inode))
+ if (IS_ENCRYPTED(inode))
return fscrypt_zeroout_range(inode, lblk, pblk, len);

ret = sb_issue_zeroout(inode->i_sb, pblk, len, GFP_NOFS);
@@ -1217,7 +1217,7 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len,
(block_start < from || block_end > to)) {
ll_rw_block(REQ_OP_READ, 0, 1, &bh);
*wait_bh++ = bh;
- decrypt = ext4_encrypted_inode(inode) &&
+ decrypt = IS_ENCRYPTED(inode) &&
S_ISREG(inode->i_mode);
}
}
@@ -3880,7 +3880,7 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
ssize_t ret;

#ifdef CONFIG_EXT4_FS_ENCRYPTION
- if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode))
+ if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode))
return 0;
#endif

@@ -4068,7 +4068,7 @@ static int __ext4_block_zero_page_range(handle_t *handle,
if (!buffer_uptodate(bh))
goto unlock;
if (S_ISREG(inode->i_mode) &&
- ext4_encrypted_inode(inode)) {
+ IS_ENCRYPTED(inode)) {
/* We expect the key to be set. */
BUG_ON(!fscrypt_has_encryption_key(inode));
BUG_ON(blocksize != PAGE_SIZE);
@@ -4144,7 +4144,7 @@ static int ext4_block_truncate_page(handle_t *handle,
struct inode *inode = mapping->host;

/* If we are processing an encrypted inode during orphan list handling */
- if (ext4_encrypted_inode(inode) && !fscrypt_has_encryption_key(inode))
+ if (IS_ENCRYPTED(inode) && !fscrypt_has_encryption_key(inode))
return 0;

blocksize = inode->i_sb->s_blocksize;
@@ -4724,7 +4724,7 @@ static bool ext4_should_use_dax(struct inode *inode)
return false;
if (ext4_has_inline_data(inode))
return false;
- if (ext4_encrypted_inode(inode))
+ if (ext4_test_inode_flag(inode, EXT4_INODE_ENCRYPT))
return false;
if (ext4_verity_inode(inode))
return false;
@@ -5050,7 +5050,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
ret = -EFSCORRUPTED;
goto bad_inode;
}
- if (ext4_encrypted_inode(inode)) {
+ if (IS_ENCRYPTED(inode)) {
inode->i_op = &ext4_encrypted_symlink_inode_operations;
ext4_set_aops(inode);
} else if (ext4_inode_is_fast_symlink(inode)) {
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index 2f5be02fc6f6..1083a9f3f16a 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -592,8 +592,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
return -EOPNOTSUPP;
}

- if (ext4_encrypted_inode(orig_inode) ||
- ext4_encrypted_inode(donor_inode)) {
+ if (IS_ENCRYPTED(orig_inode) || IS_ENCRYPTED(donor_inode)) {
ext4_msg(orig_inode->i_sb, KERN_ERR,
"Online defrag not supported for encrypted files");
return -EOPNOTSUPP;
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 67a38532032a..0de60207a963 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -620,7 +620,7 @@ static struct stats dx_show_leaf(struct inode *dir,

name = de->name;
len = de->name_len;
- if (ext4_encrypted_inode(dir))
+ if (IS_ENCRYPTED(dir))
res = fscrypt_get_encryption_info(dir);
if (res) {
printk(KERN_WARNING "Error setting up"
@@ -985,7 +985,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
EXT4_DIR_REC_LEN(0));
#ifdef CONFIG_EXT4_FS_ENCRYPTION
/* Check if the directory is encrypted */
- if (ext4_encrypted_inode(dir)) {
+ if (IS_ENCRYPTED(dir)) {
err = fscrypt_get_encryption_info(dir);
if (err < 0) {
brelse(bh);
@@ -1014,7 +1014,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
continue;
if (de->inode == 0)
continue;
- if (!ext4_encrypted_inode(dir)) {
+ if (!IS_ENCRYPTED(dir)) {
tmp_str.name = de->name;
tmp_str.len = de->name_len;
err = ext4_htree_store_dirent(dir_file,
@@ -1577,7 +1577,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
ino);
return ERR_PTR(-EFSCORRUPTED);
}
- if (!IS_ERR(inode) && ext4_encrypted_inode(dir) &&
+ if (!IS_ERR(inode) && IS_ENCRYPTED(dir) &&
(S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
!fscrypt_has_permitted_context(dir, inode)) {
ext4_warning(inode->i_sb,
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 2aa62d58d8dd..008c20b58f98 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -477,7 +477,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io,

bh = head = page_buffers(page);

- if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode) &&
+ if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode) &&
nr_to_submit) {
gfp_t gfp_flags = GFP_NOFS;

diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
index d3dd1ff745db..45e707fb9749 100644
--- a/fs/ext4/readpage.c
+++ b/fs/ext4/readpage.c
@@ -156,7 +156,7 @@ static struct bio_post_read_ctx *get_bio_post_read_ctx(struct inode *inode,
unsigned int post_read_steps = 0;
struct bio_post_read_ctx *ctx = NULL;

- if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode))
+ if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode))
post_read_steps |= 1 << STEP_DECRYPT;
#ifdef CONFIG_EXT4_FS_VERITY
if (inode->i_verity_info != NULL &&
--
2.19.1

2018-12-04 23:49:12

by Eric Biggers

[permalink] [raw]
Subject: Re: [PATCH V2 4/7] Add S_VERITY and IS_VERITY()

On Tue, Dec 04, 2018 at 03:26:47PM +0530, Chandan Rajendra wrote:
> Similar to S_ENCRYPTED/IS_ENCRYPTED(), this commit adds
> S_VERITY/IS_VERITY() to be able to check if a VFS inode has verity
> information associated with it.
>
> Signed-off-by: Chandan Rajendra <[email protected]>
> ---
> include/linux/fs.h | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index 389a35e028bf..de602d9f8d0e 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -1938,6 +1938,7 @@ struct super_operations {
> #define S_DAX 0 /* Make all the DAX code disappear */
> #endif
> #define S_ENCRYPTED 16384 /* Encrypted file (using fs/crypto/) */
> +#define S_VERITY 32768 /* Verity file (using fs/verity/) */
>
> /*
> * Note that nosuid etc flags are inode-specific: setting some file-system
> @@ -1978,6 +1979,7 @@ static inline bool sb_rdonly(const struct super_block *sb) { return sb->s_flags
> #define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC)
> #define IS_DAX(inode) ((inode)->i_flags & S_DAX)
> #define IS_ENCRYPTED(inode) ((inode)->i_flags & S_ENCRYPTED)
> +#define IS_VERITY(inode) ((inode)->i_flags & S_VERITY)
>
> #define IS_WHITEOUT(inode) (S_ISCHR(inode->i_mode) && \
> (inode)->i_rdev == WHITEOUT_DEV)
> --
> 2.19.1
>

Reviewed-by: Eric Biggers <[email protected]>

2018-12-12 01:52:15

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH V2 3/7] fscrypt: remove filesystem specific build config option

Hi,

On Tue, Dec 04, 2018 at 03:26:46PM +0530, Chandan Rajendra wrote:
> In order to have a common code base for fscrypt "post read" processing
> for all filesystems which support encryption, this commit removes
> filesystem specific build config option (e.g. CONFIG_EXT4_FS_ENCRYPTION)
> and replaces it with a build option (i.e. CONFIG_FS_ENCRYPTION) whose
> value affects all the filesystems making use of fscrypt.
>
> Signed-off-by: Chandan Rajendra <[email protected]>

this patch causes a recursive dependency when trying to build ia64 images.

make ARCH=ia64 allnoconfig:

scripts/kconfig/conf --allnoconfig Kconfig
arch/ia64/Kconfig:126:error: recursive dependency detected!
arch/ia64/Kconfig:126: choice <choice> contains symbol IA64_HP_SIM
arch/ia64/Kconfig:200: symbol IA64_HP_SIM is part of choice PM
kernel/power/Kconfig:144: symbol PM is selected by PM_SLEEP
kernel/power/Kconfig:104: symbol PM_SLEEP depends on HIBERNATE_CALLBACKS
kernel/power/Kconfig:31: symbol HIBERNATE_CALLBACKS is selected by HIBERNATION
kernel/power/Kconfig:34: symbol HIBERNATION depends on SWAP
init/Kconfig:250: symbol SWAP depends on BLOCK
block/Kconfig:5: symbol BLOCK is selected by UBIFS_FS
fs/ubifs/Kconfig:1: symbol UBIFS_FS depends on MISC_FILESYSTEMS
fs/Kconfig:220: symbol MISC_FILESYSTEMS is selected by ACPI_APEI
drivers/acpi/apei/Kconfig:8: symbol ACPI_APEI depends on ACPI
drivers/acpi/Kconfig:9: symbol ACPI depends on ARCH_SUPPORTS_ACPI
drivers/acpi/Kconfig:6: symbol ARCH_SUPPORTS_ACPI is selected by IA64_HP_SIM
arch/ia64/Kconfig:200: symbol IA64_HP_SIM is part of choice <choice>
For a resolution refer to Documentation/kbuild/kconfig-language.txt
subsection "Kconfig recursive dependency limitations"

scripts/kconfig/Makefile:69: recipe for target 'allnoconfig' failed

Reverting the patch fixes the problem.

Guenter

---
bisect log:

# bad: [60bec71b5acb0b469d07e73a348f6610236ae7fa] Add linux-next specific files for 20181211
# good: [40e020c129cfc991e8ab4736d2665351ffd1468d] Linux 4.20-rc6
git bisect start 'HEAD' 'v4.20-rc6'
# bad: [9d9400c203d670e3b002336bf3a70a34c8023853] Merge remote-tracking branch 'spi-nor/spi-nor/next'
git bisect bad 9d9400c203d670e3b002336bf3a70a34c8023853
# bad: [98d439a801d02e313d762fa08368b680e4c0d961] Merge remote-tracking branch 'vfs/for-next'
git bisect bad 98d439a801d02e313d762fa08368b680e4c0d961
# good: [79271eb86e6aca36f962657ea4efa248fc84e2fa] Merge remote-tracking branch 'samsung-krzk/for-next'
git bisect good 79271eb86e6aca36f962657ea4efa248fc84e2fa
# good: [b506abfb5f33d7358cfc9818054e3a834813f7af] Merge remote-tracking branch 'mips/mips-next'
git bisect good b506abfb5f33d7358cfc9818054e3a834813f7af
# bad: [d58e2b0647688a51a96e373589c0597f493ba066] Merge remote-tracking branch 'befs/for-next'
git bisect bad d58e2b0647688a51a96e373589c0597f493ba066
# good: [39f8d343f04868e14abdf1c7ca31d53855bf6f81] Merge remote-tracking branch 'risc-v/for-next'
git bisect good 39f8d343f04868e14abdf1c7ca31d53855bf6f81
# good: [e2f3efdaf1b66f9ac1a5ae16a99a1ff5b0956515] Merge branch 'xtensa-cleanups' into xtensa-for-next
git bisect good e2f3efdaf1b66f9ac1a5ae16a99a1ff5b0956515
# bad: [25da54f1d777ac4a612d9b036f8ac41baf746674] fsverity: Move verity status check to fsverity_prepare_setattr
git bisect bad 25da54f1d777ac4a612d9b036f8ac41baf746674
# good: [a391d6149e706be54aeed8757769910f1b2445d4] fs-verity: add CRC-32C support
git bisect good a391d6149e706be54aeed8757769910f1b2445d4
# good: [848a010287e6a02f1e46c344bbffeb987ed2a0aa] f2fs: use IS_ENCRYPTED() to check encryption status
git bisect good 848a010287e6a02f1e46c344bbffeb987ed2a0aa
# bad: [9f55ada08b452bde55c02ae9bc97c19990ff5c36] ext4: use IS_VERITY() to check inode's fsverity status
git bisect bad 9f55ada08b452bde55c02ae9bc97c19990ff5c36
# bad: [824834dc4a5e595ef24ba44086efa56b97ad4990] Add S_VERITY and IS_VERITY()
git bisect bad 824834dc4a5e595ef24ba44086efa56b97ad4990
# bad: [6956097c429aae498d26b8603b2dec39250b8940] fscrypt: remove filesystem specific build config option
git bisect bad 6956097c429aae498d26b8603b2dec39250b8940
# first bad commit: [6956097c429aae498d26b8603b2dec39250b8940] fscrypt: remove filesystem specific build config option

2018-12-12 06:27:39

by Chandan Rajendra

[permalink] [raw]
Subject: Re: [PATCH V2 3/7] fscrypt: remove filesystem specific build config option

On Wednesday, December 12, 2018 8:18:12 AM IST Eric Biggers wrote:
> On Tue, Dec 11, 2018 at 05:52:11PM -0800, Guenter Roeck wrote:
> > Hi,
> >
> > On Tue, Dec 04, 2018 at 03:26:46PM +0530, Chandan Rajendra wrote:
> > > In order to have a common code base for fscrypt "post read" processing
> > > for all filesystems which support encryption, this commit removes
> > > filesystem specific build config option (e.g. CONFIG_EXT4_FS_ENCRYPTION)
> > > and replaces it with a build option (i.e. CONFIG_FS_ENCRYPTION) whose
> > > value affects all the filesystems making use of fscrypt.
> > >
> > > Signed-off-by: Chandan Rajendra <[email protected]>
> >
> > this patch causes a recursive dependency when trying to build ia64 images.
> >
> > make ARCH=ia64 allnoconfig:
> >
> > scripts/kconfig/conf --allnoconfig Kconfig
> > arch/ia64/Kconfig:126:error: recursive dependency detected!
> > arch/ia64/Kconfig:126: choice <choice> contains symbol IA64_HP_SIM
> > arch/ia64/Kconfig:200: symbol IA64_HP_SIM is part of choice PM
> > kernel/power/Kconfig:144: symbol PM is selected by PM_SLEEP
> > kernel/power/Kconfig:104: symbol PM_SLEEP depends on HIBERNATE_CALLBACKS
> > kernel/power/Kconfig:31: symbol HIBERNATE_CALLBACKS is selected by HIBERNATION
> > kernel/power/Kconfig:34: symbol HIBERNATION depends on SWAP
> > init/Kconfig:250: symbol SWAP depends on BLOCK
> > block/Kconfig:5: symbol BLOCK is selected by UBIFS_FS
> > fs/ubifs/Kconfig:1: symbol UBIFS_FS depends on MISC_FILESYSTEMS
> > fs/Kconfig:220: symbol MISC_FILESYSTEMS is selected by ACPI_APEI
> > drivers/acpi/apei/Kconfig:8: symbol ACPI_APEI depends on ACPI
> > drivers/acpi/Kconfig:9: symbol ACPI depends on ARCH_SUPPORTS_ACPI
> > drivers/acpi/Kconfig:6: symbol ARCH_SUPPORTS_ACPI is selected by IA64_HP_SIM
> > arch/ia64/Kconfig:200: symbol IA64_HP_SIM is part of choice <choice>
> > For a resolution refer to Documentation/kbuild/kconfig-language.txt
> > subsection "Kconfig recursive dependency limitations"
> >
> > scripts/kconfig/Makefile:69: recipe for target 'allnoconfig' failed
> >
> > Reverting the patch fixes the problem.
> >
>
> Thanks for the report. Chandan, it appears the problem is UBIFS_FS selecting
> BLOCK. It's actually not necessary because now the parts of fs/crypto/ that
> depend on BLOCK are separated out into a separate file fs/crypto/bio.c that is
> only compiled with CONFIG_BLOCK. So how about just removing the selection of
> BLOCK from fs/ubifs/Kconfig:
>
> select BLOCK if FS_ENCRYPTION
>

Yes, I will do that.

Also, Apologies for sending V4 of the patchset without checking for newer
responses from you.

--
chandan

2018-12-12 03:16:10

by Guenter Roeck

[permalink] [raw]
Subject: Re: [PATCH V2 3/7] fscrypt: remove filesystem specific build config option

On 12/11/18 6:48 PM, Eric Biggers wrote:
> On Tue, Dec 11, 2018 at 05:52:11PM -0800, Guenter Roeck wrote:
>> Hi,
>>
>> On Tue, Dec 04, 2018 at 03:26:46PM +0530, Chandan Rajendra wrote:
>>> In order to have a common code base for fscrypt "post read" processing
>>> for all filesystems which support encryption, this commit removes
>>> filesystem specific build config option (e.g. CONFIG_EXT4_FS_ENCRYPTION)
>>> and replaces it with a build option (i.e. CONFIG_FS_ENCRYPTION) whose
>>> value affects all the filesystems making use of fscrypt.
>>>
>>> Signed-off-by: Chandan Rajendra <[email protected]>
>>
>> this patch causes a recursive dependency when trying to build ia64 images.
>>
>> make ARCH=ia64 allnoconfig:
>>
>> scripts/kconfig/conf --allnoconfig Kconfig
>> arch/ia64/Kconfig:126:error: recursive dependency detected!
>> arch/ia64/Kconfig:126: choice <choice> contains symbol IA64_HP_SIM
>> arch/ia64/Kconfig:200: symbol IA64_HP_SIM is part of choice PM
>> kernel/power/Kconfig:144: symbol PM is selected by PM_SLEEP
>> kernel/power/Kconfig:104: symbol PM_SLEEP depends on HIBERNATE_CALLBACKS
>> kernel/power/Kconfig:31: symbol HIBERNATE_CALLBACKS is selected by HIBERNATION
>> kernel/power/Kconfig:34: symbol HIBERNATION depends on SWAP
>> init/Kconfig:250: symbol SWAP depends on BLOCK
>> block/Kconfig:5: symbol BLOCK is selected by UBIFS_FS
>> fs/ubifs/Kconfig:1: symbol UBIFS_FS depends on MISC_FILESYSTEMS
>> fs/Kconfig:220: symbol MISC_FILESYSTEMS is selected by ACPI_APEI
>> drivers/acpi/apei/Kconfig:8: symbol ACPI_APEI depends on ACPI
>> drivers/acpi/Kconfig:9: symbol ACPI depends on ARCH_SUPPORTS_ACPI
>> drivers/acpi/Kconfig:6: symbol ARCH_SUPPORTS_ACPI is selected by IA64_HP_SIM
>> arch/ia64/Kconfig:200: symbol IA64_HP_SIM is part of choice <choice>
>> For a resolution refer to Documentation/kbuild/kconfig-language.txt
>> subsection "Kconfig recursive dependency limitations"
>>
>> scripts/kconfig/Makefile:69: recipe for target 'allnoconfig' failed
>>
>> Reverting the patch fixes the problem.
>>
>
> Thanks for the report. Chandan, it appears the problem is UBIFS_FS selecting
> BLOCK. It's actually not necessary because now the parts of fs/crypto/ that
> depend on BLOCK are separated out into a separate file fs/crypto/bio.c that is
> only compiled with CONFIG_BLOCK. So how about just removing the selection of
> BLOCK from fs/ubifs/Kconfig:
>
> select BLOCK if FS_ENCRYPTION
>
The recursion is gone if I make this change.

Guenter

2018-12-04 09:57:38

by Chandan Rajendra

[permalink] [raw]
Subject: [PATCH V2 4/7] Add S_VERITY and IS_VERITY()

Similar to S_ENCRYPTED/IS_ENCRYPTED(), this commit adds
S_VERITY/IS_VERITY() to be able to check if a VFS inode has verity
information associated with it.

Signed-off-by: Chandan Rajendra <[email protected]>
---
include/linux/fs.h | 2 ++
1 file changed, 2 insertions(+)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 389a35e028bf..de602d9f8d0e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1938,6 +1938,7 @@ struct super_operations {
#define S_DAX 0 /* Make all the DAX code disappear */
#endif
#define S_ENCRYPTED 16384 /* Encrypted file (using fs/crypto/) */
+#define S_VERITY 32768 /* Verity file (using fs/verity/) */

/*
* Note that nosuid etc flags are inode-specific: setting some file-system
@@ -1978,6 +1979,7 @@ static inline bool sb_rdonly(const struct super_block *sb) { return sb->s_flags
#define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC)
#define IS_DAX(inode) ((inode)->i_flags & S_DAX)
#define IS_ENCRYPTED(inode) ((inode)->i_flags & S_ENCRYPTED)
+#define IS_VERITY(inode) ((inode)->i_flags & S_VERITY)

#define IS_WHITEOUT(inode) (S_ISCHR(inode->i_mode) && \
(inode)->i_rdev == WHITEOUT_DEV)
--
2.19.1

2018-12-04 23:57:56

by Eric Biggers

[permalink] [raw]
Subject: Re: [PATCH V2 6/7] f2fs: use IS_VERITY() to check inode's fsverity status

Hi Chandan,

On Tue, Dec 04, 2018 at 03:26:49PM +0530, Chandan Rajendra wrote:
> This commit now uses IS_VERITY() macro to check if fsverity is
> enabled on an inode.
>
> Acked-by: Chao Yu <[email protected]>
> Signed-off-by: Chandan Rajendra <[email protected]>
> ---
> fs/f2fs/file.c | 6 +++---
> fs/f2fs/inode.c | 4 +++-
> 2 files changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> index 6c7ad15000b9..2eb4821d95d1 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -491,7 +491,7 @@ static int f2fs_file_open(struct inode *inode, struct file *filp)
> if (err)
> return err;
>
> - if (f2fs_verity_file(inode)) {
> + if (IS_VERITY(inode)) {
> err = fsverity_file_open(inode, filp);
> if (err)
> return err;
> @@ -701,7 +701,7 @@ int f2fs_getattr(const struct path *path, struct kstat *stat,
> struct f2fs_inode *ri;
> unsigned int flags;
>
> - if (f2fs_verity_file(inode)) {
> + if (IS_VERITY(inode)) {
> /*
> * For fs-verity we need to override i_size with the original
> * data i_size. This requires I/O to the file which with
> @@ -800,7 +800,7 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr)
> if (err)
> return err;
>
> - if (f2fs_verity_file(inode)) {
> + if (IS_VERITY(inode)) {
> err = fsverity_prepare_setattr(dentry, attr);
> if (err)
> return err;
> diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
> index ddef483ad689..02806feed64c 100644
> --- a/fs/f2fs/inode.c
> +++ b/fs/f2fs/inode.c
> @@ -45,9 +45,11 @@ void f2fs_set_inode_flags(struct inode *inode)
> new_fl |= S_DIRSYNC;
> if (f2fs_encrypted_inode(inode))
> new_fl |= S_ENCRYPTED;
> + if (f2fs_verity_file(inode))
> + new_fl |= S_VERITY;
> inode_set_flags(inode, new_fl,
> S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|
> - S_ENCRYPTED);
> + S_ENCRYPTED|S_VERITY);
> }
>
> static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri)
> --
> 2.19.1
>

Similar to what I said for fscrypt: why not remove f2fs_verity_file() entirely
and always use IS_VERITY() or file_is_verity() as appropriate?

- Eric

2018-12-12 02:48:15

by Eric Biggers

[permalink] [raw]
Subject: Re: [PATCH V2 3/7] fscrypt: remove filesystem specific build config option

On Tue, Dec 11, 2018 at 05:52:11PM -0800, Guenter Roeck wrote:
> Hi,
>
> On Tue, Dec 04, 2018 at 03:26:46PM +0530, Chandan Rajendra wrote:
> > In order to have a common code base for fscrypt "post read" processing
> > for all filesystems which support encryption, this commit removes
> > filesystem specific build config option (e.g. CONFIG_EXT4_FS_ENCRYPTION)
> > and replaces it with a build option (i.e. CONFIG_FS_ENCRYPTION) whose
> > value affects all the filesystems making use of fscrypt.
> >
> > Signed-off-by: Chandan Rajendra <[email protected]>
>
> this patch causes a recursive dependency when trying to build ia64 images.
>
> make ARCH=ia64 allnoconfig:
>
> scripts/kconfig/conf --allnoconfig Kconfig
> arch/ia64/Kconfig:126:error: recursive dependency detected!
> arch/ia64/Kconfig:126: choice <choice> contains symbol IA64_HP_SIM
> arch/ia64/Kconfig:200: symbol IA64_HP_SIM is part of choice PM
> kernel/power/Kconfig:144: symbol PM is selected by PM_SLEEP
> kernel/power/Kconfig:104: symbol PM_SLEEP depends on HIBERNATE_CALLBACKS
> kernel/power/Kconfig:31: symbol HIBERNATE_CALLBACKS is selected by HIBERNATION
> kernel/power/Kconfig:34: symbol HIBERNATION depends on SWAP
> init/Kconfig:250: symbol SWAP depends on BLOCK
> block/Kconfig:5: symbol BLOCK is selected by UBIFS_FS
> fs/ubifs/Kconfig:1: symbol UBIFS_FS depends on MISC_FILESYSTEMS
> fs/Kconfig:220: symbol MISC_FILESYSTEMS is selected by ACPI_APEI
> drivers/acpi/apei/Kconfig:8: symbol ACPI_APEI depends on ACPI
> drivers/acpi/Kconfig:9: symbol ACPI depends on ARCH_SUPPORTS_ACPI
> drivers/acpi/Kconfig:6: symbol ARCH_SUPPORTS_ACPI is selected by IA64_HP_SIM
> arch/ia64/Kconfig:200: symbol IA64_HP_SIM is part of choice <choice>
> For a resolution refer to Documentation/kbuild/kconfig-language.txt
> subsection "Kconfig recursive dependency limitations"
>
> scripts/kconfig/Makefile:69: recipe for target 'allnoconfig' failed
>
> Reverting the patch fixes the problem.
>

Thanks for the report. Chandan, it appears the problem is UBIFS_FS selecting
BLOCK. It's actually not necessary because now the parts of fs/crypto/ that
depend on BLOCK are separated out into a separate file fs/crypto/bio.c that is
only compiled with CONFIG_BLOCK. So how about just removing the selection of
BLOCK from fs/ubifs/Kconfig:

select BLOCK if FS_ENCRYPTION

- Eric

2018-12-04 23:12:09

by Eric Biggers

[permalink] [raw]
Subject: Re: [PATCH V2 1/7] ext4: use IS_ENCRYPTED() to check encryption status

On Tue, Dec 04, 2018 at 03:26:44PM +0530, Chandan Rajendra wrote:
> This commit removes the ext4 specific ext4_encrypted_inode() and makes
> use of the generic IS_ENCRYPTED() macro to check for the encryption
> status of an inode.
>
> Signed-off-by: Chandan Rajendra <[email protected]>

Reviewed-by: Eric Biggers <[email protected]>

Though if you send this out again, there are a few places where you can remove a
line break while remaining within 80 characters, due to IS_ENCRYPTED() being
shorter than ext4_encrypted_inode().

- Eric

> ---
> fs/ext4/dir.c | 8 ++++----
> fs/ext4/ext4.h | 5 -----
> fs/ext4/ext4_jbd2.h | 2 +-
> fs/ext4/extents.c | 4 ++--
> fs/ext4/ialloc.c | 2 +-
> fs/ext4/inode.c | 14 +++++++-------
> fs/ext4/move_extent.c | 3 +--
> fs/ext4/namei.c | 8 ++++----
> fs/ext4/page-io.c | 2 +-
> fs/ext4/readpage.c | 2 +-
> 10 files changed, 22 insertions(+), 28 deletions(-)
>
> diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
> index f93f9881ec18..fb7a64ea5679 100644
> --- a/fs/ext4/dir.c
> +++ b/fs/ext4/dir.c
> @@ -111,7 +111,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
> int dir_has_error = 0;
> struct fscrypt_str fstr = FSTR_INIT(NULL, 0);
>
> - if (ext4_encrypted_inode(inode)) {
> + if (IS_ENCRYPTED(inode)) {
> err = fscrypt_get_encryption_info(inode);
> if (err && err != -ENOKEY)
> return err;
> @@ -138,7 +138,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
> return err;
> }
>
> - if (ext4_encrypted_inode(inode)) {
> + if (IS_ENCRYPTED(inode)) {
> err = fscrypt_fname_alloc_buffer(inode, EXT4_NAME_LEN, &fstr);
> if (err < 0)
> return err;
> @@ -245,7 +245,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
> offset += ext4_rec_len_from_disk(de->rec_len,
> sb->s_blocksize);
> if (le32_to_cpu(de->inode)) {
> - if (!ext4_encrypted_inode(inode)) {
> + if (!IS_ENCRYPTED(inode)) {
> if (!dir_emit(ctx, de->name,
> de->name_len,
> le32_to_cpu(de->inode),
> @@ -613,7 +613,7 @@ static int ext4_dx_readdir(struct file *file, struct dir_context *ctx)
>
> static int ext4_dir_open(struct inode * inode, struct file * filp)
> {
> - if (ext4_encrypted_inode(inode))
> + if (IS_ENCRYPTED(inode))
> return fscrypt_get_encryption_info(inode) ? -EACCES : 0;
> return 0;
> }
> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
> index 80957f9d3cbe..2ae6ab88f218 100644
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -2297,11 +2297,6 @@ extern unsigned ext4_free_clusters_after_init(struct super_block *sb,
> struct ext4_group_desc *gdp);
> ext4_fsblk_t ext4_inode_to_goal_block(struct inode *);
>
> -static inline bool ext4_encrypted_inode(struct inode *inode)
> -{
> - return ext4_test_inode_flag(inode, EXT4_INODE_ENCRYPT);
> -}
> -
> static inline bool ext4_verity_inode(struct inode *inode)
> {
> #ifdef CONFIG_EXT4_FS_VERITY
> diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
> index 15b6dd733780..a1ac7e9245ec 100644
> --- a/fs/ext4/ext4_jbd2.h
> +++ b/fs/ext4/ext4_jbd2.h
> @@ -411,7 +411,7 @@ static inline int ext4_inode_journal_mode(struct inode *inode)
> (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) &&
> !test_opt(inode->i_sb, DELALLOC))) {
> /* We do not support data journalling for encrypted data */
> - if (S_ISREG(inode->i_mode) && ext4_encrypted_inode(inode))
> + if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode))
> return EXT4_INODE_ORDERED_DATA_MODE; /* ordered */
> return EXT4_INODE_JOURNAL_DATA_MODE; /* journal data */
> }
> diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
> index 240b6dea5441..79d986dbf5af 100644
> --- a/fs/ext4/extents.c
> +++ b/fs/ext4/extents.c
> @@ -3631,7 +3631,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
> max_zeroout = sbi->s_extent_max_zeroout_kb >>
> (inode->i_sb->s_blocksize_bits - 10);
>
> - if (ext4_encrypted_inode(inode))
> + if (IS_ENCRYPTED(inode))
> max_zeroout = 0;
>
> /*
> @@ -4818,7 +4818,7 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
> * leave it disabled for encrypted inodes for now. This is a
> * bug we should fix....
> */
> - if (ext4_encrypted_inode(inode) &&
> + if (IS_ENCRYPTED(inode) &&
> (mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE |
> FALLOC_FL_ZERO_RANGE)))
> return -EOPNOTSUPP;
> diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
> index 2addcb8730e1..3002f110eb4f 100644
> --- a/fs/ext4/ialloc.c
> +++ b/fs/ext4/ialloc.c
> @@ -771,7 +771,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
> if (unlikely(ext4_forced_shutdown(sbi)))
> return ERR_PTR(-EIO);
>
> - if ((ext4_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
> + if ((IS_ENCRYPTED(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
> (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) &&
> !(i_flags & EXT4_EA_INODE_FL)) {
> err = fscrypt_get_encryption_info(dir);
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index d7019f5dca6f..ef835bd46155 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -415,7 +415,7 @@ int ext4_issue_zeroout(struct inode *inode, ext4_lblk_t lblk, ext4_fsblk_t pblk,
> {
> int ret;
>
> - if (ext4_encrypted_inode(inode))
> + if (IS_ENCRYPTED(inode))
> return fscrypt_zeroout_range(inode, lblk, pblk, len);
>
> ret = sb_issue_zeroout(inode->i_sb, pblk, len, GFP_NOFS);
> @@ -1217,7 +1217,7 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len,
> (block_start < from || block_end > to)) {
> ll_rw_block(REQ_OP_READ, 0, 1, &bh);
> *wait_bh++ = bh;
> - decrypt = ext4_encrypted_inode(inode) &&
> + decrypt = IS_ENCRYPTED(inode) &&
> S_ISREG(inode->i_mode);
> }
> }
> @@ -3880,7 +3880,7 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
> ssize_t ret;
>
> #ifdef CONFIG_EXT4_FS_ENCRYPTION
> - if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode))
> + if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode))
> return 0;
> #endif
>
> @@ -4068,7 +4068,7 @@ static int __ext4_block_zero_page_range(handle_t *handle,
> if (!buffer_uptodate(bh))
> goto unlock;
> if (S_ISREG(inode->i_mode) &&
> - ext4_encrypted_inode(inode)) {
> + IS_ENCRYPTED(inode)) {
> /* We expect the key to be set. */
> BUG_ON(!fscrypt_has_encryption_key(inode));
> BUG_ON(blocksize != PAGE_SIZE);
> @@ -4144,7 +4144,7 @@ static int ext4_block_truncate_page(handle_t *handle,
> struct inode *inode = mapping->host;
>
> /* If we are processing an encrypted inode during orphan list handling */
> - if (ext4_encrypted_inode(inode) && !fscrypt_has_encryption_key(inode))
> + if (IS_ENCRYPTED(inode) && !fscrypt_has_encryption_key(inode))
> return 0;
>
> blocksize = inode->i_sb->s_blocksize;
> @@ -4724,7 +4724,7 @@ static bool ext4_should_use_dax(struct inode *inode)
> return false;
> if (ext4_has_inline_data(inode))
> return false;
> - if (ext4_encrypted_inode(inode))
> + if (ext4_test_inode_flag(inode, EXT4_INODE_ENCRYPT))
> return false;
> if (ext4_verity_inode(inode))
> return false;
> @@ -5050,7 +5050,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
> ret = -EFSCORRUPTED;
> goto bad_inode;
> }
> - if (ext4_encrypted_inode(inode)) {
> + if (IS_ENCRYPTED(inode)) {
> inode->i_op = &ext4_encrypted_symlink_inode_operations;
> ext4_set_aops(inode);
> } else if (ext4_inode_is_fast_symlink(inode)) {
> diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
> index 2f5be02fc6f6..1083a9f3f16a 100644
> --- a/fs/ext4/move_extent.c
> +++ b/fs/ext4/move_extent.c
> @@ -592,8 +592,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
> return -EOPNOTSUPP;
> }
>
> - if (ext4_encrypted_inode(orig_inode) ||
> - ext4_encrypted_inode(donor_inode)) {
> + if (IS_ENCRYPTED(orig_inode) || IS_ENCRYPTED(donor_inode)) {
> ext4_msg(orig_inode->i_sb, KERN_ERR,
> "Online defrag not supported for encrypted files");
> return -EOPNOTSUPP;
> diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
> index 67a38532032a..0de60207a963 100644
> --- a/fs/ext4/namei.c
> +++ b/fs/ext4/namei.c
> @@ -620,7 +620,7 @@ static struct stats dx_show_leaf(struct inode *dir,
>
> name = de->name;
> len = de->name_len;
> - if (ext4_encrypted_inode(dir))
> + if (IS_ENCRYPTED(dir))
> res = fscrypt_get_encryption_info(dir);
> if (res) {
> printk(KERN_WARNING "Error setting up"
> @@ -985,7 +985,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
> EXT4_DIR_REC_LEN(0));
> #ifdef CONFIG_EXT4_FS_ENCRYPTION
> /* Check if the directory is encrypted */
> - if (ext4_encrypted_inode(dir)) {
> + if (IS_ENCRYPTED(dir)) {
> err = fscrypt_get_encryption_info(dir);
> if (err < 0) {
> brelse(bh);
> @@ -1014,7 +1014,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
> continue;
> if (de->inode == 0)
> continue;
> - if (!ext4_encrypted_inode(dir)) {
> + if (!IS_ENCRYPTED(dir)) {
> tmp_str.name = de->name;
> tmp_str.len = de->name_len;
> err = ext4_htree_store_dirent(dir_file,
> @@ -1577,7 +1577,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
> ino);
> return ERR_PTR(-EFSCORRUPTED);
> }
> - if (!IS_ERR(inode) && ext4_encrypted_inode(dir) &&
> + if (!IS_ERR(inode) && IS_ENCRYPTED(dir) &&
> (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
> !fscrypt_has_permitted_context(dir, inode)) {
> ext4_warning(inode->i_sb,
> diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
> index 2aa62d58d8dd..008c20b58f98 100644
> --- a/fs/ext4/page-io.c
> +++ b/fs/ext4/page-io.c
> @@ -477,7 +477,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
>
> bh = head = page_buffers(page);
>
> - if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode) &&
> + if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode) &&
> nr_to_submit) {
> gfp_t gfp_flags = GFP_NOFS;
>
> diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
> index d3dd1ff745db..45e707fb9749 100644
> --- a/fs/ext4/readpage.c
> +++ b/fs/ext4/readpage.c
> @@ -156,7 +156,7 @@ static struct bio_post_read_ctx *get_bio_post_read_ctx(struct inode *inode,
> unsigned int post_read_steps = 0;
> struct bio_post_read_ctx *ctx = NULL;
>
> - if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode))
> + if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode))
> post_read_steps |= 1 << STEP_DECRYPT;
> #ifdef CONFIG_EXT4_FS_VERITY
> if (inode->i_verity_info != NULL &&
> --
> 2.19.1
>

2018-12-10 18:04:26

by Eric Biggers

[permalink] [raw]
Subject: Re: [PATCH V2 3/7] fscrypt: remove filesystem specific build config option

On Sat, Dec 08, 2018 at 12:37:20PM +0530, Chandan Rajendra wrote:
> On Wednesday, December 5, 2018 5:13:21 AM IST Eric Biggers wrote:
> > Hi Chandan,
> >
> > On Tue, Dec 04, 2018 at 03:26:46PM +0530, Chandan Rajendra wrote:
> > > In order to have a common code base for fscrypt "post read" processing
> > > for all filesystems which support encryption, this commit removes
> > > filesystem specific build config option (e.g. CONFIG_EXT4_FS_ENCRYPTION)
> > > and replaces it with a build option (i.e. CONFIG_FS_ENCRYPTION) whose
> > > value affects all the filesystems making use of fscrypt.
> > >
> > > Signed-off-by: Chandan Rajendra <[email protected]>
> > [...]
> > > -config F2FS_FS_ENCRYPTION
> > > - bool "F2FS Encryption"
> > > - depends on F2FS_FS
> > > - depends on F2FS_FS_XATTR
> > > - select FS_ENCRYPTION
> > > - help
> > > - Enable encryption of f2fs files and directories. This
> > > - feature is similar to ecryptfs, but it is more memory
> > > - efficient since it avoids caching the encrypted and
> > > - decrypted pages in the page cache.
> > > -
> > [...]
> > > -config UBIFS_FS_ENCRYPTION
> > > - bool "UBIFS Encryption"
> > > - depends on UBIFS_FS && UBIFS_FS_XATTR && BLOCK
> > > - select FS_ENCRYPTION
> > > - default n
> > > - help
> > > - Enable encryption of UBIFS files and directories. This
> > > - feature is similar to ecryptfs, but it is more memory
> > > - efficient since it avoids caching the encrypted and
> > > - decrypted pages in the page cache.
> >
> > Will it cause problems that now f2fs encryption can be "enabled" without
> > F2FS_FS_XATTR, and ubifs encryption without UBIFS_FS_XATTR && BLOCK?
> >
> > Otherwise I think this patch looks fine. I'm a bit concerned about the bloat
> > from making FS_ENCRYPTION non-modular, but given that it will make sharing I/O
> > code much easier, it's probably worthwhile.
> >
> > It would help to strip down the dependencies of FS_ENCRYPTION to just the stuff
> > needed for just AES-256-XTS and AES-256-CTS. I already sent out a patch a
> > couple months ago (https://patchwork.kernel.org/patch/10589319/) to remove
> > CONFIG_CTR which isn't used at all; I'll remind Ted to apply that. But we could
> > also drop CONFIG_SHA256, which is only needed for AES-128-CBC contents
> > encryption. If we do that, it should be a separate patch, though.
>
> Hi Eric,
>
> fscrypt_valid_enc_modes() allows FS_ENCRYPTION_MODE_AES_128_CBC to be used for
> encryption of file's contents. This is consistent with what you had mentioned
> above.
>
> static inline bool fscrypt_valid_enc_modes(u32 contents_mode,
> u32 filenames_mode)
> {
> if (contents_mode == FS_ENCRYPTION_MODE_AES_128_CBC &&
> filenames_mode == FS_ENCRYPTION_MODE_AES_128_CTS)
> return true;
>
> if (contents_mode == FS_ENCRYPTION_MODE_AES_256_XTS &&
> filenames_mode == FS_ENCRYPTION_MODE_AES_256_CTS)
> return true;
>
> return false;
> }
>
> Hence FS_ENCRYPTION does need to have AES-128-CBC and by extension SHA256 code
> compiled in right?
>

No those algorithms don't have to be compiled in if userspace doesn't use the
(FS_ENCRYPTION_MODE_AES_128_CBC, FS_ENCRYPTION_MODE_AES_128_CTS) pair, because
the algorithms are allocated dynamically on-demand through the crypto API.

- Eric

2018-12-04 23:16:32

by Eric Biggers

[permalink] [raw]
Subject: Re: [PATCH V2 2/7] f2fs: use IS_ENCRYPTED() to check encryption status

On Tue, Dec 04, 2018 at 03:26:45PM +0530, Chandan Rajendra wrote:
> This commit removes the f2fs specific f2fs_encrypted_inode() and makes
> use of the generic IS_ENCRYPTED() macro to check for the encryption
> status of an inode.
>
> Acked-by: Chao Yu <[email protected]>
> Signed-off-by: Chandan Rajendra <[email protected]>

This commit message is incorrect because f2fs_encrypted_inode() isn't actually
removed by this patch. Did you mean to remove it? I think you can if you
change f2fs_encrypted_file() to:

static inline bool f2fs_encrypted_file(struct inode *inode)
{
return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode);
}

... and if you replace the other calls to f2fs_encrypted_inode() with
file_is_encrypt().

- Eric

> ---
> fs/f2fs/data.c | 4 ++--
> fs/f2fs/dir.c | 10 +++++-----
> fs/f2fs/file.c | 10 +++++-----
> fs/f2fs/namei.c | 6 +++---
> 4 files changed, 15 insertions(+), 15 deletions(-)
>
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index 09d9fc1676a7..844ec573263e 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -1491,7 +1491,7 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
> }
>
> if (size) {
> - if (f2fs_encrypted_inode(inode))
> + if (IS_ENCRYPTED(inode))
> flags |= FIEMAP_EXTENT_DATA_ENCRYPTED;
>
> ret = fiemap_fill_next_extent(fieinfo, logical,
> @@ -1764,7 +1764,7 @@ static inline bool check_inplace_update_policy(struct inode *inode,
> if (policy & (0x1 << F2FS_IPU_ASYNC) &&
> fio && fio->op == REQ_OP_WRITE &&
> !(fio->op_flags & REQ_SYNC) &&
> - !f2fs_encrypted_inode(inode))
> + !IS_ENCRYPTED(inode))
> return true;
>
> /* this is only set during fdatasync */
> diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
> index bacc667950b6..cf9e2564388d 100644
> --- a/fs/f2fs/dir.c
> +++ b/fs/f2fs/dir.c
> @@ -385,7 +385,7 @@ struct page *f2fs_init_inode_metadata(struct inode *inode, struct inode *dir,
> if (err)
> goto put_error;
>
> - if ((f2fs_encrypted_inode(dir) || dummy_encrypt) &&
> + if ((IS_ENCRYPTED(dir) || dummy_encrypt) &&
> f2fs_may_encrypt(inode)) {
> err = fscrypt_inherit_context(dir, inode, page, false);
> if (err)
> @@ -399,7 +399,7 @@ struct page *f2fs_init_inode_metadata(struct inode *inode, struct inode *dir,
>
> if (new_name) {
> init_dent_inode(new_name, page);
> - if (f2fs_encrypted_inode(dir))
> + if (IS_ENCRYPTED(dir))
> file_set_enc_name(inode);
> }
>
> @@ -808,7 +808,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
> de_name.name = d->filename[bit_pos];
> de_name.len = le16_to_cpu(de->name_len);
>
> - if (f2fs_encrypted_inode(d->inode)) {
> + if (IS_ENCRYPTED(d->inode)) {
> int save_len = fstr->len;
>
> err = fscrypt_fname_disk_to_usr(d->inode,
> @@ -852,7 +852,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
> struct fscrypt_str fstr = FSTR_INIT(NULL, 0);
> int err = 0;
>
> - if (f2fs_encrypted_inode(inode)) {
> + if (IS_ENCRYPTED(inode)) {
> err = fscrypt_get_encryption_info(inode);
> if (err && err != -ENOKEY)
> goto out;
> @@ -914,7 +914,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
>
> static int f2fs_dir_open(struct inode *inode, struct file *filp)
> {
> - if (f2fs_encrypted_inode(inode))
> + if (IS_ENCRYPTED(inode))
> return fscrypt_get_encryption_info(inode) ? -EACCES : 0;
> return 0;
> }
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> index 87794b2a45ff..6c7ad15000b9 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -585,7 +585,7 @@ static int truncate_partial_data_page(struct inode *inode, u64 from,
> zero_user(page, offset, PAGE_SIZE - offset);
>
> /* An encrypted inode should have a key and truncate the last page. */
> - f2fs_bug_on(F2FS_I_SB(inode), cache_only && f2fs_encrypted_inode(inode));
> + f2fs_bug_on(F2FS_I_SB(inode), cache_only && IS_ENCRYPTED(inode));
> if (!cache_only)
> set_page_dirty(page);
> f2fs_put_page(page, 1);
> @@ -730,7 +730,7 @@ int f2fs_getattr(const struct path *path, struct kstat *stat,
> stat->attributes |= STATX_ATTR_APPEND;
> if (flags & F2FS_COMPR_FL)
> stat->attributes |= STATX_ATTR_COMPRESSED;
> - if (f2fs_encrypted_inode(inode))
> + if (IS_ENCRYPTED(inode))
> stat->attributes |= STATX_ATTR_ENCRYPTED;
> if (flags & F2FS_IMMUTABLE_FL)
> stat->attributes |= STATX_ATTR_IMMUTABLE;
> @@ -1587,7 +1587,7 @@ static long f2fs_fallocate(struct file *file, int mode,
> if (!S_ISREG(inode->i_mode))
> return -EINVAL;
>
> - if (f2fs_encrypted_inode(inode) &&
> + if (IS_ENCRYPTED(inode) &&
> (mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE)))
> return -EOPNOTSUPP;
>
> @@ -1671,7 +1671,7 @@ static int f2fs_ioc_getflags(struct file *filp, unsigned long arg)
> struct f2fs_inode_info *fi = F2FS_I(inode);
> unsigned int flags = fi->i_flags;
>
> - if (f2fs_encrypted_inode(inode))
> + if (IS_ENCRYPTED(inode))
> flags |= F2FS_ENCRYPT_FL;
> if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode))
> flags |= F2FS_INLINE_DATA_FL;
> @@ -2430,7 +2430,7 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in,
> if (!S_ISREG(src->i_mode) || !S_ISREG(dst->i_mode))
> return -EINVAL;
>
> - if (f2fs_encrypted_inode(src) || f2fs_encrypted_inode(dst))
> + if (IS_ENCRYPTED(src) || IS_ENCRYPTED(dst))
> return -EOPNOTSUPP;
>
> if (src == dst) {
> diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
> index 99299ede7429..6ae37e0cf6e3 100644
> --- a/fs/f2fs/namei.c
> +++ b/fs/f2fs/namei.c
> @@ -75,7 +75,7 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
> set_inode_flag(inode, FI_NEW_INODE);
>
> /* If the directory encrypted, then we should encrypt the inode. */
> - if ((f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
> + if ((IS_ENCRYPTED(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
> f2fs_may_encrypt(inode))
> f2fs_set_encrypted_inode(inode);
>
> @@ -476,7 +476,7 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
> if (err)
> goto out_iput;
> }
> - if (f2fs_encrypted_inode(dir) &&
> + if (IS_ENCRYPTED(dir) &&
> (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
> !fscrypt_has_permitted_context(dir, inode)) {
> f2fs_msg(inode->i_sb, KERN_WARNING,
> @@ -803,7 +803,7 @@ static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
> if (unlikely(f2fs_cp_error(sbi)))
> return -EIO;
>
> - if (f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) {
> + if (IS_ENCRYPTED(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) {
> int err = fscrypt_get_encryption_info(dir);
> if (err)
> return err;
> --
> 2.19.1
>

2018-12-04 09:57:59

by Chandan Rajendra

[permalink] [raw]
Subject: [PATCH V2 7/7] fsverity: Remove filesystem specific build config option

In order to have a common code base for fsverity "post read" processing
for all filesystems which support fsverity, this commit removes
filesystem specific build config option (e.g. CONFIG_EXT4_FS_VERITY)
and replaces it with a build option (i.e. CONFIG_FS_VERITY) whose
value affects all the filesystems making use of fsverity.

Signed-off-by: Chandan Rajendra <[email protected]>
---
Documentation/filesystems/fsverity.rst | 4 ++--
fs/ext4/Kconfig | 20 --------------------
fs/ext4/ext4.h | 2 --
fs/ext4/readpage.c | 4 ++--
fs/ext4/super.c | 6 +++---
fs/ext4/sysfs.c | 4 ++--
fs/f2fs/Kconfig | 20 --------------------
fs/f2fs/data.c | 2 +-
fs/f2fs/f2fs.h | 2 --
fs/f2fs/super.c | 6 +++---
fs/f2fs/sysfs.c | 4 ++--
fs/verity/Kconfig | 3 ++-
include/linux/fs.h | 4 ++--
include/linux/fsverity.h | 3 +--
14 files changed, 20 insertions(+), 64 deletions(-)

diff --git a/Documentation/filesystems/fsverity.rst b/Documentation/filesystems/fsverity.rst
index d633fc0567bd..bb208dad10d9 100644
--- a/Documentation/filesystems/fsverity.rst
+++ b/Documentation/filesystems/fsverity.rst
@@ -279,7 +279,7 @@ ext4

ext4 supports fs-verity since kernel version TODO.

-CONFIG_EXT4_FS_VERITY must be enabled in the kernel config. Also, the
+CONFIG_FS_VERITY must be enabled in the kernel config. Also, the
filesystem must have been formatted with ``-O verity``, or had
``tune2fs -O verity`` run on it. These require e2fsprogs v1.44.4-2 or
later. This e2fsprogs version is also required for e2fsck to
@@ -306,7 +306,7 @@ f2fs

f2fs supports fs-verity since kernel version TODO.

-CONFIG_F2FS_FS_VERITY must be enabled in the kernel config. Also, the
+CONFIG_FS_VERITY must be enabled in the kernel config. Also, the
filesystem must have been formatted with ``-O verity``. This requires
f2fs-tools v1.11.0 or later.

diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index e1002bbf35bf..031e5a82d556 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -96,26 +96,6 @@ config EXT4_FS_SECURITY
If you are not using a security module that requires using
extended attributes for file security labels, say N.

-config EXT4_FS_VERITY
- bool "Ext4 Verity"
- depends on EXT4_FS
- select FS_VERITY
- help
- This option enables fs-verity for ext4. fs-verity is the
- dm-verity mechanism implemented at the file level. Userspace
- can append a Merkle tree (hash tree) to a file, then enable
- fs-verity on the file. ext4 will then transparently verify
- any data read from the file against the Merkle tree. The file
- is also made read-only.
-
- This serves as an integrity check, but the availability of the
- Merkle tree root hash also allows efficiently supporting
- various use cases where normally the whole file would need to
- be hashed at once, such as auditing and authenticity
- verification (appraisal).
-
- If unsure, say N.
-
config EXT4_DEBUG
bool "EXT4 debugging support"
depends on EXT4_FS
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 64bf9fb7ef18..bff8d639dd0c 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -41,8 +41,6 @@
#endif

#include <linux/fscrypt.h>
-
-#define __FS_HAS_VERITY IS_ENABLED(CONFIG_EXT4_FS_VERITY)
#include <linux/fsverity.h>

#include <linux/compiler.h>
diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
index 2c037df629dd..8717ac0a5bb2 100644
--- a/fs/ext4/readpage.c
+++ b/fs/ext4/readpage.c
@@ -158,7 +158,7 @@ static struct bio_post_read_ctx *get_bio_post_read_ctx(struct inode *inode,

if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode))
post_read_steps |= 1 << STEP_DECRYPT;
-#ifdef CONFIG_EXT4_FS_VERITY
+#ifdef CONFIG_FS_VERITY
if (inode->i_verity_info != NULL &&
(index < ((i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT)))
post_read_steps |= 1 << STEP_VERITY;
@@ -205,7 +205,7 @@ static void mpage_end_io(struct bio *bio)

static inline loff_t ext4_readpage_limit(struct inode *inode)
{
-#ifdef CONFIG_EXT4_FS_VERITY
+#ifdef CONFIG_FS_VERITY
if (IS_VERITY(inode)) {
if (inode->i_verity_info)
/* limit to end of metadata region */
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 35ed3c48f8d2..0d169de59f76 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1316,7 +1316,7 @@ static const struct fscrypt_operations ext4_cryptops = {
};
#endif

-#ifdef CONFIG_EXT4_FS_VERITY
+#ifdef CONFIG_FS_VERITY
static int ext4_set_verity(struct inode *inode, loff_t data_i_size)
{
int err;
@@ -1402,7 +1402,7 @@ static const struct fsverity_operations ext4_verityops = {
.set_verity = ext4_set_verity,
.get_metadata_end = ext4_get_metadata_end,
};
-#endif /* CONFIG_EXT4_FS_VERITY */
+#endif /* CONFIG_FS_VERITY */

#ifdef CONFIG_QUOTA
static const char * const quotatypes[] = INITQFNAMES;
@@ -4235,7 +4235,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
#ifdef CONFIG_FS_ENCRYPTION
sb->s_cop = &ext4_cryptops;
#endif
-#ifdef CONFIG_EXT4_FS_VERITY
+#ifdef CONFIG_FS_VERITY
sb->s_vop = &ext4_verityops;
#endif
#ifdef CONFIG_QUOTA
diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
index 8bc915452a38..6fa0f47c3180 100644
--- a/fs/ext4/sysfs.c
+++ b/fs/ext4/sysfs.c
@@ -227,7 +227,7 @@ EXT4_ATTR_FEATURE(meta_bg_resize);
#ifdef CONFIG_FS_ENCRYPTION
EXT4_ATTR_FEATURE(encryption);
#endif
-#ifdef CONFIG_EXT4_FS_VERITY
+#ifdef CONFIG_FS_VERITY
EXT4_ATTR_FEATURE(verity);
#endif
EXT4_ATTR_FEATURE(metadata_csum_seed);
@@ -239,7 +239,7 @@ static struct attribute *ext4_feat_attrs[] = {
#ifdef CONFIG_FS_ENCRYPTION
ATTR_LIST(encryption),
#endif
-#ifdef CONFIG_EXT4_FS_VERITY
+#ifdef CONFIG_FS_VERITY
ATTR_LIST(verity),
#endif
ATTR_LIST(metadata_csum_seed),
diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig
index ce60e480fec1..708e23816575 100644
--- a/fs/f2fs/Kconfig
+++ b/fs/f2fs/Kconfig
@@ -70,26 +70,6 @@ config F2FS_CHECK_FS

If you want to improve the performance, say N.

-config F2FS_FS_VERITY
- bool "F2FS Verity"
- depends on F2FS_FS
- select FS_VERITY
- help
- This option enables fs-verity for f2fs. fs-verity is the
- dm-verity mechanism implemented at the file level. Userspace
- can append a Merkle tree (hash tree) to a file, then enable
- fs-verity on the file. f2fs will then transparently verify
- any data read from the file against the Merkle tree. The file
- is also made read-only.
-
- This serves as an integrity check, but the availability of the
- Merkle tree root hash also allows efficiently supporting
- various use cases where normally the whole file would need to
- be hashed at once, such as auditing and authenticity
- verification (appraisal).
-
- If unsure, say N.
-
config F2FS_IO_TRACE
bool "F2FS IO tracer"
depends on F2FS_FS
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 844ec573263e..83b59b985894 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -610,7 +610,7 @@ static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr,

if (f2fs_encrypted_file(inode))
post_read_steps |= 1 << STEP_DECRYPT;
-#ifdef CONFIG_F2FS_FS_VERITY
+#ifdef CONFIG_FS_VERITY
if (inode->i_verity_info != NULL &&
(first_idx < ((i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT)))
post_read_steps |= 1 << STEP_VERITY;
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ea8a5ffc4f1f..dc999af932f2 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -25,8 +25,6 @@
#include <crypto/hash.h>

#include <linux/fscrypt.h>
-
-#define __FS_HAS_VERITY IS_ENABLED(CONFIG_F2FS_FS_VERITY)
#include <linux/fsverity.h>

#ifdef CONFIG_F2FS_CHECK_FS
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 4287cf348d3c..60d5338280fb 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2197,7 +2197,7 @@ static const struct fscrypt_operations f2fs_cryptops = {
};
#endif

-#ifdef CONFIG_F2FS_FS_VERITY
+#ifdef CONFIG_FS_VERITY
static int f2fs_set_verity(struct inode *inode, loff_t data_i_size)
{
int err;
@@ -2222,7 +2222,7 @@ static const struct fsverity_operations f2fs_verityops = {
.set_verity = f2fs_set_verity,
.get_metadata_end = f2fs_get_metadata_end,
};
-#endif /* CONFIG_F2FS_FS_VERITY */
+#endif /* CONFIG_FS_VERITY */

static struct inode *f2fs_nfs_get_inode(struct super_block *sb,
u64 ino, u32 generation)
@@ -3146,7 +3146,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
#ifdef CONFIG_FS_ENCRYPTION
sb->s_cop = &f2fs_cryptops;
#endif
-#ifdef CONFIG_F2FS_FS_VERITY
+#ifdef CONFIG_FS_VERITY
sb->s_vop = &f2fs_verityops;
#endif
sb->s_xattr = f2fs_xattr_handlers;
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 737677655bc0..949e6d87f4e3 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -444,7 +444,7 @@ F2FS_FEATURE_RO_ATTR(flexible_inline_xattr, FEAT_FLEXIBLE_INLINE_XATTR);
F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO);
F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME);
F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND);
-#ifdef CONFIG_F2FS_FS_VERITY
+#ifdef CONFIG_FS_VERITY
F2FS_FEATURE_RO_ATTR(verity, FEAT_VERITY);
#endif
F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM);
@@ -507,7 +507,7 @@ static struct attribute *f2fs_feat_attrs[] = {
ATTR_LIST(quota_ino),
ATTR_LIST(inode_crtime),
ATTR_LIST(lost_found),
-#ifdef CONFIG_F2FS_FS_VERITY
+#ifdef CONFIG_FS_VERITY
ATTR_LIST(verity),
#endif
ATTR_LIST(sb_checksum),
diff --git a/fs/verity/Kconfig b/fs/verity/Kconfig
index a7470a2e4892..6d9437a432cd 100644
--- a/fs/verity/Kconfig
+++ b/fs/verity/Kconfig
@@ -1,5 +1,5 @@
config FS_VERITY
- tristate "FS Verity (read-only file-based authenticity protection)"
+ bool "FS Verity (read-only file-based authenticity protection)"
select CRYPTO
# SHA-256 is selected as it's intended to be the default hash algorithm.
# To avoid bloat, other wanted algorithms must be selected explicitly.
@@ -23,6 +23,7 @@ config FS_VERITY
the contents may actually be needed. Also, fs-verity verifies
data each time it is paged back in, which provides better
protection against malicious disks vs. an ahead-of-time hash.
+ Currently Ext4 and F2FS make use of this feature.

If unsure, say N.

diff --git a/include/linux/fs.h b/include/linux/fs.h
index de602d9f8d0e..1583b861a225 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -704,7 +704,7 @@ struct inode {
struct fscrypt_info *i_crypt_info;
#endif

-#if IS_ENABLED(CONFIG_FS_VERITY)
+#ifdef CONFIG_FS_VERITY
struct fsverity_info *i_verity_info;
#endif

@@ -1407,7 +1407,7 @@ struct super_block {
#ifdef CONFIG_FS_ENCRYPTION
const struct fscrypt_operations *s_cop;
#endif
-#if IS_ENABLED(CONFIG_FS_VERITY)
+#ifdef CONFIG_FS_VERITY
const struct fsverity_operations *s_vop;
#endif
struct hlist_bl_head s_roots; /* alternate root dentries for NFS */
diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h
index c30c4f6ed411..f37132c640ee 100644
--- a/include/linux/fsverity.h
+++ b/include/linux/fsverity.h
@@ -19,8 +19,7 @@ struct fsverity_operations {
int (*get_metadata_end)(struct inode *inode, loff_t *metadata_end_ret);
};

-#if __FS_HAS_VERITY
-
+#ifdef CONFIG_FS_VERITY
/* ioctl.c */
extern int fsverity_ioctl_enable(struct file *filp, const void __user *arg);
extern int fsverity_ioctl_measure(struct file *filp, void __user *arg);
--
2.19.1

2018-12-04 09:57:44

by Chandan Rajendra

[permalink] [raw]
Subject: [PATCH V2 5/7] ext4: use IS_VERITY() to check inode's fsverity status

This commit now uses IS_VERITY() macro to check if fsverity is
enabled on an inode.

Signed-off-by: Chandan Rajendra <[email protected]>
---
fs/ext4/ext4.h | 9 ---------
fs/ext4/file.c | 2 +-
fs/ext4/inode.c | 10 ++++++----
fs/ext4/readpage.c | 2 +-
fs/ext4/super.c | 1 +
5 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index db21df885186..64bf9fb7ef18 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2296,15 +2296,6 @@ extern unsigned ext4_free_clusters_after_init(struct super_block *sb,
struct ext4_group_desc *gdp);
ext4_fsblk_t ext4_inode_to_goal_block(struct inode *);

-static inline bool ext4_verity_inode(struct inode *inode)
-{
-#ifdef CONFIG_EXT4_FS_VERITY
- return ext4_test_inode_flag(inode, EXT4_INODE_VERITY);
-#else
- return false;
-#endif
-}
-
#ifdef CONFIG_FS_ENCRYPTION
static inline int ext4_fname_setup_filename(struct inode *dir,
const struct qstr *iname,
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index cb4b69ef01a2..30fbd663354f 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -444,7 +444,7 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
if (ret)
return ret;

- if (ext4_verity_inode(inode)) {
+ if (IS_VERITY(inode)) {
ret = fsverity_file_open(inode, filp);
if (ret)
return ret;
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 09d8857b0e3c..79d14d8bbbf4 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -3884,7 +3884,7 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
return 0;
#endif

- if (ext4_verity_inode(inode))
+ if (IS_VERITY(inode))
return 0;

/*
@@ -4726,7 +4726,7 @@ static bool ext4_should_use_dax(struct inode *inode)
return false;
if (ext4_test_inode_flag(inode, EXT4_INODE_ENCRYPT))
return false;
- if (ext4_verity_inode(inode))
+ if (ext4_test_inode_flag(inode, EXT4_INODE_VERITY))
return false;
return true;
}
@@ -4750,9 +4750,11 @@ void ext4_set_inode_flags(struct inode *inode)
new_fl |= S_DAX;
if (flags & EXT4_ENCRYPT_FL)
new_fl |= S_ENCRYPTED;
+ if (flags & EXT4_VERITY_FL)
+ new_fl |= S_VERITY;
inode_set_flags(inode, new_fl,
S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX|
- S_ENCRYPTED);
+ S_ENCRYPTED|S_VERITY);
}

static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode,
@@ -5510,7 +5512,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
if (error)
return error;

- if (ext4_verity_inode(inode)) {
+ if (IS_VERITY(inode)) {
error = fsverity_prepare_setattr(dentry, attr);
if (error)
return error;
diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
index 7252f0a60cdb..2c037df629dd 100644
--- a/fs/ext4/readpage.c
+++ b/fs/ext4/readpage.c
@@ -206,7 +206,7 @@ static void mpage_end_io(struct bio *bio)
static inline loff_t ext4_readpage_limit(struct inode *inode)
{
#ifdef CONFIG_EXT4_FS_VERITY
- if (ext4_verity_inode(inode)) {
+ if (IS_VERITY(inode)) {
if (inode->i_verity_info)
/* limit to end of metadata region */
return fsverity_full_i_size(inode);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 16fb483a6f4a..35ed3c48f8d2 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1344,6 +1344,7 @@ static int ext4_set_verity(struct inode *inode, loff_t data_i_size)
err = ext4_reserve_inode_write(handle, inode, &iloc);
if (err == 0) {
ext4_set_inode_flag(inode, EXT4_INODE_VERITY);
+ ext4_set_inode_flags(inode);
EXT4_I(inode)->i_disksize = data_i_size;
err = ext4_mark_iloc_dirty(handle, inode, &iloc);
}
--
2.19.1

2018-12-05 00:05:31

by Eric Biggers

[permalink] [raw]
Subject: Re: [PATCH V2 3/7] fscrypt: remove filesystem specific build config option

On Tue, Dec 04, 2018 at 03:26:46PM +0530, Chandan Rajendra wrote:
> diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
> index 952ab97af325..6ba193c23f37 100644
> --- a/include/linux/fscrypt.h
> +++ b/include/linux/fscrypt.h
> @@ -2,9 +2,8 @@
> /*
> * fscrypt.h: declarations for per-file encryption
> *
> - * Filesystems that implement per-file encryption include this header
> - * file with the __FS_HAS_ENCRYPTION set according to whether that filesystem
> - * is being built with encryption support or not.
> + * Filesystems that implement per-file encryption must include this header
> + * file.
> *
> * Copyright (C) 2015, Google, Inc.
> *

There's still a definition of __FS_HAS_ENCRYPTION in
fs/crypto/fscrypt_private.h. This patch removes everything that checks
__FS_HAS_ENCRYPTION, so that should be removed too.

Thanks,

- Eric

2018-12-04 09:57:37

by Chandan Rajendra

[permalink] [raw]
Subject: [PATCH V2 3/7] fscrypt: remove filesystem specific build config option

In order to have a common code base for fscrypt "post read" processing
for all filesystems which support encryption, this commit removes
filesystem specific build config option (e.g. CONFIG_EXT4_FS_ENCRYPTION)
and replaces it with a build option (i.e. CONFIG_FS_ENCRYPTION) whose
value affects all the filesystems making use of fscrypt.

Signed-off-by: Chandan Rajendra <[email protected]>
---
Documentation/filesystems/fscrypt.rst | 4 +-
arch/mips/configs/generic_defconfig | 2 +-
arch/nds32/configs/defconfig | 2 +-
arch/s390/configs/debug_defconfig | 2 +-
arch/s390/configs/performance_defconfig | 2 +-
fs/crypto/Kconfig | 5 +-
fs/ext4/Kconfig | 15 -
fs/ext4/dir.c | 2 -
fs/ext4/ext4.h | 7 +-
fs/ext4/inode.c | 8 +-
fs/ext4/ioctl.c | 4 +-
fs/ext4/namei.c | 10 +-
fs/ext4/page-io.c | 6 +-
fs/ext4/readpage.c | 2 +-
fs/ext4/super.c | 6 +-
fs/ext4/sysfs.c | 4 +-
fs/f2fs/Kconfig | 11 -
fs/f2fs/f2fs.h | 7 +-
fs/f2fs/super.c | 8 +-
fs/f2fs/sysfs.c | 4 +-
fs/ubifs/Kconfig | 11 -
fs/ubifs/Makefile | 2 +-
fs/ubifs/ioctl.c | 4 +-
fs/ubifs/sb.c | 2 +-
fs/ubifs/super.c | 2 +-
fs/ubifs/ubifs.h | 5 +-
include/linux/fs.h | 4 +-
include/linux/fscrypt.h | 416 +++++++++++++++++++++++-
include/linux/fscrypt_notsupp.h | 231 -------------
include/linux/fscrypt_supp.h | 204 ------------
30 files changed, 458 insertions(+), 534 deletions(-)
delete mode 100644 include/linux/fscrypt_notsupp.h
delete mode 100644 include/linux/fscrypt_supp.h

diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst
index cfbc18f0d9c9..92084762ad20 100644
--- a/Documentation/filesystems/fscrypt.rst
+++ b/Documentation/filesystems/fscrypt.rst
@@ -318,9 +318,9 @@ FS_IOC_SET_ENCRYPTION_POLICY can fail with the following errors:
- ``ENOTEMPTY``: the file is unencrypted and is a nonempty directory
- ``ENOTTY``: this type of filesystem does not implement encryption
- ``EOPNOTSUPP``: the kernel was not configured with encryption
- support for this filesystem, or the filesystem superblock has not
+ support for filesystems, or the filesystem superblock has not
had encryption enabled on it. (For example, to use encryption on an
- ext4 filesystem, CONFIG_EXT4_ENCRYPTION must be enabled in the
+ ext4 filesystem, CONFIG_FS_ENCRYPTION must be enabled in the
kernel config, and the superblock must have had the "encrypt"
feature flag enabled using ``tune2fs -O encrypt`` or ``mkfs.ext4 -O
encrypt``.)
diff --git a/arch/mips/configs/generic_defconfig b/arch/mips/configs/generic_defconfig
index 684c9dcba126..b8a21b9b934a 100644
--- a/arch/mips/configs/generic_defconfig
+++ b/arch/mips/configs/generic_defconfig
@@ -63,7 +63,7 @@ CONFIG_HID_MONTEREY=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
-CONFIG_EXT4_ENCRYPTION=y
+CONFIG_FS_ENCRYPTION=y
CONFIG_FANOTIFY=y
CONFIG_FUSE_FS=y
CONFIG_CUSE=y
diff --git a/arch/nds32/configs/defconfig b/arch/nds32/configs/defconfig
index 2546d8770785..65ce9259081b 100644
--- a/arch/nds32/configs/defconfig
+++ b/arch/nds32/configs/defconfig
@@ -74,7 +74,7 @@ CONFIG_GENERIC_PHY=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
-CONFIG_EXT4_ENCRYPTION=y
+CONFIG_FS_ENCRYPTION=y
CONFIG_FUSE_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index 259d1698ac50..e8868e0fba76 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -492,7 +492,6 @@ CONFIG_VIRTIO_INPUT=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
-CONFIG_EXT4_ENCRYPTION=y
CONFIG_JBD2_DEBUG=y
CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y
@@ -512,6 +511,7 @@ CONFIG_BTRFS_DEBUG=y
CONFIG_NILFS2_FS=m
CONFIG_FS_DAX=y
CONFIG_EXPORTFS_BLOCK_OPS=y
+CONFIG_FS_ENCRYPTION=y
CONFIG_FANOTIFY=y
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
diff --git a/arch/s390/configs/performance_defconfig b/arch/s390/configs/performance_defconfig
index 37fd60c20e22..ef1dd74b29f5 100644
--- a/arch/s390/configs/performance_defconfig
+++ b/arch/s390/configs/performance_defconfig
@@ -489,7 +489,6 @@ CONFIG_VIRTIO_INPUT=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
-CONFIG_EXT4_ENCRYPTION=y
CONFIG_JBD2_DEBUG=y
CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y
@@ -507,6 +506,7 @@ CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_NILFS2_FS=m
CONFIG_FS_DAX=y
CONFIG_EXPORTFS_BLOCK_OPS=y
+CONFIG_FS_ENCRYPTION=y
CONFIG_FANOTIFY=y
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
CONFIG_QUOTA_NETLINK_INTERFACE=y
diff --git a/fs/crypto/Kconfig b/fs/crypto/Kconfig
index 02b7d91c9231..9a639da0464f 100644
--- a/fs/crypto/Kconfig
+++ b/fs/crypto/Kconfig
@@ -1,5 +1,5 @@
config FS_ENCRYPTION
- tristate "FS Encryption (Per-file encryption)"
+ bool "FS Encryption (Per-file encryption)"
select CRYPTO
select CRYPTO_AES
select CRYPTO_CBC
@@ -13,4 +13,5 @@ config FS_ENCRYPTION
Enable encryption of files and directories. This
feature is similar to ecryptfs, but it is more memory
efficient since it avoids caching the encrypted and
- decrypted pages in the page cache.
+ decrypted pages in the page cache. Currently Ext4,
+ F2FS and UBIFS make use of this feature.
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
index 5a76125ac0f8..e1002bbf35bf 100644
--- a/fs/ext4/Kconfig
+++ b/fs/ext4/Kconfig
@@ -96,21 +96,6 @@ config EXT4_FS_SECURITY
If you are not using a security module that requires using
extended attributes for file security labels, say N.

-config EXT4_ENCRYPTION
- bool "Ext4 Encryption"
- depends on EXT4_FS
- select FS_ENCRYPTION
- help
- Enable encryption of ext4 files and directories. This
- feature is similar to ecryptfs, but it is more memory
- efficient since it avoids caching the encrypted and
- decrypted pages in the page cache.
-
-config EXT4_FS_ENCRYPTION
- bool
- default y
- depends on EXT4_ENCRYPTION
-
config EXT4_FS_VERITY
bool "Ext4 Verity"
depends on EXT4_FS
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index fb7a64ea5679..0ccd51f72048 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -283,9 +283,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
done:
err = 0;
errout:
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
fscrypt_fname_free_buffer(&fstr);
-#endif
brelse(bh);
return err;
}
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 2ae6ab88f218..db21df885186 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -40,7 +40,6 @@
#include <linux/compat.h>
#endif

-#define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_EXT4_FS_ENCRYPTION)
#include <linux/fscrypt.h>

#define __FS_HAS_VERITY IS_ENABLED(CONFIG_EXT4_FS_VERITY)
@@ -1341,7 +1340,7 @@ struct ext4_super_block {
#define EXT4_MF_FS_ABORTED 0x0002 /* Fatal error detected */
#define EXT4_MF_TEST_DUMMY_ENCRYPTION 0x0004

-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
#define DUMMY_ENCRYPTION_ENABLED(sbi) (unlikely((sbi)->s_mount_flags & \
EXT4_MF_TEST_DUMMY_ENCRYPTION))
#else
@@ -2069,7 +2068,7 @@ struct ext4_filename {
const struct qstr *usr_fname;
struct fscrypt_str disk_name;
struct dx_hash_info hinfo;
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
struct fscrypt_str crypto_buf;
#endif
};
@@ -2306,7 +2305,7 @@ static inline bool ext4_verity_inode(struct inode *inode)
#endif
}

-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
static inline int ext4_fname_setup_filename(struct inode *dir,
const struct qstr *iname,
int lookup, struct ext4_filename *fname)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index ef835bd46155..09d8857b0e3c 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1150,7 +1150,7 @@ int do_journal_get_write_access(handle_t *handle,
return ret;
}

-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len,
get_block_t *get_block)
{
@@ -1303,7 +1303,7 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping,
/* In case writeback began while the page was unlocked */
wait_for_stable_page(page);

-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
if (ext4_should_dioread_nolock(inode))
ret = ext4_block_write_begin(page, pos, len,
ext4_get_block_unwritten);
@@ -3104,7 +3104,7 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
/* In case writeback began while the page was unlocked */
wait_for_stable_page(page);

-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
ret = ext4_block_write_begin(page, pos, len,
ext4_da_get_block_prep);
#else
@@ -3879,7 +3879,7 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
loff_t offset = iocb->ki_pos;
ssize_t ret;

-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode))
return 0;
#endif
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 9bb6cc1ae8ce..892fb1925836 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -210,7 +210,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
return err;
}

-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
static int uuid_is_zero(__u8 u[16])
{
int i;
@@ -978,7 +978,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return fscrypt_ioctl_set_policy(filp, (const void __user *)arg);

case EXT4_IOC_GET_ENCRYPTION_PWSALT: {
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
int err, err2;
struct ext4_sb_info *sbi = EXT4_SB(sb);
handle_t *handle;
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 0de60207a963..1e1a3c8c3a8b 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -611,7 +611,7 @@ static struct stats dx_show_leaf(struct inode *dir,
{
if (show_names)
{
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
int len;
char *name;
struct fscrypt_str fname_crypto_str =
@@ -983,7 +983,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
top = (struct ext4_dir_entry_2 *) ((char *) de +
dir->i_sb->s_blocksize -
EXT4_DIR_REC_LEN(0));
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
/* Check if the directory is encrypted */
if (IS_ENCRYPTED(dir)) {
err = fscrypt_get_encryption_info(dir);
@@ -1046,7 +1046,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
}
errout:
brelse(bh);
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
fscrypt_fname_free_buffer(&fname_crypto_str);
#endif
return count;
@@ -1266,7 +1266,7 @@ static inline bool ext4_match(const struct ext4_filename *fname,

f.usr_fname = fname->usr_fname;
f.disk_name = fname->disk_name;
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
f.crypto_buf = fname->crypto_buf;
#endif
return fscrypt_match_name(&f, de->name, de->name_len);
@@ -1497,7 +1497,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir,
ext4_lblk_t block;
int retval;

-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
*res_dir = NULL;
#endif
frame = dx_probe(fname, dir, NULL, frames);
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 008c20b58f98..7d5f12be07ab 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -66,7 +66,7 @@ static void ext4_finish_bio(struct bio *bio)

bio_for_each_segment_all(bvec, bio, i) {
struct page *page = bvec->bv_page;
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
struct page *data_page = NULL;
#endif
struct buffer_head *bh, *head;
@@ -78,7 +78,7 @@ static void ext4_finish_bio(struct bio *bio)
if (!page)
continue;

-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
if (!page->mapping) {
/* The bounce data pages are unmapped. */
data_page = page;
@@ -111,7 +111,7 @@ static void ext4_finish_bio(struct bio *bio)
bit_spin_unlock(BH_Uptodate_Lock, &head->b_state);
local_irq_restore(flags);
if (!under_io) {
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
if (data_page)
fscrypt_restore_control_page(data_page);
#endif
diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
index 45e707fb9749..7252f0a60cdb 100644
--- a/fs/ext4/readpage.c
+++ b/fs/ext4/readpage.c
@@ -54,7 +54,7 @@ static mempool_t *bio_post_read_ctx_pool;

static inline bool ext4_bio_encrypted(struct bio *bio)
{
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
return unlikely(bio->bi_private != NULL);
#else
return false;
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index fb4e060f28ec..16fb483a6f4a 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1210,7 +1210,7 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page,
return try_to_free_buffers(page);
}

-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
static int ext4_get_context(struct inode *inode, void *ctx, size_t len)
{
return ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION,
@@ -1986,7 +1986,7 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
*journal_ioprio =
IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, arg);
} else if (token == Opt_test_dummy_encryption) {
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
sbi->s_mount_flags |= EXT4_MF_TEST_DUMMY_ENCRYPTION;
ext4_msg(sb, KERN_WARNING,
"Test dummy encryption mode enabled");
@@ -4231,7 +4231,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
sb->s_op = &ext4_sops;
sb->s_export_op = &ext4_export_ops;
sb->s_xattr = ext4_xattr_handlers;
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
sb->s_cop = &ext4_cryptops;
#endif
#ifdef CONFIG_EXT4_FS_VERITY
diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
index 8e86087c2f03..8bc915452a38 100644
--- a/fs/ext4/sysfs.c
+++ b/fs/ext4/sysfs.c
@@ -224,7 +224,7 @@ static struct attribute *ext4_attrs[] = {
EXT4_ATTR_FEATURE(lazy_itable_init);
EXT4_ATTR_FEATURE(batched_discard);
EXT4_ATTR_FEATURE(meta_bg_resize);
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
EXT4_ATTR_FEATURE(encryption);
#endif
#ifdef CONFIG_EXT4_FS_VERITY
@@ -236,7 +236,7 @@ static struct attribute *ext4_feat_attrs[] = {
ATTR_LIST(lazy_itable_init),
ATTR_LIST(batched_discard),
ATTR_LIST(meta_bg_resize),
-#ifdef CONFIG_EXT4_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
ATTR_LIST(encryption),
#endif
#ifdef CONFIG_EXT4_FS_VERITY
diff --git a/fs/f2fs/Kconfig b/fs/f2fs/Kconfig
index c8396c7220f2..ce60e480fec1 100644
--- a/fs/f2fs/Kconfig
+++ b/fs/f2fs/Kconfig
@@ -70,17 +70,6 @@ config F2FS_CHECK_FS

If you want to improve the performance, say N.

-config F2FS_FS_ENCRYPTION
- bool "F2FS Encryption"
- depends on F2FS_FS
- depends on F2FS_FS_XATTR
- select FS_ENCRYPTION
- help
- Enable encryption of f2fs files and directories. This
- feature is similar to ecryptfs, but it is more memory
- efficient since it avoids caching the encrypted and
- decrypted pages in the page cache.
-
config F2FS_FS_VERITY
bool "F2FS Verity"
depends on F2FS_FS
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index dadb5f468f20..ea8a5ffc4f1f 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -24,7 +24,6 @@
#include <linux/quotaops.h>
#include <crypto/hash.h>

-#define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_F2FS_FS_ENCRYPTION)
#include <linux/fscrypt.h>

#define __FS_HAS_VERITY IS_ENABLED(CONFIG_F2FS_FS_VERITY)
@@ -1145,7 +1144,7 @@ enum fsync_mode {
FSYNC_MODE_NOBARRIER, /* fsync behaves nobarrier based on posix */
};

-#ifdef CONFIG_F2FS_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
#define DUMMY_ENCRYPTION_ENABLED(sbi) \
(unlikely(F2FS_OPTION(sbi).test_dummy_encryption))
#else
@@ -3448,7 +3447,7 @@ static inline bool f2fs_encrypted_file(struct inode *inode)

static inline void f2fs_set_encrypted_inode(struct inode *inode)
{
-#ifdef CONFIG_F2FS_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
file_set_encrypt(inode);
f2fs_set_inode_flags(inode);
#endif
@@ -3533,7 +3532,7 @@ static inline void set_opt_mode(struct f2fs_sb_info *sbi, unsigned int mt)

static inline bool f2fs_may_encrypt(struct inode *inode)
{
-#ifdef CONFIG_F2FS_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
umode_t mode = inode->i_mode;

return (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode));
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index adf38c1b6414..4287cf348d3c 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -757,7 +757,7 @@ static int parse_options(struct super_block *sb, char *options)
kfree(name);
break;
case Opt_test_dummy_encryption:
-#ifdef CONFIG_F2FS_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
if (!f2fs_sb_has_encrypt(sb)) {
f2fs_msg(sb, KERN_ERR, "Encrypt feature is off");
return -EINVAL;
@@ -1387,7 +1387,7 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
seq_printf(seq, ",whint_mode=%s", "user-based");
else if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_FS)
seq_printf(seq, ",whint_mode=%s", "fs-based");
-#ifdef CONFIG_F2FS_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
if (F2FS_OPTION(sbi).test_dummy_encryption)
seq_puts(seq, ",test_dummy_encryption");
#endif
@@ -2154,7 +2154,7 @@ static const struct super_operations f2fs_sops = {
.remount_fs = f2fs_remount,
};

-#ifdef CONFIG_F2FS_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
static int f2fs_get_context(struct inode *inode, void *ctx, size_t len)
{
return f2fs_getxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION,
@@ -3143,7 +3143,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
#endif

sb->s_op = &f2fs_sops;
-#ifdef CONFIG_F2FS_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
sb->s_cop = &f2fs_cryptops;
#endif
#ifdef CONFIG_F2FS_FS_VERITY
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 5599c9ac4426..737677655bc0 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -430,7 +430,7 @@ F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes);
F2FS_GENERAL_RO_ATTR(features);
F2FS_GENERAL_RO_ATTR(current_reserved_blocks);

-#ifdef CONFIG_F2FS_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO);
#endif
#ifdef CONFIG_BLK_DEV_ZONED
@@ -493,7 +493,7 @@ static struct attribute *f2fs_attrs[] = {
};

static struct attribute *f2fs_feat_attrs[] = {
-#ifdef CONFIG_F2FS_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
ATTR_LIST(encryption),
#endif
#ifdef CONFIG_BLK_DEV_ZONED
diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig
index bbc78549be4c..87ec3c28e61f 100644
--- a/fs/ubifs/Kconfig
+++ b/fs/ubifs/Kconfig
@@ -62,17 +62,6 @@ config UBIFS_FS_XATTR

If unsure, say Y.

-config UBIFS_FS_ENCRYPTION
- bool "UBIFS Encryption"
- depends on UBIFS_FS && UBIFS_FS_XATTR && BLOCK
- select FS_ENCRYPTION
- default n
- help
- Enable encryption of UBIFS files and directories. This
- feature is similar to ecryptfs, but it is more memory
- efficient since it avoids caching the encrypted and
- decrypted pages in the page cache.
-
config UBIFS_FS_SECURITY
bool "UBIFS Security Labels"
depends on UBIFS_FS && UBIFS_FS_XATTR
diff --git a/fs/ubifs/Makefile b/fs/ubifs/Makefile
index 6197d7e539e4..079b13fb88a2 100644
--- a/fs/ubifs/Makefile
+++ b/fs/ubifs/Makefile
@@ -6,5 +6,5 @@ ubifs-y += tnc.o master.o scan.o replay.o log.o commit.o gc.o orphan.o
ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o
ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o debug.o
ubifs-y += misc.o
-ubifs-$(CONFIG_UBIFS_FS_ENCRYPTION) += crypto.o
+ubifs-$(CONFIG_FS_ENCRYPTION) += crypto.o
ubifs-$(CONFIG_UBIFS_FS_XATTR) += xattr.o
diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c
index 0164bcc827f8..0f9c362a3402 100644
--- a/fs/ubifs/ioctl.c
+++ b/fs/ubifs/ioctl.c
@@ -185,7 +185,7 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return err;
}
case FS_IOC_SET_ENCRYPTION_POLICY: {
-#ifdef CONFIG_UBIFS_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
struct ubifs_info *c = inode->i_sb->s_fs_info;

err = ubifs_enable_encryption(c);
@@ -198,7 +198,7 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
#endif
}
case FS_IOC_GET_ENCRYPTION_POLICY: {
-#ifdef CONFIG_UBIFS_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
return fscrypt_ioctl_get_policy(file, (void __user *)arg);
#else
return -EOPNOTSUPP;
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c
index bf17f58908ff..3dffa595a60f 100644
--- a/fs/ubifs/sb.c
+++ b/fs/ubifs/sb.c
@@ -647,7 +647,7 @@ int ubifs_read_superblock(struct ubifs_info *c)
goto out;
}

-#ifndef CONFIG_UBIFS_FS_ENCRYPTION
+#ifndef CONFIG_FS_ENCRYPTION
if (c->encrypted) {
ubifs_err(c, "file system contains encrypted files but UBIFS"
" was built without crypto support.");
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index fec62e9dfbe6..7c98ccca2c41 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2087,7 +2087,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
#ifdef CONFIG_UBIFS_FS_XATTR
sb->s_xattr = ubifs_xattr_handlers;
#endif
-#ifdef CONFIG_UBIFS_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
sb->s_cop = &ubifs_crypt_operations;
#endif

diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 4368cde476b0..4d46bb83b964 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -40,7 +40,6 @@
#include <linux/xattr.h>
#include <linux/random.h>

-#define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_UBIFS_FS_ENCRYPTION)
#include <linux/fscrypt.h>

#include "ubifs-media.h"
@@ -139,7 +138,7 @@
*/
#define WORST_COMPR_FACTOR 2

-#ifdef CONFIG_UBIFS_FS_ENCRYPTION
+#ifdef CONFIG_FS_ENCRYPTION
#define UBIFS_CIPHER_BLOCK_SIZE FS_CRYPTO_BLOCK_SIZE
#else
#define UBIFS_CIPHER_BLOCK_SIZE 0
@@ -1829,7 +1828,7 @@ int ubifs_decompress(const struct ubifs_info *c, const void *buf, int len,
#include "misc.h"
#include "key.h"

-#ifndef CONFIG_UBIFS_FS_ENCRYPTION
+#ifndef CONFIG_FS_ENCRYPTION
static inline int ubifs_encrypt(const struct inode *inode,
struct ubifs_data_node *dn,
unsigned int in_len, unsigned int *out_len,
diff --git a/include/linux/fs.h b/include/linux/fs.h
index bcfc40062757..389a35e028bf 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -700,7 +700,7 @@ struct inode {
struct fsnotify_mark_connector __rcu *i_fsnotify_marks;
#endif

-#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
+#ifdef CONFIG_FS_ENCRYPTION
struct fscrypt_info *i_crypt_info;
#endif

@@ -1404,7 +1404,7 @@ struct super_block {
void *s_security;
#endif
const struct xattr_handler **s_xattr;
-#if IS_ENABLED(CONFIG_FS_ENCRYPTION)
+#ifdef CONFIG_FS_ENCRYPTION
const struct fscrypt_operations *s_cop;
#endif
#if IS_ENABLED(CONFIG_FS_VERITY)
diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
index 952ab97af325..6ba193c23f37 100644
--- a/include/linux/fscrypt.h
+++ b/include/linux/fscrypt.h
@@ -2,9 +2,8 @@
/*
* fscrypt.h: declarations for per-file encryption
*
- * Filesystems that implement per-file encryption include this header
- * file with the __FS_HAS_ENCRYPTION set according to whether that filesystem
- * is being built with encryption support or not.
+ * Filesystems that implement per-file encryption must include this header
+ * file.
*
* Copyright (C) 2015, Google, Inc.
*
@@ -15,6 +14,8 @@
#define _LINUX_FSCRYPT_H

#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/slab.h>

#define FS_CRYPTO_BLOCK_SIZE 16

@@ -42,11 +43,410 @@ struct fscrypt_name {
/* Maximum value for the third parameter of fscrypt_operations.set_context(). */
#define FSCRYPT_SET_CONTEXT_MAX_SIZE 28

-#if __FS_HAS_ENCRYPTION
-#include <linux/fscrypt_supp.h>
-#else
-#include <linux/fscrypt_notsupp.h>
-#endif
+#ifdef CONFIG_FS_ENCRYPTION
+/*
+ * fscrypt superblock flags
+ */
+#define FS_CFLG_OWN_PAGES (1U << 1)
+
+/*
+ * crypto operations for filesystems
+ */
+struct fscrypt_operations {
+ unsigned int flags;
+ const char *key_prefix;
+ int (*get_context)(struct inode *, void *, size_t);
+ int (*set_context)(struct inode *, const void *, size_t, void *);
+ bool (*dummy_context)(struct inode *);
+ bool (*empty_dir)(struct inode *);
+ unsigned int max_namelen;
+};
+
+struct fscrypt_ctx {
+ union {
+ struct {
+ struct page *bounce_page; /* Ciphertext page */
+ struct page *control_page; /* Original page */
+ } w;
+ struct {
+ struct bio *bio;
+ struct work_struct work;
+ } r;
+ struct list_head free_list; /* Free list */
+ };
+ u8 flags; /* Flags */
+};
+
+static inline bool fscrypt_has_encryption_key(const struct inode *inode)
+{
+ return (inode->i_crypt_info != NULL);
+}
+
+static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
+{
+ return inode->i_sb->s_cop->dummy_context &&
+ inode->i_sb->s_cop->dummy_context(inode);
+}
+
+/* crypto.c */
+extern void fscrypt_enqueue_decrypt_work(struct work_struct *);
+extern struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *, gfp_t);
+extern void fscrypt_release_ctx(struct fscrypt_ctx *);
+extern struct page *fscrypt_encrypt_page(const struct inode *, struct page *,
+ unsigned int, unsigned int,
+ u64, gfp_t);
+extern int fscrypt_decrypt_page(const struct inode *, struct page *, unsigned int,
+ unsigned int, u64);
+
+static inline struct page *fscrypt_control_page(struct page *page)
+{
+ return ((struct fscrypt_ctx *)page_private(page))->w.control_page;
+}
+
+extern void fscrypt_restore_control_page(struct page *);
+
+/* policy.c */
+extern int fscrypt_ioctl_set_policy(struct file *, const void __user *);
+extern int fscrypt_ioctl_get_policy(struct file *, void __user *);
+extern int fscrypt_has_permitted_context(struct inode *, struct inode *);
+extern int fscrypt_inherit_context(struct inode *, struct inode *,
+ void *, bool);
+/* keyinfo.c */
+extern int fscrypt_get_encryption_info(struct inode *);
+extern void fscrypt_put_encryption_info(struct inode *);
+
+/* fname.c */
+extern int fscrypt_setup_filename(struct inode *, const struct qstr *,
+ int lookup, struct fscrypt_name *);
+
+static inline void fscrypt_free_filename(struct fscrypt_name *fname)
+{
+ kfree(fname->crypto_buf.name);
+}
+
+extern int fscrypt_fname_alloc_buffer(const struct inode *, u32,
+ struct fscrypt_str *);
+extern void fscrypt_fname_free_buffer(struct fscrypt_str *);
+extern int fscrypt_fname_disk_to_usr(struct inode *, u32, u32,
+ const struct fscrypt_str *, struct fscrypt_str *);
+
+#define FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE 32
+
+/* Extracts the second-to-last ciphertext block; see explanation below */
+#define FSCRYPT_FNAME_DIGEST(name, len) \
+ ((name) + round_down((len) - FS_CRYPTO_BLOCK_SIZE - 1, \
+ FS_CRYPTO_BLOCK_SIZE))
+
+#define FSCRYPT_FNAME_DIGEST_SIZE FS_CRYPTO_BLOCK_SIZE
+
+/**
+ * fscrypt_digested_name - alternate identifier for an on-disk filename
+ *
+ * When userspace lists an encrypted directory without access to the key,
+ * filenames whose ciphertext is longer than FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE
+ * bytes are shown in this abbreviated form (base64-encoded) rather than as the
+ * full ciphertext (base64-encoded). This is necessary to allow supporting
+ * filenames up to NAME_MAX bytes, since base64 encoding expands the length.
+ *
+ * To make it possible for filesystems to still find the correct directory entry
+ * despite not knowing the full on-disk name, we encode any filesystem-specific
+ * 'hash' and/or 'minor_hash' which the filesystem may need for its lookups,
+ * followed by the second-to-last ciphertext block of the filename. Due to the
+ * use of the CBC-CTS encryption mode, the second-to-last ciphertext block
+ * depends on the full plaintext. (Note that ciphertext stealing causes the
+ * last two blocks to appear "flipped".) This makes accidental collisions very
+ * unlikely: just a 1 in 2^128 chance for two filenames to collide even if they
+ * share the same filesystem-specific hashes.
+ *
+ * However, this scheme isn't immune to intentional collisions, which can be
+ * created by anyone able to create arbitrary plaintext filenames and view them
+ * without the key. Making the "digest" be a real cryptographic hash like
+ * SHA-256 over the full ciphertext would prevent this, although it would be
+ * less efficient and harder to implement, especially since the filesystem would
+ * need to calculate it for each directory entry examined during a search.
+ */
+struct fscrypt_digested_name {
+ u32 hash;
+ u32 minor_hash;
+ u8 digest[FSCRYPT_FNAME_DIGEST_SIZE];
+};
+
+/**
+ * fscrypt_match_name() - test whether the given name matches a directory entry
+ * @fname: the name being searched for
+ * @de_name: the name from the directory entry
+ * @de_name_len: the length of @de_name in bytes
+ *
+ * Normally @fname->disk_name will be set, and in that case we simply compare
+ * that to the name stored in the directory entry. The only exception is that
+ * if we don't have the key for an encrypted directory and a filename in it is
+ * very long, then we won't have the full disk_name and we'll instead need to
+ * match against the fscrypt_digested_name.
+ *
+ * Return: %true if the name matches, otherwise %false.
+ */
+static inline bool fscrypt_match_name(const struct fscrypt_name *fname,
+ const u8 *de_name, u32 de_name_len)
+{
+ if (unlikely(!fname->disk_name.name)) {
+ const struct fscrypt_digested_name *n =
+ (const void *)fname->crypto_buf.name;
+ if (WARN_ON_ONCE(fname->usr_fname->name[0] != '_'))
+ return false;
+ if (de_name_len <= FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE)
+ return false;
+ return !memcmp(FSCRYPT_FNAME_DIGEST(de_name, de_name_len),
+ n->digest, FSCRYPT_FNAME_DIGEST_SIZE);
+ }
+
+ if (de_name_len != fname->disk_name.len)
+ return false;
+ return !memcmp(de_name, fname->disk_name.name, fname->disk_name.len);
+}
+
+/* bio.c */
+extern void fscrypt_decrypt_bio(struct bio *);
+extern void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx,
+ struct bio *bio);
+extern void fscrypt_pullback_bio_page(struct page **, bool);
+extern int fscrypt_zeroout_range(const struct inode *, pgoff_t, sector_t,
+ unsigned int);
+
+/* hooks.c */
+extern int fscrypt_file_open(struct inode *inode, struct file *filp);
+extern int __fscrypt_prepare_link(struct inode *inode, struct inode *dir);
+extern int __fscrypt_prepare_rename(struct inode *old_dir,
+ struct dentry *old_dentry,
+ struct inode *new_dir,
+ struct dentry *new_dentry,
+ unsigned int flags);
+extern int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry);
+extern int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
+ unsigned int max_len,
+ struct fscrypt_str *disk_link);
+extern int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
+ unsigned int len,
+ struct fscrypt_str *disk_link);
+extern const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
+ unsigned int max_size,
+ struct delayed_call *done);
+#else /* ! CONFIG_FS_ENCRYPTION */
+
+static inline bool fscrypt_has_encryption_key(const struct inode *inode)
+{
+ return false;
+}
+
+static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
+{
+ return false;
+}
+
+/* crypto.c */
+static inline void fscrypt_enqueue_decrypt_work(struct work_struct *work)
+{
+}
+
+static inline struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode,
+ gfp_t gfp_flags)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline void fscrypt_release_ctx(struct fscrypt_ctx *ctx)
+{
+ return;
+}
+
+static inline struct page *fscrypt_encrypt_page(const struct inode *inode,
+ struct page *page,
+ unsigned int len,
+ unsigned int offs,
+ u64 lblk_num, gfp_t gfp_flags)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
+
+static inline int fscrypt_decrypt_page(const struct inode *inode,
+ struct page *page,
+ unsigned int len, unsigned int offs,
+ u64 lblk_num)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline struct page *fscrypt_control_page(struct page *page)
+{
+ WARN_ON_ONCE(1);
+ return ERR_PTR(-EINVAL);
+}
+
+static inline void fscrypt_restore_control_page(struct page *page)
+{
+ return;
+}
+
+/* policy.c */
+static inline int fscrypt_ioctl_set_policy(struct file *filp,
+ const void __user *arg)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int fscrypt_has_permitted_context(struct inode *parent,
+ struct inode *child)
+{
+ return 0;
+}
+
+static inline int fscrypt_inherit_context(struct inode *parent,
+ struct inode *child,
+ void *fs_data, bool preload)
+{
+ return -EOPNOTSUPP;
+}
+
+/* keyinfo.c */
+static inline int fscrypt_get_encryption_info(struct inode *inode)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline void fscrypt_put_encryption_info(struct inode *inode)
+{
+ return;
+}
+
+ /* fname.c */
+static inline int fscrypt_setup_filename(struct inode *dir,
+ const struct qstr *iname,
+ int lookup, struct fscrypt_name *fname)
+{
+ if (IS_ENCRYPTED(dir))
+ return -EOPNOTSUPP;
+
+ memset(fname, 0, sizeof(struct fscrypt_name));
+ fname->usr_fname = iname;
+ fname->disk_name.name = (unsigned char *)iname->name;
+ fname->disk_name.len = iname->len;
+ return 0;
+}
+
+static inline void fscrypt_free_filename(struct fscrypt_name *fname)
+{
+ return;
+}
+
+static inline int fscrypt_fname_alloc_buffer(const struct inode *inode,
+ u32 max_encrypted_len,
+ struct fscrypt_str *crypto_str)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str)
+{
+ return;
+}
+
+static inline int fscrypt_fname_disk_to_usr(struct inode *inode,
+ u32 hash, u32 minor_hash,
+ const struct fscrypt_str *iname,
+ struct fscrypt_str *oname)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline bool fscrypt_match_name(const struct fscrypt_name *fname,
+ const u8 *de_name, u32 de_name_len)
+{
+ /* Encryption support disabled; use standard comparison */
+ if (de_name_len != fname->disk_name.len)
+ return false;
+ return !memcmp(de_name, fname->disk_name.name, fname->disk_name.len);
+}
+
+/* bio.c */
+static inline void fscrypt_decrypt_bio(struct bio *bio)
+{
+}
+
+static inline void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx,
+ struct bio *bio)
+{
+}
+
+static inline void fscrypt_pullback_bio_page(struct page **page, bool restore)
+{
+ return;
+}
+
+static inline int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
+ sector_t pblk, unsigned int len)
+{
+ return -EOPNOTSUPP;
+}
+
+/* hooks.c */
+
+static inline int fscrypt_file_open(struct inode *inode, struct file *filp)
+{
+ if (IS_ENCRYPTED(inode))
+ return -EOPNOTSUPP;
+ return 0;
+}
+
+static inline int __fscrypt_prepare_link(struct inode *inode,
+ struct inode *dir)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int __fscrypt_prepare_rename(struct inode *old_dir,
+ struct dentry *old_dentry,
+ struct inode *new_dir,
+ struct dentry *new_dentry,
+ unsigned int flags)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int __fscrypt_prepare_lookup(struct inode *dir,
+ struct dentry *dentry)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline int __fscrypt_prepare_symlink(struct inode *dir,
+ unsigned int len,
+ unsigned int max_len,
+ struct fscrypt_str *disk_link)
+{
+ return -EOPNOTSUPP;
+}
+
+
+static inline int __fscrypt_encrypt_symlink(struct inode *inode,
+ const char *target,
+ unsigned int len,
+ struct fscrypt_str *disk_link)
+{
+ return -EOPNOTSUPP;
+}
+
+static inline const char *fscrypt_get_symlink(struct inode *inode,
+ const void *caddr,
+ unsigned int max_size,
+ struct delayed_call *done)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
+#endif /* ! CONFIG_FS_ENCRYPTION */

/**
* fscrypt_require_key - require an inode's encryption key
diff --git a/include/linux/fscrypt_notsupp.h b/include/linux/fscrypt_notsupp.h
deleted file mode 100644
index ee8b43e4c15a..000000000000
--- a/include/linux/fscrypt_notsupp.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * fscrypt_notsupp.h
- *
- * This stubs out the fscrypt functions for filesystems configured without
- * encryption support.
- *
- * Do not include this file directly. Use fscrypt.h instead!
- */
-#ifndef _LINUX_FSCRYPT_H
-#error "Incorrect include of linux/fscrypt_notsupp.h!"
-#endif
-
-#ifndef _LINUX_FSCRYPT_NOTSUPP_H
-#define _LINUX_FSCRYPT_NOTSUPP_H
-
-static inline bool fscrypt_has_encryption_key(const struct inode *inode)
-{
- return false;
-}
-
-static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
-{
- return false;
-}
-
-/* crypto.c */
-static inline void fscrypt_enqueue_decrypt_work(struct work_struct *work)
-{
-}
-
-static inline struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode,
- gfp_t gfp_flags)
-{
- return ERR_PTR(-EOPNOTSUPP);
-}
-
-static inline void fscrypt_release_ctx(struct fscrypt_ctx *ctx)
-{
- return;
-}
-
-static inline struct page *fscrypt_encrypt_page(const struct inode *inode,
- struct page *page,
- unsigned int len,
- unsigned int offs,
- u64 lblk_num, gfp_t gfp_flags)
-{
- return ERR_PTR(-EOPNOTSUPP);
-}
-
-static inline int fscrypt_decrypt_page(const struct inode *inode,
- struct page *page,
- unsigned int len, unsigned int offs,
- u64 lblk_num)
-{
- return -EOPNOTSUPP;
-}
-
-static inline struct page *fscrypt_control_page(struct page *page)
-{
- WARN_ON_ONCE(1);
- return ERR_PTR(-EINVAL);
-}
-
-static inline void fscrypt_restore_control_page(struct page *page)
-{
- return;
-}
-
-/* policy.c */
-static inline int fscrypt_ioctl_set_policy(struct file *filp,
- const void __user *arg)
-{
- return -EOPNOTSUPP;
-}
-
-static inline int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg)
-{
- return -EOPNOTSUPP;
-}
-
-static inline int fscrypt_has_permitted_context(struct inode *parent,
- struct inode *child)
-{
- return 0;
-}
-
-static inline int fscrypt_inherit_context(struct inode *parent,
- struct inode *child,
- void *fs_data, bool preload)
-{
- return -EOPNOTSUPP;
-}
-
-/* keyinfo.c */
-static inline int fscrypt_get_encryption_info(struct inode *inode)
-{
- return -EOPNOTSUPP;
-}
-
-static inline void fscrypt_put_encryption_info(struct inode *inode)
-{
- return;
-}
-
- /* fname.c */
-static inline int fscrypt_setup_filename(struct inode *dir,
- const struct qstr *iname,
- int lookup, struct fscrypt_name *fname)
-{
- if (IS_ENCRYPTED(dir))
- return -EOPNOTSUPP;
-
- memset(fname, 0, sizeof(struct fscrypt_name));
- fname->usr_fname = iname;
- fname->disk_name.name = (unsigned char *)iname->name;
- fname->disk_name.len = iname->len;
- return 0;
-}
-
-static inline void fscrypt_free_filename(struct fscrypt_name *fname)
-{
- return;
-}
-
-static inline int fscrypt_fname_alloc_buffer(const struct inode *inode,
- u32 max_encrypted_len,
- struct fscrypt_str *crypto_str)
-{
- return -EOPNOTSUPP;
-}
-
-static inline void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str)
-{
- return;
-}
-
-static inline int fscrypt_fname_disk_to_usr(struct inode *inode,
- u32 hash, u32 minor_hash,
- const struct fscrypt_str *iname,
- struct fscrypt_str *oname)
-{
- return -EOPNOTSUPP;
-}
-
-static inline bool fscrypt_match_name(const struct fscrypt_name *fname,
- const u8 *de_name, u32 de_name_len)
-{
- /* Encryption support disabled; use standard comparison */
- if (de_name_len != fname->disk_name.len)
- return false;
- return !memcmp(de_name, fname->disk_name.name, fname->disk_name.len);
-}
-
-/* bio.c */
-static inline void fscrypt_decrypt_bio(struct bio *bio)
-{
-}
-
-static inline void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx,
- struct bio *bio)
-{
-}
-
-static inline void fscrypt_pullback_bio_page(struct page **page, bool restore)
-{
- return;
-}
-
-static inline int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk,
- sector_t pblk, unsigned int len)
-{
- return -EOPNOTSUPP;
-}
-
-/* hooks.c */
-
-static inline int fscrypt_file_open(struct inode *inode, struct file *filp)
-{
- if (IS_ENCRYPTED(inode))
- return -EOPNOTSUPP;
- return 0;
-}
-
-static inline int __fscrypt_prepare_link(struct inode *inode,
- struct inode *dir)
-{
- return -EOPNOTSUPP;
-}
-
-static inline int __fscrypt_prepare_rename(struct inode *old_dir,
- struct dentry *old_dentry,
- struct inode *new_dir,
- struct dentry *new_dentry,
- unsigned int flags)
-{
- return -EOPNOTSUPP;
-}
-
-static inline int __fscrypt_prepare_lookup(struct inode *dir,
- struct dentry *dentry)
-{
- return -EOPNOTSUPP;
-}
-
-static inline int __fscrypt_prepare_symlink(struct inode *dir,
- unsigned int len,
- unsigned int max_len,
- struct fscrypt_str *disk_link)
-{
- return -EOPNOTSUPP;
-}
-
-static inline int __fscrypt_encrypt_symlink(struct inode *inode,
- const char *target,
- unsigned int len,
- struct fscrypt_str *disk_link)
-{
- return -EOPNOTSUPP;
-}
-
-static inline const char *fscrypt_get_symlink(struct inode *inode,
- const void *caddr,
- unsigned int max_size,
- struct delayed_call *done)
-{
- return ERR_PTR(-EOPNOTSUPP);
-}
-
-#endif /* _LINUX_FSCRYPT_NOTSUPP_H */
diff --git a/include/linux/fscrypt_supp.h b/include/linux/fscrypt_supp.h
deleted file mode 100644
index 6456c6b2005f..000000000000
--- a/include/linux/fscrypt_supp.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * fscrypt_supp.h
- *
- * Do not include this file directly. Use fscrypt.h instead!
- */
-#ifndef _LINUX_FSCRYPT_H
-#error "Incorrect include of linux/fscrypt_supp.h!"
-#endif
-
-#ifndef _LINUX_FSCRYPT_SUPP_H
-#define _LINUX_FSCRYPT_SUPP_H
-
-#include <linux/mm.h>
-#include <linux/slab.h>
-
-/*
- * fscrypt superblock flags
- */
-#define FS_CFLG_OWN_PAGES (1U << 1)
-
-/*
- * crypto operations for filesystems
- */
-struct fscrypt_operations {
- unsigned int flags;
- const char *key_prefix;
- int (*get_context)(struct inode *, void *, size_t);
- int (*set_context)(struct inode *, const void *, size_t, void *);
- bool (*dummy_context)(struct inode *);
- bool (*empty_dir)(struct inode *);
- unsigned int max_namelen;
-};
-
-struct fscrypt_ctx {
- union {
- struct {
- struct page *bounce_page; /* Ciphertext page */
- struct page *control_page; /* Original page */
- } w;
- struct {
- struct bio *bio;
- struct work_struct work;
- } r;
- struct list_head free_list; /* Free list */
- };
- u8 flags; /* Flags */
-};
-
-static inline bool fscrypt_has_encryption_key(const struct inode *inode)
-{
- return (inode->i_crypt_info != NULL);
-}
-
-static inline bool fscrypt_dummy_context_enabled(struct inode *inode)
-{
- return inode->i_sb->s_cop->dummy_context &&
- inode->i_sb->s_cop->dummy_context(inode);
-}
-
-/* crypto.c */
-extern void fscrypt_enqueue_decrypt_work(struct work_struct *);
-extern struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *, gfp_t);
-extern void fscrypt_release_ctx(struct fscrypt_ctx *);
-extern struct page *fscrypt_encrypt_page(const struct inode *, struct page *,
- unsigned int, unsigned int,
- u64, gfp_t);
-extern int fscrypt_decrypt_page(const struct inode *, struct page *, unsigned int,
- unsigned int, u64);
-
-static inline struct page *fscrypt_control_page(struct page *page)
-{
- return ((struct fscrypt_ctx *)page_private(page))->w.control_page;
-}
-
-extern void fscrypt_restore_control_page(struct page *);
-
-/* policy.c */
-extern int fscrypt_ioctl_set_policy(struct file *, const void __user *);
-extern int fscrypt_ioctl_get_policy(struct file *, void __user *);
-extern int fscrypt_has_permitted_context(struct inode *, struct inode *);
-extern int fscrypt_inherit_context(struct inode *, struct inode *,
- void *, bool);
-/* keyinfo.c */
-extern int fscrypt_get_encryption_info(struct inode *);
-extern void fscrypt_put_encryption_info(struct inode *);
-
-/* fname.c */
-extern int fscrypt_setup_filename(struct inode *, const struct qstr *,
- int lookup, struct fscrypt_name *);
-
-static inline void fscrypt_free_filename(struct fscrypt_name *fname)
-{
- kfree(fname->crypto_buf.name);
-}
-
-extern int fscrypt_fname_alloc_buffer(const struct inode *, u32,
- struct fscrypt_str *);
-extern void fscrypt_fname_free_buffer(struct fscrypt_str *);
-extern int fscrypt_fname_disk_to_usr(struct inode *, u32, u32,
- const struct fscrypt_str *, struct fscrypt_str *);
-
-#define FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE 32
-
-/* Extracts the second-to-last ciphertext block; see explanation below */
-#define FSCRYPT_FNAME_DIGEST(name, len) \
- ((name) + round_down((len) - FS_CRYPTO_BLOCK_SIZE - 1, \
- FS_CRYPTO_BLOCK_SIZE))
-
-#define FSCRYPT_FNAME_DIGEST_SIZE FS_CRYPTO_BLOCK_SIZE
-
-/**
- * fscrypt_digested_name - alternate identifier for an on-disk filename
- *
- * When userspace lists an encrypted directory without access to the key,
- * filenames whose ciphertext is longer than FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE
- * bytes are shown in this abbreviated form (base64-encoded) rather than as the
- * full ciphertext (base64-encoded). This is necessary to allow supporting
- * filenames up to NAME_MAX bytes, since base64 encoding expands the length.
- *
- * To make it possible for filesystems to still find the correct directory entry
- * despite not knowing the full on-disk name, we encode any filesystem-specific
- * 'hash' and/or 'minor_hash' which the filesystem may need for its lookups,
- * followed by the second-to-last ciphertext block of the filename. Due to the
- * use of the CBC-CTS encryption mode, the second-to-last ciphertext block
- * depends on the full plaintext. (Note that ciphertext stealing causes the
- * last two blocks to appear "flipped".) This makes accidental collisions very
- * unlikely: just a 1 in 2^128 chance for two filenames to collide even if they
- * share the same filesystem-specific hashes.
- *
- * However, this scheme isn't immune to intentional collisions, which can be
- * created by anyone able to create arbitrary plaintext filenames and view them
- * without the key. Making the "digest" be a real cryptographic hash like
- * SHA-256 over the full ciphertext would prevent this, although it would be
- * less efficient and harder to implement, especially since the filesystem would
- * need to calculate it for each directory entry examined during a search.
- */
-struct fscrypt_digested_name {
- u32 hash;
- u32 minor_hash;
- u8 digest[FSCRYPT_FNAME_DIGEST_SIZE];
-};
-
-/**
- * fscrypt_match_name() - test whether the given name matches a directory entry
- * @fname: the name being searched for
- * @de_name: the name from the directory entry
- * @de_name_len: the length of @de_name in bytes
- *
- * Normally @fname->disk_name will be set, and in that case we simply compare
- * that to the name stored in the directory entry. The only exception is that
- * if we don't have the key for an encrypted directory and a filename in it is
- * very long, then we won't have the full disk_name and we'll instead need to
- * match against the fscrypt_digested_name.
- *
- * Return: %true if the name matches, otherwise %false.
- */
-static inline bool fscrypt_match_name(const struct fscrypt_name *fname,
- const u8 *de_name, u32 de_name_len)
-{
- if (unlikely(!fname->disk_name.name)) {
- const struct fscrypt_digested_name *n =
- (const void *)fname->crypto_buf.name;
- if (WARN_ON_ONCE(fname->usr_fname->name[0] != '_'))
- return false;
- if (de_name_len <= FSCRYPT_FNAME_MAX_UNDIGESTED_SIZE)
- return false;
- return !memcmp(FSCRYPT_FNAME_DIGEST(de_name, de_name_len),
- n->digest, FSCRYPT_FNAME_DIGEST_SIZE);
- }
-
- if (de_name_len != fname->disk_name.len)
- return false;
- return !memcmp(de_name, fname->disk_name.name, fname->disk_name.len);
-}
-
-/* bio.c */
-extern void fscrypt_decrypt_bio(struct bio *);
-extern void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx,
- struct bio *bio);
-extern void fscrypt_pullback_bio_page(struct page **, bool);
-extern int fscrypt_zeroout_range(const struct inode *, pgoff_t, sector_t,
- unsigned int);
-
-/* hooks.c */
-extern int fscrypt_file_open(struct inode *inode, struct file *filp);
-extern int __fscrypt_prepare_link(struct inode *inode, struct inode *dir);
-extern int __fscrypt_prepare_rename(struct inode *old_dir,
- struct dentry *old_dentry,
- struct inode *new_dir,
- struct dentry *new_dentry,
- unsigned int flags);
-extern int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry);
-extern int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
- unsigned int max_len,
- struct fscrypt_str *disk_link);
-extern int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
- unsigned int len,
- struct fscrypt_str *disk_link);
-extern const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
- unsigned int max_size,
- struct delayed_call *done);
-
-#endif /* _LINUX_FSCRYPT_SUPP_H */
--
2.19.1