Message ID | 20181119052324.31456-4-chandan@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Remove fs specific fscrypt and fsverity build config options | expand |
Hi Chandan, On Mon, Nov 19, 2018 at 10:53:20AM +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 <chandan@linux.vnet.ibm.com> Can you grep for EXT4_ENCRYPTION? There are still some references left, one in Documentation/filesystems/fscrypt.rst and some in defconfig files. Also in include/linux/fs.h, there are tests of #if IS_ENABLED(CONFIG_FS_ENCRYPTION) which after this change should be #ifdef CONFIG_FS_ENCRYPTION like is done elsewhere. Thanks, - Eric > --- > fs/crypto/Kconfig | 2 +- > 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 +- > include/linux/fscrypt.h | 416 +++++++++++++++++++++++++++++++- > include/linux/fscrypt_notsupp.h | 231 ------------------ > include/linux/fscrypt_supp.h | 204 ---------------- > 18 files changed, 441 insertions(+), 506 deletions(-) > delete mode 100644 include/linux/fscrypt_notsupp.h > delete mode 100644 include/linux/fscrypt_supp.h > > diff --git a/fs/crypto/Kconfig b/fs/crypto/Kconfig > index 02b7d91c9231..6e9ae566a8fc 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 > 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 725777772f32..ae6794649817 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/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 >
On Tuesday, November 27, 2018 5:44:24 AM IST Eric Biggers wrote: > Hi Chandan, > > On Mon, Nov 19, 2018 at 10:53:20AM +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 <chandan@linux.vnet.ibm.com> > > Can you grep for EXT4_ENCRYPTION? There are still some references left, one in > Documentation/filesystems/fscrypt.rst and some in defconfig files. > > Also in include/linux/fs.h, there are tests of > > #if IS_ENABLED(CONFIG_FS_ENCRYPTION) > > which after this change should be > > #ifdef CONFIG_FS_ENCRYPTION > > like is done elsewhere. Sorry, I had restricted my search to *.[ch] files and that too within linux/fs/ directory. I will fix the other occurrences as well. > > > --- > > fs/crypto/Kconfig | 2 +- > > 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 +- > > include/linux/fscrypt.h | 416 +++++++++++++++++++++++++++++++- > > include/linux/fscrypt_notsupp.h | 231 ------------------ > > include/linux/fscrypt_supp.h | 204 ---------------- > > 18 files changed, 441 insertions(+), 506 deletions(-) > > delete mode 100644 include/linux/fscrypt_notsupp.h > > delete mode 100644 include/linux/fscrypt_supp.h > > > > diff --git a/fs/crypto/Kconfig b/fs/crypto/Kconfig > > index 02b7d91c9231..6e9ae566a8fc 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 > > 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 725777772f32..ae6794649817 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/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 */ > >
diff --git a/fs/crypto/Kconfig b/fs/crypto/Kconfig index 02b7d91c9231..6e9ae566a8fc 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 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 725777772f32..ae6794649817 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/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 */
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 <chandan@linux.vnet.ibm.com> --- fs/crypto/Kconfig | 2 +- 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 +- include/linux/fscrypt.h | 416 +++++++++++++++++++++++++++++++- include/linux/fscrypt_notsupp.h | 231 ------------------ include/linux/fscrypt_supp.h | 204 ---------------- 18 files changed, 441 insertions(+), 506 deletions(-) delete mode 100644 include/linux/fscrypt_notsupp.h delete mode 100644 include/linux/fscrypt_supp.h