fscrypt updates for v5.1

First: Ted, Jaegeuk, and I have decided to add me as a co-maintainer for
 fscrypt, and we're now using a shared git tree.  So we've updated
 MAINTAINERS accordingly, and I'm doing the pull request this time.
 
 The actual changes for v5.1 are:
 
 - Remove the fs-specific kconfig options like CONFIG_EXT4_ENCRYPTION and
   make fscrypt support for all fscrypt-capable filesystems be controlled
   by CONFIG_FS_ENCRYPTION, similar to how CONFIG_QUOTA works.
 
 - Improve error code for rename() and link() into encrypted directories.
 
 - Various cleanups.
 -----BEGIN PGP SIGNATURE-----
 
 iIoEABYIADIWIQSacvsUNc7UX4ntmEPzXCl4vpKOKwUCXH2YDRQcZWJpZ2dlcnNA
 Z29vZ2xlLmNvbQAKCRDzXCl4vpKOK+SAAQCWYOTwYko8uE8Ze8i2fiUm0vr91NOg
 zj5DGmK7Izxy/gEAsNDOVA7zWrDg/f5600/7aLpDQQTGHA38YVsgiyd7DgY=
 =S3tT
 -----END PGP SIGNATURE-----

Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt

Pull fscrypt updates from Eric Biggers:
 "First: Ted, Jaegeuk, and I have decided to add me as a co-maintainer
  for fscrypt, and we're now using a shared git tree. So we've updated
  MAINTAINERS accordingly, and I'm doing the pull request this time.

  The actual changes for v5.1 are:

   - Remove the fs-specific kconfig options like CONFIG_EXT4_ENCRYPTION
     and make fscrypt support for all fscrypt-capable filesystems be
     controlled by CONFIG_FS_ENCRYPTION, similar to how CONFIG_QUOTA
     works.

   - Improve error code for rename() and link() into encrypted
     directories.

   - Various cleanups"

* tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt:
  MAINTAINERS: add Eric Biggers as an fscrypt maintainer
  fscrypt: return -EXDEV for incompatible rename or link into encrypted dir
  fscrypt: remove filesystem specific build config option
  f2fs: use IS_ENCRYPTED() to check encryption status
  ext4: use IS_ENCRYPTED() to check encryption status
  fscrypt: remove CRYPTO_CTR dependency
This commit is contained in:
Linus Torvalds 2019-03-09 10:54:24 -08:00
commit d1cae94871
43 changed files with 518 additions and 601 deletions

View File

@ -343,9 +343,9 @@ FS_IOC_SET_ENCRYPTION_POLICY can fail with the following errors:
- ``ENOTEMPTY``: the file is unencrypted and is a nonempty directory - ``ENOTEMPTY``: the file is unencrypted and is a nonempty directory
- ``ENOTTY``: this type of filesystem does not implement encryption - ``ENOTTY``: this type of filesystem does not implement encryption
- ``EOPNOTSUPP``: the kernel was not configured with encryption - ``EOPNOTSUPP``: the kernel was not configured with encryption
support for this filesystem, or the filesystem superblock has not support for filesystems, or the filesystem superblock has not
had encryption enabled on it. (For example, to use encryption on an had encryption enabled on it. (For example, to use encryption on an
ext4 filesystem, CONFIG_EXT4_ENCRYPTION must be enabled in the ext4 filesystem, CONFIG_FS_ENCRYPTION must be enabled in the
kernel config, and the superblock must have had the "encrypt" kernel config, and the superblock must have had the "encrypt"
feature flag enabled using ``tune2fs -O encrypt`` or ``mkfs.ext4 -O feature flag enabled using ``tune2fs -O encrypt`` or ``mkfs.ext4 -O
encrypt``.) encrypt``.)
@ -451,10 +451,18 @@ astute users may notice some differences in behavior:
- Unencrypted files, or files encrypted with a different encryption - Unencrypted files, or files encrypted with a different encryption
policy (i.e. different key, modes, or flags), cannot be renamed or policy (i.e. different key, modes, or flags), cannot be renamed or
linked into an encrypted directory; see `Encryption policy linked into an encrypted directory; see `Encryption policy
enforcement`_. Attempts to do so will fail with EPERM. However, enforcement`_. Attempts to do so will fail with EXDEV. However,
encrypted files can be renamed within an encrypted directory, or encrypted files can be renamed within an encrypted directory, or
into an unencrypted directory. into an unencrypted directory.
Note: "moving" an unencrypted file into an encrypted directory, e.g.
with the `mv` program, is implemented in userspace by a copy
followed by a delete. Be aware that the original unencrypted data
may remain recoverable from free space on the disk; prefer to keep
all files encrypted from the very beginning. The `shred` program
may be used to overwrite the source files but isn't guaranteed to be
effective on all filesystems and storage devices.
- Direct I/O is not supported on encrypted files. Attempts to use - Direct I/O is not supported on encrypted files. Attempts to use
direct I/O on such files will fall back to buffered I/O. direct I/O on such files will fall back to buffered I/O.
@ -541,7 +549,7 @@ not be encrypted.
Except for those special files, it is forbidden to have unencrypted Except for those special files, it is forbidden to have unencrypted
files, or files encrypted with a different encryption policy, in an files, or files encrypted with a different encryption policy, in an
encrypted directory tree. Attempts to link or rename such a file into encrypted directory tree. Attempts to link or rename such a file into
an encrypted directory will fail with EPERM. This is also enforced an encrypted directory will fail with EXDEV. This is also enforced
during ->lookup() to provide limited protection against offline during ->lookup() to provide limited protection against offline
attacks that try to disable or downgrade encryption in known locations attacks that try to disable or downgrade encryption in known locations
where applications may later write sensitive data. It is recommended where applications may later write sensitive data. It is recommended

View File

@ -6337,9 +6337,10 @@ F: include/linux/fscache*.h
FSCRYPT: FILE SYSTEM LEVEL ENCRYPTION SUPPORT FSCRYPT: FILE SYSTEM LEVEL ENCRYPTION SUPPORT
M: Theodore Y. Ts'o <tytso@mit.edu> M: Theodore Y. Ts'o <tytso@mit.edu>
M: Jaegeuk Kim <jaegeuk@kernel.org> M: Jaegeuk Kim <jaegeuk@kernel.org>
M: Eric Biggers <ebiggers@kernel.org>
L: linux-fscrypt@vger.kernel.org L: linux-fscrypt@vger.kernel.org
Q: https://patchwork.kernel.org/project/linux-fscrypt/list/ Q: https://patchwork.kernel.org/project/linux-fscrypt/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tytso/fscrypt.git T: git git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt.git
S: Supported S: Supported
F: fs/crypto/ F: fs/crypto/
F: include/linux/fscrypt*.h F: include/linux/fscrypt*.h

View File

@ -59,7 +59,7 @@ CONFIG_HID_MONTEREY=y
CONFIG_EXT4_FS=y CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXT4_ENCRYPTION=y CONFIG_FS_ENCRYPTION=y
CONFIG_FANOTIFY=y CONFIG_FANOTIFY=y
CONFIG_FUSE_FS=y CONFIG_FUSE_FS=y
CONFIG_CUSE=y CONFIG_CUSE=y

View File

@ -74,7 +74,7 @@ CONFIG_GENERIC_PHY=y
CONFIG_EXT4_FS=y CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXT4_ENCRYPTION=y CONFIG_FS_ENCRYPTION=y
CONFIG_FUSE_FS=y CONFIG_FUSE_FS=y
CONFIG_MSDOS_FS=y CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y CONFIG_VFAT_FS=y

View File

@ -500,7 +500,6 @@ CONFIG_S390_AP_IOMMU=y
CONFIG_EXT4_FS=y CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXT4_ENCRYPTION=y
CONFIG_JBD2_DEBUG=y CONFIG_JBD2_DEBUG=y
CONFIG_JFS_FS=m CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y CONFIG_JFS_POSIX_ACL=y
@ -520,6 +519,7 @@ CONFIG_BTRFS_DEBUG=y
CONFIG_NILFS2_FS=m CONFIG_NILFS2_FS=m
CONFIG_FS_DAX=y CONFIG_FS_DAX=y
CONFIG_EXPORTFS_BLOCK_OPS=y CONFIG_EXPORTFS_BLOCK_OPS=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FANOTIFY=y CONFIG_FANOTIFY=y
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QUOTA_NETLINK_INTERFACE=y

View File

@ -497,7 +497,6 @@ CONFIG_S390_AP_IOMMU=y
CONFIG_EXT4_FS=y CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_FS_SECURITY=y
CONFIG_EXT4_ENCRYPTION=y
CONFIG_JBD2_DEBUG=y CONFIG_JBD2_DEBUG=y
CONFIG_JFS_FS=m CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y CONFIG_JFS_POSIX_ACL=y
@ -515,6 +514,7 @@ CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_NILFS2_FS=m CONFIG_NILFS2_FS=m
CONFIG_FS_DAX=y CONFIG_FS_DAX=y
CONFIG_EXPORTFS_BLOCK_OPS=y CONFIG_EXPORTFS_BLOCK_OPS=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FANOTIFY=y CONFIG_FANOTIFY=y
CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QUOTA_NETLINK_INTERFACE=y

View File

@ -1,16 +1,16 @@
config FS_ENCRYPTION config FS_ENCRYPTION
tristate "FS Encryption (Per-file encryption)" bool "FS Encryption (Per-file encryption)"
select CRYPTO select CRYPTO
select CRYPTO_AES select CRYPTO_AES
select CRYPTO_CBC select CRYPTO_CBC
select CRYPTO_ECB select CRYPTO_ECB
select CRYPTO_XTS select CRYPTO_XTS
select CRYPTO_CTS select CRYPTO_CTS
select CRYPTO_CTR
select CRYPTO_SHA256 select CRYPTO_SHA256
select KEYS select KEYS
help help
Enable encryption of files and directories. This Enable encryption of files and directories. This
feature is similar to ecryptfs, but it is more memory feature is similar to ecryptfs, but it is more memory
efficient since it avoids caching the encrypted and efficient since it avoids caching the encrypted and
decrypted pages in the page cache. decrypted pages in the page cache. Currently Ext4,
F2FS and UBIFS make use of this feature.

View File

@ -12,7 +12,6 @@
#ifndef _FSCRYPT_PRIVATE_H #ifndef _FSCRYPT_PRIVATE_H
#define _FSCRYPT_PRIVATE_H #define _FSCRYPT_PRIVATE_H
#define __FS_HAS_ENCRYPTION 1
#include <linux/fscrypt.h> #include <linux/fscrypt.h>
#include <crypto/hash.h> #include <crypto/hash.h>

View File

@ -58,7 +58,7 @@ int __fscrypt_prepare_link(struct inode *inode, struct inode *dir)
return err; return err;
if (!fscrypt_has_permitted_context(dir, inode)) if (!fscrypt_has_permitted_context(dir, inode))
return -EPERM; return -EXDEV;
return 0; return 0;
} }
@ -82,13 +82,13 @@ int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry,
if (IS_ENCRYPTED(new_dir) && if (IS_ENCRYPTED(new_dir) &&
!fscrypt_has_permitted_context(new_dir, !fscrypt_has_permitted_context(new_dir,
d_inode(old_dentry))) d_inode(old_dentry)))
return -EPERM; return -EXDEV;
if ((flags & RENAME_EXCHANGE) && if ((flags & RENAME_EXCHANGE) &&
IS_ENCRYPTED(old_dir) && IS_ENCRYPTED(old_dir) &&
!fscrypt_has_permitted_context(old_dir, !fscrypt_has_permitted_context(old_dir,
d_inode(new_dentry))) d_inode(new_dentry)))
return -EPERM; return -EXDEV;
} }
return 0; return 0;
} }

View File

@ -151,8 +151,7 @@ EXPORT_SYMBOL(fscrypt_ioctl_get_policy);
* malicious offline violations of this constraint, while the link and rename * malicious offline violations of this constraint, while the link and rename
* checks are needed to prevent online violations of this constraint. * checks are needed to prevent online violations of this constraint.
* *
* Return: 1 if permitted, 0 if forbidden. If forbidden, the caller must fail * Return: 1 if permitted, 0 if forbidden.
* the filesystem operation with EPERM.
*/ */
int fscrypt_has_permitted_context(struct inode *parent, struct inode *child) int fscrypt_has_permitted_context(struct inode *parent, struct inode *child)
{ {

View File

@ -96,21 +96,6 @@ config EXT4_FS_SECURITY
If you are not using a security module that requires using If you are not using a security module that requires using
extended attributes for file security labels, say N. 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_DEBUG config EXT4_DEBUG
bool "EXT4 debugging support" bool "EXT4 debugging support"
depends on EXT4_FS depends on EXT4_FS

View File

@ -111,7 +111,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
int dir_has_error = 0; int dir_has_error = 0;
struct fscrypt_str fstr = FSTR_INIT(NULL, 0); struct fscrypt_str fstr = FSTR_INIT(NULL, 0);
if (ext4_encrypted_inode(inode)) { if (IS_ENCRYPTED(inode)) {
err = fscrypt_get_encryption_info(inode); err = fscrypt_get_encryption_info(inode);
if (err && err != -ENOKEY) if (err && err != -ENOKEY)
return err; return err;
@ -138,7 +138,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
return err; return err;
} }
if (ext4_encrypted_inode(inode)) { if (IS_ENCRYPTED(inode)) {
err = fscrypt_fname_alloc_buffer(inode, EXT4_NAME_LEN, &fstr); err = fscrypt_fname_alloc_buffer(inode, EXT4_NAME_LEN, &fstr);
if (err < 0) if (err < 0)
return err; return err;
@ -245,7 +245,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
offset += ext4_rec_len_from_disk(de->rec_len, offset += ext4_rec_len_from_disk(de->rec_len,
sb->s_blocksize); sb->s_blocksize);
if (le32_to_cpu(de->inode)) { if (le32_to_cpu(de->inode)) {
if (!ext4_encrypted_inode(inode)) { if (!IS_ENCRYPTED(inode)) {
if (!dir_emit(ctx, de->name, if (!dir_emit(ctx, de->name,
de->name_len, de->name_len,
le32_to_cpu(de->inode), le32_to_cpu(de->inode),
@ -283,9 +283,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
done: done:
err = 0; err = 0;
errout: errout:
#ifdef CONFIG_EXT4_FS_ENCRYPTION
fscrypt_fname_free_buffer(&fstr); fscrypt_fname_free_buffer(&fstr);
#endif
brelse(bh); brelse(bh);
return err; return err;
} }
@ -613,7 +611,7 @@ finished:
static int ext4_dir_open(struct inode * inode, struct file * filp) static int ext4_dir_open(struct inode * inode, struct file * filp)
{ {
if (ext4_encrypted_inode(inode)) if (IS_ENCRYPTED(inode))
return fscrypt_get_encryption_info(inode) ? -EACCES : 0; return fscrypt_get_encryption_info(inode) ? -EACCES : 0;
return 0; return 0;
} }

View File

@ -40,7 +40,6 @@
#include <linux/compat.h> #include <linux/compat.h>
#endif #endif
#define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_EXT4_FS_ENCRYPTION)
#include <linux/fscrypt.h> #include <linux/fscrypt.h>
#include <linux/compiler.h> #include <linux/compiler.h>
@ -1326,7 +1325,7 @@ struct ext4_super_block {
#define EXT4_MF_FS_ABORTED 0x0002 /* Fatal error detected */ #define EXT4_MF_FS_ABORTED 0x0002 /* Fatal error detected */
#define EXT4_MF_TEST_DUMMY_ENCRYPTION 0x0004 #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 & \ #define DUMMY_ENCRYPTION_ENABLED(sbi) (unlikely((sbi)->s_mount_flags & \
EXT4_MF_TEST_DUMMY_ENCRYPTION)) EXT4_MF_TEST_DUMMY_ENCRYPTION))
#else #else
@ -2051,7 +2050,7 @@ struct ext4_filename {
const struct qstr *usr_fname; const struct qstr *usr_fname;
struct fscrypt_str disk_name; struct fscrypt_str disk_name;
struct dx_hash_info hinfo; struct dx_hash_info hinfo;
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
struct fscrypt_str crypto_buf; struct fscrypt_str crypto_buf;
#endif #endif
}; };
@ -2279,12 +2278,7 @@ extern unsigned ext4_free_clusters_after_init(struct super_block *sb,
struct ext4_group_desc *gdp); struct ext4_group_desc *gdp);
ext4_fsblk_t ext4_inode_to_goal_block(struct inode *); ext4_fsblk_t ext4_inode_to_goal_block(struct inode *);
static inline bool ext4_encrypted_inode(struct inode *inode) #ifdef CONFIG_FS_ENCRYPTION
{
return ext4_test_inode_flag(inode, EXT4_INODE_ENCRYPT);
}
#ifdef CONFIG_EXT4_FS_ENCRYPTION
static inline int ext4_fname_setup_filename(struct inode *dir, static inline int ext4_fname_setup_filename(struct inode *dir,
const struct qstr *iname, const struct qstr *iname,
int lookup, struct ext4_filename *fname) int lookup, struct ext4_filename *fname)

View File

@ -411,7 +411,7 @@ static inline int ext4_inode_journal_mode(struct inode *inode)
(ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) && (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) &&
!test_opt(inode->i_sb, DELALLOC))) { !test_opt(inode->i_sb, DELALLOC))) {
/* We do not support data journalling for encrypted data */ /* We do not support data journalling for encrypted data */
if (S_ISREG(inode->i_mode) && ext4_encrypted_inode(inode)) if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode))
return EXT4_INODE_ORDERED_DATA_MODE; /* ordered */ return EXT4_INODE_ORDERED_DATA_MODE; /* ordered */
return EXT4_INODE_JOURNAL_DATA_MODE; /* journal data */ return EXT4_INODE_JOURNAL_DATA_MODE; /* journal data */
} }

View File

@ -3631,7 +3631,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
max_zeroout = sbi->s_extent_max_zeroout_kb >> max_zeroout = sbi->s_extent_max_zeroout_kb >>
(inode->i_sb->s_blocksize_bits - 10); (inode->i_sb->s_blocksize_bits - 10);
if (ext4_encrypted_inode(inode)) if (IS_ENCRYPTED(inode))
max_zeroout = 0; max_zeroout = 0;
/* /*
@ -4818,7 +4818,7 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
* leave it disabled for encrypted inodes for now. This is a * leave it disabled for encrypted inodes for now. This is a
* bug we should fix.... * bug we should fix....
*/ */
if (ext4_encrypted_inode(inode) && if (IS_ENCRYPTED(inode) &&
(mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE | (mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE |
FALLOC_FL_ZERO_RANGE))) FALLOC_FL_ZERO_RANGE)))
return -EOPNOTSUPP; return -EOPNOTSUPP;

View File

@ -771,7 +771,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
if (unlikely(ext4_forced_shutdown(sbi))) if (unlikely(ext4_forced_shutdown(sbi)))
return ERR_PTR(-EIO); return ERR_PTR(-EIO);
if ((ext4_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) && if ((IS_ENCRYPTED(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) && (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) &&
!(i_flags & EXT4_EA_INODE_FL)) { !(i_flags & EXT4_EA_INODE_FL)) {
err = fscrypt_get_encryption_info(dir); err = fscrypt_get_encryption_info(dir);

View File

@ -415,7 +415,7 @@ int ext4_issue_zeroout(struct inode *inode, ext4_lblk_t lblk, ext4_fsblk_t pblk,
{ {
int ret; int ret;
if (ext4_encrypted_inode(inode)) if (IS_ENCRYPTED(inode))
return fscrypt_zeroout_range(inode, lblk, pblk, len); return fscrypt_zeroout_range(inode, lblk, pblk, len);
ret = sb_issue_zeroout(inode->i_sb, pblk, len, GFP_NOFS); ret = sb_issue_zeroout(inode->i_sb, pblk, len, GFP_NOFS);
@ -1150,7 +1150,7 @@ int do_journal_get_write_access(handle_t *handle,
return ret; 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, static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len,
get_block_t *get_block) get_block_t *get_block)
{ {
@ -1217,8 +1217,7 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len,
(block_start < from || block_end > to)) { (block_start < from || block_end > to)) {
ll_rw_block(REQ_OP_READ, 0, 1, &bh); ll_rw_block(REQ_OP_READ, 0, 1, &bh);
*wait_bh++ = bh; *wait_bh++ = bh;
decrypt = ext4_encrypted_inode(inode) && decrypt = IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode);
S_ISREG(inode->i_mode);
} }
} }
/* /*
@ -1303,7 +1302,7 @@ retry_journal:
/* In case writeback began while the page was unlocked */ /* In case writeback began while the page was unlocked */
wait_for_stable_page(page); wait_for_stable_page(page);
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
if (ext4_should_dioread_nolock(inode)) if (ext4_should_dioread_nolock(inode))
ret = ext4_block_write_begin(page, pos, len, ret = ext4_block_write_begin(page, pos, len,
ext4_get_block_unwritten); ext4_get_block_unwritten);
@ -3105,7 +3104,7 @@ retry_journal:
/* In case writeback began while the page was unlocked */ /* In case writeback began while the page was unlocked */
wait_for_stable_page(page); wait_for_stable_page(page);
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
ret = ext4_block_write_begin(page, pos, len, ret = ext4_block_write_begin(page, pos, len,
ext4_da_get_block_prep); ext4_da_get_block_prep);
#else #else
@ -3880,8 +3879,8 @@ static ssize_t ext4_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
loff_t offset = iocb->ki_pos; loff_t offset = iocb->ki_pos;
ssize_t ret; ssize_t ret;
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode)) if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode))
return 0; return 0;
#endif #endif
@ -4065,8 +4064,7 @@ static int __ext4_block_zero_page_range(handle_t *handle,
/* Uhhuh. Read error. Complain and punt. */ /* Uhhuh. Read error. Complain and punt. */
if (!buffer_uptodate(bh)) if (!buffer_uptodate(bh))
goto unlock; goto unlock;
if (S_ISREG(inode->i_mode) && if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode)) {
ext4_encrypted_inode(inode)) {
/* We expect the key to be set. */ /* We expect the key to be set. */
BUG_ON(!fscrypt_has_encryption_key(inode)); BUG_ON(!fscrypt_has_encryption_key(inode));
BUG_ON(blocksize != PAGE_SIZE); BUG_ON(blocksize != PAGE_SIZE);
@ -4142,7 +4140,7 @@ static int ext4_block_truncate_page(handle_t *handle,
struct inode *inode = mapping->host; struct inode *inode = mapping->host;
/* If we are processing an encrypted inode during orphan list handling */ /* If we are processing an encrypted inode during orphan list handling */
if (ext4_encrypted_inode(inode) && !fscrypt_has_encryption_key(inode)) if (IS_ENCRYPTED(inode) && !fscrypt_has_encryption_key(inode))
return 0; return 0;
blocksize = inode->i_sb->s_blocksize; blocksize = inode->i_sb->s_blocksize;
@ -4722,7 +4720,7 @@ static bool ext4_should_use_dax(struct inode *inode)
return false; return false;
if (ext4_has_inline_data(inode)) if (ext4_has_inline_data(inode))
return false; return false;
if (ext4_encrypted_inode(inode)) if (ext4_test_inode_flag(inode, EXT4_INODE_ENCRYPT))
return false; return false;
return true; return true;
} }
@ -5072,7 +5070,7 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino,
ret = -EFSCORRUPTED; ret = -EFSCORRUPTED;
goto bad_inode; goto bad_inode;
} }
if (ext4_encrypted_inode(inode)) { if (IS_ENCRYPTED(inode)) {
inode->i_op = &ext4_encrypted_symlink_inode_operations; inode->i_op = &ext4_encrypted_symlink_inode_operations;
ext4_set_aops(inode); ext4_set_aops(inode);
} else if (ext4_inode_is_fast_symlink(inode)) { } else if (ext4_inode_is_fast_symlink(inode)) {

View File

@ -210,7 +210,7 @@ journal_err_out:
return err; return err;
} }
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
static int uuid_is_zero(__u8 u[16]) static int uuid_is_zero(__u8 u[16])
{ {
int i; int i;
@ -978,7 +978,7 @@ resizefs_out:
return fscrypt_ioctl_set_policy(filp, (const void __user *)arg); return fscrypt_ioctl_set_policy(filp, (const void __user *)arg);
case EXT4_IOC_GET_ENCRYPTION_PWSALT: { case EXT4_IOC_GET_ENCRYPTION_PWSALT: {
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
int err, err2; int err, err2;
struct ext4_sb_info *sbi = EXT4_SB(sb); struct ext4_sb_info *sbi = EXT4_SB(sb);
handle_t *handle; handle_t *handle;

View File

@ -592,8 +592,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
if (ext4_encrypted_inode(orig_inode) || if (IS_ENCRYPTED(orig_inode) || IS_ENCRYPTED(donor_inode)) {
ext4_encrypted_inode(donor_inode)) {
ext4_msg(orig_inode->i_sb, KERN_ERR, ext4_msg(orig_inode->i_sb, KERN_ERR,
"Online defrag not supported for encrypted files"); "Online defrag not supported for encrypted files");
return -EOPNOTSUPP; return -EOPNOTSUPP;

View File

@ -612,7 +612,7 @@ static struct stats dx_show_leaf(struct inode *dir,
{ {
if (show_names) if (show_names)
{ {
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
int len; int len;
char *name; char *name;
struct fscrypt_str fname_crypto_str = struct fscrypt_str fname_crypto_str =
@ -621,7 +621,7 @@ static struct stats dx_show_leaf(struct inode *dir,
name = de->name; name = de->name;
len = de->name_len; len = de->name_len;
if (ext4_encrypted_inode(dir)) if (IS_ENCRYPTED(dir))
res = fscrypt_get_encryption_info(dir); res = fscrypt_get_encryption_info(dir);
if (res) { if (res) {
printk(KERN_WARNING "Error setting up" printk(KERN_WARNING "Error setting up"
@ -984,9 +984,9 @@ static int htree_dirblock_to_tree(struct file *dir_file,
top = (struct ext4_dir_entry_2 *) ((char *) de + top = (struct ext4_dir_entry_2 *) ((char *) de +
dir->i_sb->s_blocksize - dir->i_sb->s_blocksize -
EXT4_DIR_REC_LEN(0)); EXT4_DIR_REC_LEN(0));
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
/* Check if the directory is encrypted */ /* Check if the directory is encrypted */
if (ext4_encrypted_inode(dir)) { if (IS_ENCRYPTED(dir)) {
err = fscrypt_get_encryption_info(dir); err = fscrypt_get_encryption_info(dir);
if (err < 0) { if (err < 0) {
brelse(bh); brelse(bh);
@ -1015,7 +1015,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
continue; continue;
if (de->inode == 0) if (de->inode == 0)
continue; continue;
if (!ext4_encrypted_inode(dir)) { if (!IS_ENCRYPTED(dir)) {
tmp_str.name = de->name; tmp_str.name = de->name;
tmp_str.len = de->name_len; tmp_str.len = de->name_len;
err = ext4_htree_store_dirent(dir_file, err = ext4_htree_store_dirent(dir_file,
@ -1047,7 +1047,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
} }
errout: errout:
brelse(bh); brelse(bh);
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
fscrypt_fname_free_buffer(&fname_crypto_str); fscrypt_fname_free_buffer(&fname_crypto_str);
#endif #endif
return count; return count;
@ -1267,7 +1267,7 @@ static inline bool ext4_match(const struct ext4_filename *fname,
f.usr_fname = fname->usr_fname; f.usr_fname = fname->usr_fname;
f.disk_name = fname->disk_name; f.disk_name = fname->disk_name;
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
f.crypto_buf = fname->crypto_buf; f.crypto_buf = fname->crypto_buf;
#endif #endif
return fscrypt_match_name(&f, de->name, de->name_len); return fscrypt_match_name(&f, de->name, de->name_len);
@ -1498,7 +1498,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir,
ext4_lblk_t block; ext4_lblk_t block;
int retval; int retval;
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
*res_dir = NULL; *res_dir = NULL;
#endif #endif
frame = dx_probe(fname, dir, NULL, frames); frame = dx_probe(fname, dir, NULL, frames);
@ -1578,7 +1578,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
ino); ino);
return ERR_PTR(-EFSCORRUPTED); return ERR_PTR(-EFSCORRUPTED);
} }
if (!IS_ERR(inode) && ext4_encrypted_inode(dir) && if (!IS_ERR(inode) && IS_ENCRYPTED(dir) &&
(S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) && (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
!fscrypt_has_permitted_context(dir, inode)) { !fscrypt_has_permitted_context(dir, inode)) {
ext4_warning(inode->i_sb, ext4_warning(inode->i_sb,

View File

@ -67,7 +67,7 @@ static void ext4_finish_bio(struct bio *bio)
bio_for_each_segment_all(bvec, bio, i, iter_all) { bio_for_each_segment_all(bvec, bio, i, iter_all) {
struct page *page = bvec->bv_page; struct page *page = bvec->bv_page;
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
struct page *data_page = NULL; struct page *data_page = NULL;
#endif #endif
struct buffer_head *bh, *head; struct buffer_head *bh, *head;
@ -79,7 +79,7 @@ static void ext4_finish_bio(struct bio *bio)
if (!page) if (!page)
continue; continue;
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
if (!page->mapping) { if (!page->mapping) {
/* The bounce data pages are unmapped. */ /* The bounce data pages are unmapped. */
data_page = page; data_page = page;
@ -112,7 +112,7 @@ static void ext4_finish_bio(struct bio *bio)
bit_spin_unlock(BH_Uptodate_Lock, &head->b_state); bit_spin_unlock(BH_Uptodate_Lock, &head->b_state);
local_irq_restore(flags); local_irq_restore(flags);
if (!under_io) { if (!under_io) {
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
if (data_page) if (data_page)
fscrypt_restore_control_page(data_page); fscrypt_restore_control_page(data_page);
#endif #endif
@ -478,8 +478,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
bh = head = page_buffers(page); bh = head = page_buffers(page);
if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode) && if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode) && nr_to_submit) {
nr_to_submit) {
gfp_t gfp_flags = GFP_NOFS; gfp_t gfp_flags = GFP_NOFS;
retry_encrypt: retry_encrypt:

View File

@ -49,7 +49,7 @@
static inline bool ext4_bio_encrypted(struct bio *bio) static inline bool ext4_bio_encrypted(struct bio *bio)
{ {
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
return unlikely(bio->bi_private != NULL); return unlikely(bio->bi_private != NULL);
#else #else
return false; return false;
@ -243,8 +243,7 @@ int ext4_mpage_readpages(struct address_space *mapping,
if (bio == NULL) { if (bio == NULL) {
struct fscrypt_ctx *ctx = NULL; struct fscrypt_ctx *ctx = NULL;
if (ext4_encrypted_inode(inode) && if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode)) {
S_ISREG(inode->i_mode)) {
ctx = fscrypt_get_ctx(inode, GFP_NOFS); ctx = fscrypt_get_ctx(inode, GFP_NOFS);
if (IS_ERR(ctx)) if (IS_ERR(ctx))
goto set_error_page; goto set_error_page;

View File

@ -1232,7 +1232,7 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page,
return try_to_free_buffers(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) static int ext4_get_context(struct inode *inode, void *ctx, size_t len)
{ {
return ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION, return ext4_xattr_get(inode, EXT4_XATTR_INDEX_ENCRYPTION,
@ -1922,7 +1922,7 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
*journal_ioprio = *journal_ioprio =
IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, arg); IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, arg);
} else if (token == Opt_test_dummy_encryption) { } 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; sbi->s_mount_flags |= EXT4_MF_TEST_DUMMY_ENCRYPTION;
ext4_msg(sb, KERN_WARNING, ext4_msg(sb, KERN_WARNING,
"Test dummy encryption mode enabled"); "Test dummy encryption mode enabled");
@ -4167,7 +4167,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
sb->s_op = &ext4_sops; sb->s_op = &ext4_sops;
sb->s_export_op = &ext4_export_ops; sb->s_export_op = &ext4_export_ops;
sb->s_xattr = ext4_xattr_handlers; sb->s_xattr = ext4_xattr_handlers;
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
sb->s_cop = &ext4_cryptops; sb->s_cop = &ext4_cryptops;
#endif #endif
#ifdef CONFIG_QUOTA #ifdef CONFIG_QUOTA

View File

@ -224,7 +224,7 @@ static struct attribute *ext4_attrs[] = {
EXT4_ATTR_FEATURE(lazy_itable_init); EXT4_ATTR_FEATURE(lazy_itable_init);
EXT4_ATTR_FEATURE(batched_discard); EXT4_ATTR_FEATURE(batched_discard);
EXT4_ATTR_FEATURE(meta_bg_resize); EXT4_ATTR_FEATURE(meta_bg_resize);
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
EXT4_ATTR_FEATURE(encryption); EXT4_ATTR_FEATURE(encryption);
#endif #endif
EXT4_ATTR_FEATURE(metadata_csum_seed); EXT4_ATTR_FEATURE(metadata_csum_seed);
@ -233,7 +233,7 @@ static struct attribute *ext4_feat_attrs[] = {
ATTR_LIST(lazy_itable_init), ATTR_LIST(lazy_itable_init),
ATTR_LIST(batched_discard), ATTR_LIST(batched_discard),
ATTR_LIST(meta_bg_resize), ATTR_LIST(meta_bg_resize),
#ifdef CONFIG_EXT4_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
ATTR_LIST(encryption), ATTR_LIST(encryption),
#endif #endif
ATTR_LIST(metadata_csum_seed), ATTR_LIST(metadata_csum_seed),

View File

@ -3,6 +3,7 @@ config F2FS_FS
depends on BLOCK depends on BLOCK
select CRYPTO select CRYPTO
select CRYPTO_CRC32 select CRYPTO_CRC32
select F2FS_FS_XATTR if FS_ENCRYPTION
help help
F2FS is based on Log-structured File System (LFS), which supports F2FS is based on Log-structured File System (LFS), which supports
versatile "flash-friendly" features. The design has been focused on versatile "flash-friendly" features. The design has been focused on
@ -70,17 +71,6 @@ config F2FS_CHECK_FS
If you want to improve the performance, say N. 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_IO_TRACE config F2FS_IO_TRACE
bool "F2FS IO tracer" bool "F2FS IO tracer"
depends on F2FS_FS depends on F2FS_FS

View File

@ -1468,7 +1468,7 @@ next:
} }
if (size) { if (size) {
if (f2fs_encrypted_inode(inode)) if (IS_ENCRYPTED(inode))
flags |= FIEMAP_EXTENT_DATA_ENCRYPTED; flags |= FIEMAP_EXTENT_DATA_ENCRYPTED;
ret = fiemap_fill_next_extent(fieinfo, logical, ret = fiemap_fill_next_extent(fieinfo, logical,
@ -1739,7 +1739,7 @@ static inline bool check_inplace_update_policy(struct inode *inode,
if (policy & (0x1 << F2FS_IPU_ASYNC) && if (policy & (0x1 << F2FS_IPU_ASYNC) &&
fio && fio->op == REQ_OP_WRITE && fio && fio->op == REQ_OP_WRITE &&
!(fio->op_flags & REQ_SYNC) && !(fio->op_flags & REQ_SYNC) &&
!f2fs_encrypted_inode(inode)) !IS_ENCRYPTED(inode))
return true; return true;
/* this is only set during fdatasync */ /* this is only set during fdatasync */

View File

@ -385,7 +385,7 @@ struct page *f2fs_init_inode_metadata(struct inode *inode, struct inode *dir,
if (err) if (err)
goto put_error; goto put_error;
if ((f2fs_encrypted_inode(dir) || dummy_encrypt) && if ((IS_ENCRYPTED(dir) || dummy_encrypt) &&
f2fs_may_encrypt(inode)) { f2fs_may_encrypt(inode)) {
err = fscrypt_inherit_context(dir, inode, page, false); err = fscrypt_inherit_context(dir, inode, page, false);
if (err) if (err)
@ -399,7 +399,7 @@ struct page *f2fs_init_inode_metadata(struct inode *inode, struct inode *dir,
if (new_name) { if (new_name) {
init_dent_inode(new_name, page); init_dent_inode(new_name, page);
if (f2fs_encrypted_inode(dir)) if (IS_ENCRYPTED(dir))
file_set_enc_name(inode); file_set_enc_name(inode);
} }
@ -819,7 +819,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
goto out; goto out;
} }
if (f2fs_encrypted_inode(d->inode)) { if (IS_ENCRYPTED(d->inode)) {
int save_len = fstr->len; int save_len = fstr->len;
err = fscrypt_fname_disk_to_usr(d->inode, err = fscrypt_fname_disk_to_usr(d->inode,
@ -862,7 +862,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
struct fscrypt_str fstr = FSTR_INIT(NULL, 0); struct fscrypt_str fstr = FSTR_INIT(NULL, 0);
int err = 0; int err = 0;
if (f2fs_encrypted_inode(inode)) { if (IS_ENCRYPTED(inode)) {
err = fscrypt_get_encryption_info(inode); err = fscrypt_get_encryption_info(inode);
if (err && err != -ENOKEY) if (err && err != -ENOKEY)
goto out; goto out;
@ -924,7 +924,7 @@ out:
static int f2fs_dir_open(struct inode *inode, struct file *filp) static int f2fs_dir_open(struct inode *inode, struct file *filp)
{ {
if (f2fs_encrypted_inode(inode)) if (IS_ENCRYPTED(inode))
return fscrypt_get_encryption_info(inode) ? -EACCES : 0; return fscrypt_get_encryption_info(inode) ? -EACCES : 0;
return 0; return 0;
} }

View File

@ -24,7 +24,6 @@
#include <linux/quotaops.h> #include <linux/quotaops.h>
#include <crypto/hash.h> #include <crypto/hash.h>
#define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_F2FS_FS_ENCRYPTION)
#include <linux/fscrypt.h> #include <linux/fscrypt.h>
#ifdef CONFIG_F2FS_CHECK_FS #ifdef CONFIG_F2FS_CHECK_FS
@ -1137,7 +1136,7 @@ enum fsync_mode {
FSYNC_MODE_NOBARRIER, /* fsync behaves nobarrier based on posix */ FSYNC_MODE_NOBARRIER, /* fsync behaves nobarrier based on posix */
}; };
#ifdef CONFIG_F2FS_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
#define DUMMY_ENCRYPTION_ENABLED(sbi) \ #define DUMMY_ENCRYPTION_ENABLED(sbi) \
(unlikely(F2FS_OPTION(sbi).test_dummy_encryption)) (unlikely(F2FS_OPTION(sbi).test_dummy_encryption))
#else #else
@ -3463,19 +3462,14 @@ void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi);
/* /*
* crypto support * crypto support
*/ */
static inline bool f2fs_encrypted_inode(struct inode *inode)
{
return file_is_encrypt(inode);
}
static inline bool f2fs_encrypted_file(struct inode *inode) static inline bool f2fs_encrypted_file(struct inode *inode)
{ {
return f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode); return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode);
} }
static inline void f2fs_set_encrypted_inode(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); file_set_encrypt(inode);
f2fs_set_inode_flags(inode); f2fs_set_inode_flags(inode);
#endif #endif
@ -3554,7 +3548,7 @@ static inline void set_opt_mode(struct f2fs_sb_info *sbi, unsigned int mt)
static inline bool f2fs_may_encrypt(struct inode *inode) static inline bool f2fs_may_encrypt(struct inode *inode)
{ {
#ifdef CONFIG_F2FS_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
umode_t mode = inode->i_mode; umode_t mode = inode->i_mode;
return (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)); return (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode));

View File

@ -582,7 +582,7 @@ truncate_out:
zero_user(page, offset, PAGE_SIZE - offset); zero_user(page, offset, PAGE_SIZE - offset);
/* An encrypted inode should have a key and truncate the last page. */ /* An encrypted inode should have a key and truncate the last page. */
f2fs_bug_on(F2FS_I_SB(inode), cache_only && f2fs_encrypted_inode(inode)); f2fs_bug_on(F2FS_I_SB(inode), cache_only && IS_ENCRYPTED(inode));
if (!cache_only) if (!cache_only)
set_page_dirty(page); set_page_dirty(page);
f2fs_put_page(page, 1); f2fs_put_page(page, 1);
@ -711,7 +711,7 @@ int f2fs_getattr(const struct path *path, struct kstat *stat,
stat->attributes |= STATX_ATTR_APPEND; stat->attributes |= STATX_ATTR_APPEND;
if (flags & F2FS_COMPR_FL) if (flags & F2FS_COMPR_FL)
stat->attributes |= STATX_ATTR_COMPRESSED; stat->attributes |= STATX_ATTR_COMPRESSED;
if (f2fs_encrypted_inode(inode)) if (IS_ENCRYPTED(inode))
stat->attributes |= STATX_ATTR_ENCRYPTED; stat->attributes |= STATX_ATTR_ENCRYPTED;
if (flags & F2FS_IMMUTABLE_FL) if (flags & F2FS_IMMUTABLE_FL)
stat->attributes |= STATX_ATTR_IMMUTABLE; stat->attributes |= STATX_ATTR_IMMUTABLE;
@ -1563,7 +1563,7 @@ static long f2fs_fallocate(struct file *file, int mode,
if (!S_ISREG(inode->i_mode)) if (!S_ISREG(inode->i_mode))
return -EINVAL; return -EINVAL;
if (f2fs_encrypted_inode(inode) && if (IS_ENCRYPTED(inode) &&
(mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE))) (mode & (FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_INSERT_RANGE)))
return -EOPNOTSUPP; return -EOPNOTSUPP;
@ -1647,7 +1647,7 @@ static int f2fs_ioc_getflags(struct file *filp, unsigned long arg)
struct f2fs_inode_info *fi = F2FS_I(inode); struct f2fs_inode_info *fi = F2FS_I(inode);
unsigned int flags = fi->i_flags; unsigned int flags = fi->i_flags;
if (f2fs_encrypted_inode(inode)) if (IS_ENCRYPTED(inode))
flags |= F2FS_ENCRYPT_FL; flags |= F2FS_ENCRYPT_FL;
if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode)) if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode))
flags |= F2FS_INLINE_DATA_FL; flags |= F2FS_INLINE_DATA_FL;
@ -2414,7 +2414,7 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in,
if (!S_ISREG(src->i_mode) || !S_ISREG(dst->i_mode)) if (!S_ISREG(src->i_mode) || !S_ISREG(dst->i_mode))
return -EINVAL; return -EINVAL;
if (f2fs_encrypted_inode(src) || f2fs_encrypted_inode(dst)) if (IS_ENCRYPTED(src) || IS_ENCRYPTED(dst))
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (src == dst) { if (src == dst) {

View File

@ -43,7 +43,7 @@ void f2fs_set_inode_flags(struct inode *inode)
new_fl |= S_NOATIME; new_fl |= S_NOATIME;
if (flags & F2FS_DIRSYNC_FL) if (flags & F2FS_DIRSYNC_FL)
new_fl |= S_DIRSYNC; new_fl |= S_DIRSYNC;
if (f2fs_encrypted_inode(inode)) if (file_is_encrypt(inode))
new_fl |= S_ENCRYPTED; new_fl |= S_ENCRYPTED;
inode_set_flags(inode, new_fl, inode_set_flags(inode, new_fl,
S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC| S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|
@ -453,7 +453,7 @@ make_now:
inode->i_mapping->a_ops = &f2fs_dblock_aops; inode->i_mapping->a_ops = &f2fs_dblock_aops;
inode_nohighmem(inode); inode_nohighmem(inode);
} else if (S_ISLNK(inode->i_mode)) { } else if (S_ISLNK(inode->i_mode)) {
if (f2fs_encrypted_inode(inode)) if (file_is_encrypt(inode))
inode->i_op = &f2fs_encrypted_symlink_inode_operations; inode->i_op = &f2fs_encrypted_symlink_inode_operations;
else else
inode->i_op = &f2fs_symlink_inode_operations; inode->i_op = &f2fs_symlink_inode_operations;

View File

@ -75,7 +75,7 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
set_inode_flag(inode, FI_NEW_INODE); set_inode_flag(inode, FI_NEW_INODE);
/* If the directory encrypted, then we should encrypt the inode. */ /* If the directory encrypted, then we should encrypt the inode. */
if ((f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) && if ((IS_ENCRYPTED(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
f2fs_may_encrypt(inode)) f2fs_may_encrypt(inode))
f2fs_set_encrypted_inode(inode); f2fs_set_encrypted_inode(inode);
@ -476,7 +476,7 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
if (err) if (err)
goto out_iput; goto out_iput;
} }
if (f2fs_encrypted_inode(dir) && if (IS_ENCRYPTED(dir) &&
(S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) && (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
!fscrypt_has_permitted_context(dir, inode)) { !fscrypt_has_permitted_context(dir, inode)) {
f2fs_msg(inode->i_sb, KERN_WARNING, f2fs_msg(inode->i_sb, KERN_WARNING,
@ -803,7 +803,7 @@ static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
if (unlikely(f2fs_cp_error(sbi))) if (unlikely(f2fs_cp_error(sbi)))
return -EIO; return -EIO;
if (f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) { if (IS_ENCRYPTED(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) {
int err = fscrypt_get_encryption_info(dir); int err = fscrypt_get_encryption_info(dir);
if (err) if (err)
return err; return err;

View File

@ -757,7 +757,7 @@ static int parse_options(struct super_block *sb, char *options)
kvfree(name); kvfree(name);
break; break;
case Opt_test_dummy_encryption: case Opt_test_dummy_encryption:
#ifdef CONFIG_F2FS_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
if (!f2fs_sb_has_encrypt(sbi)) { if (!f2fs_sb_has_encrypt(sbi)) {
f2fs_msg(sb, KERN_ERR, "Encrypt feature is off"); f2fs_msg(sb, KERN_ERR, "Encrypt feature is off");
return -EINVAL; return -EINVAL;
@ -1390,7 +1390,7 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
seq_printf(seq, ",whint_mode=%s", "user-based"); seq_printf(seq, ",whint_mode=%s", "user-based");
else if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_FS) else if (F2FS_OPTION(sbi).whint_mode == WHINT_MODE_FS)
seq_printf(seq, ",whint_mode=%s", "fs-based"); seq_printf(seq, ",whint_mode=%s", "fs-based");
#ifdef CONFIG_F2FS_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
if (F2FS_OPTION(sbi).test_dummy_encryption) if (F2FS_OPTION(sbi).test_dummy_encryption)
seq_puts(seq, ",test_dummy_encryption"); seq_puts(seq, ",test_dummy_encryption");
#endif #endif
@ -2154,7 +2154,7 @@ static const struct super_operations f2fs_sops = {
.remount_fs = f2fs_remount, .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) static int f2fs_get_context(struct inode *inode, void *ctx, size_t len)
{ {
return f2fs_getxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION, return f2fs_getxattr(inode, F2FS_XATTR_INDEX_ENCRYPTION,
@ -3116,7 +3116,7 @@ try_onemore:
#endif #endif
sb->s_op = &f2fs_sops; sb->s_op = &f2fs_sops;
#ifdef CONFIG_F2FS_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
sb->s_cop = &f2fs_cryptops; sb->s_cop = &f2fs_cryptops;
#endif #endif
sb->s_xattr = f2fs_xattr_handlers; sb->s_xattr = f2fs_xattr_handlers;

View File

@ -431,7 +431,7 @@ F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes);
F2FS_GENERAL_RO_ATTR(features); F2FS_GENERAL_RO_ATTR(features);
F2FS_GENERAL_RO_ATTR(current_reserved_blocks); F2FS_GENERAL_RO_ATTR(current_reserved_blocks);
#ifdef CONFIG_F2FS_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO); F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO);
#endif #endif
#ifdef CONFIG_BLK_DEV_ZONED #ifdef CONFIG_BLK_DEV_ZONED
@ -492,7 +492,7 @@ static struct attribute *f2fs_attrs[] = {
}; };
static struct attribute *f2fs_feat_attrs[] = { static struct attribute *f2fs_feat_attrs[] = {
#ifdef CONFIG_F2FS_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
ATTR_LIST(encryption), ATTR_LIST(encryption),
#endif #endif
#ifdef CONFIG_BLK_DEV_ZONED #ifdef CONFIG_BLK_DEV_ZONED

View File

@ -8,6 +8,7 @@ config UBIFS_FS
select CRYPTO_LZO if UBIFS_FS_LZO select CRYPTO_LZO if UBIFS_FS_LZO
select CRYPTO_DEFLATE if UBIFS_FS_ZLIB select CRYPTO_DEFLATE if UBIFS_FS_ZLIB
select CRYPTO_HASH_INFO select CRYPTO_HASH_INFO
select UBIFS_FS_XATTR if FS_ENCRYPTION
depends on MTD_UBI depends on MTD_UBI
help help
UBIFS is a file system for flash devices which works on top of UBI. UBIFS is a file system for flash devices which works on top of UBI.
@ -60,17 +61,6 @@ config UBIFS_FS_XATTR
If unsure, say Y. If unsure, say Y.
config UBIFS_FS_ENCRYPTION
bool "UBIFS Encryption"
depends on UBIFS_FS_XATTR && BLOCK
select FS_ENCRYPTION
default n
help
Enable encryption of UBIFS files and directories. This
feature is similar to ecryptfs, but it is more memory
efficient since it avoids caching the encrypted and
decrypted pages in the page cache.
config UBIFS_FS_SECURITY config UBIFS_FS_SECURITY
bool "UBIFS Security Labels" bool "UBIFS Security Labels"
depends on UBIFS_FS_XATTR depends on UBIFS_FS_XATTR

View File

@ -6,6 +6,6 @@ ubifs-y += tnc.o master.o scan.o replay.o log.o commit.o gc.o orphan.o
ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o
ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o debug.o ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o debug.o
ubifs-y += misc.o ubifs-y += misc.o
ubifs-$(CONFIG_UBIFS_FS_ENCRYPTION) += crypto.o ubifs-$(CONFIG_FS_ENCRYPTION) += crypto.o
ubifs-$(CONFIG_UBIFS_FS_XATTR) += xattr.o ubifs-$(CONFIG_UBIFS_FS_XATTR) += xattr.o
ubifs-$(CONFIG_UBIFS_FS_AUTHENTICATION) += auth.o ubifs-$(CONFIG_UBIFS_FS_AUTHENTICATION) += auth.o

View File

@ -185,7 +185,7 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return err; return err;
} }
case FS_IOC_SET_ENCRYPTION_POLICY: { case FS_IOC_SET_ENCRYPTION_POLICY: {
#ifdef CONFIG_UBIFS_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
struct ubifs_info *c = inode->i_sb->s_fs_info; struct ubifs_info *c = inode->i_sb->s_fs_info;
err = ubifs_enable_encryption(c); err = ubifs_enable_encryption(c);
@ -198,7 +198,7 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
#endif #endif
} }
case FS_IOC_GET_ENCRYPTION_POLICY: { case FS_IOC_GET_ENCRYPTION_POLICY: {
#ifdef CONFIG_UBIFS_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
return fscrypt_ioctl_get_policy(file, (void __user *)arg); return fscrypt_ioctl_get_policy(file, (void __user *)arg);
#else #else
return -EOPNOTSUPP; return -EOPNOTSUPP;

View File

@ -748,7 +748,7 @@ int ubifs_read_superblock(struct ubifs_info *c)
goto out; goto out;
} }
#ifndef CONFIG_UBIFS_FS_ENCRYPTION #ifndef CONFIG_FS_ENCRYPTION
if (c->encrypted) { if (c->encrypted) {
ubifs_err(c, "file system contains encrypted files but UBIFS" ubifs_err(c, "file system contains encrypted files but UBIFS"
" was built without crypto support."); " was built without crypto support.");

View File

@ -2146,7 +2146,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
#ifdef CONFIG_UBIFS_FS_XATTR #ifdef CONFIG_UBIFS_FS_XATTR
sb->s_xattr = ubifs_xattr_handlers; sb->s_xattr = ubifs_xattr_handlers;
#endif #endif
#ifdef CONFIG_UBIFS_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
sb->s_cop = &ubifs_crypt_operations; sb->s_cop = &ubifs_crypt_operations;
#endif #endif

View File

@ -43,7 +43,6 @@
#include <crypto/hash.h> #include <crypto/hash.h>
#include <crypto/algapi.h> #include <crypto/algapi.h>
#define __FS_HAS_ENCRYPTION IS_ENABLED(CONFIG_UBIFS_FS_ENCRYPTION)
#include <linux/fscrypt.h> #include <linux/fscrypt.h>
#include "ubifs-media.h" #include "ubifs-media.h"
@ -142,7 +141,7 @@
*/ */
#define WORST_COMPR_FACTOR 2 #define WORST_COMPR_FACTOR 2
#ifdef CONFIG_UBIFS_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
#define UBIFS_CIPHER_BLOCK_SIZE FS_CRYPTO_BLOCK_SIZE #define UBIFS_CIPHER_BLOCK_SIZE FS_CRYPTO_BLOCK_SIZE
#else #else
#define UBIFS_CIPHER_BLOCK_SIZE 0 #define UBIFS_CIPHER_BLOCK_SIZE 0
@ -2072,7 +2071,7 @@ int ubifs_decompress(const struct ubifs_info *c, const void *buf, int len,
#include "misc.h" #include "misc.h"
#include "key.h" #include "key.h"
#ifndef CONFIG_UBIFS_FS_ENCRYPTION #ifndef CONFIG_FS_ENCRYPTION
static inline int ubifs_encrypt(const struct inode *inode, static inline int ubifs_encrypt(const struct inode *inode,
struct ubifs_data_node *dn, struct ubifs_data_node *dn,
unsigned int in_len, unsigned int *out_len, unsigned int in_len, unsigned int *out_len,

View File

@ -708,7 +708,7 @@ struct inode {
struct fsnotify_mark_connector __rcu *i_fsnotify_marks; struct fsnotify_mark_connector __rcu *i_fsnotify_marks;
#endif #endif
#if IS_ENABLED(CONFIG_FS_ENCRYPTION) #ifdef CONFIG_FS_ENCRYPTION
struct fscrypt_info *i_crypt_info; struct fscrypt_info *i_crypt_info;
#endif #endif
@ -1415,7 +1415,7 @@ struct super_block {
void *s_security; void *s_security;
#endif #endif
const struct xattr_handler **s_xattr; const struct xattr_handler **s_xattr;
#if IS_ENABLED(CONFIG_FS_ENCRYPTION) #ifdef CONFIG_FS_ENCRYPTION
const struct fscrypt_operations *s_cop; const struct fscrypt_operations *s_cop;
#endif #endif
struct hlist_bl_head s_roots; /* alternate root dentries for NFS */ struct hlist_bl_head s_roots; /* alternate root dentries for NFS */

View File

@ -2,9 +2,8 @@
/* /*
* fscrypt.h: declarations for per-file encryption * fscrypt.h: declarations for per-file encryption
* *
* Filesystems that implement per-file encryption include this header * Filesystems that implement per-file encryption must include this header
* file with the __FS_HAS_ENCRYPTION set according to whether that filesystem * file.
* is being built with encryption support or not.
* *
* Copyright (C) 2015, Google, Inc. * Copyright (C) 2015, Google, Inc.
* *
@ -15,6 +14,8 @@
#define _LINUX_FSCRYPT_H #define _LINUX_FSCRYPT_H
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/mm.h>
#include <linux/slab.h>
#define FS_CRYPTO_BLOCK_SIZE 16 #define FS_CRYPTO_BLOCK_SIZE 16
@ -42,11 +43,410 @@ struct fscrypt_name {
/* Maximum value for the third parameter of fscrypt_operations.set_context(). */ /* Maximum value for the third parameter of fscrypt_operations.set_context(). */
#define FSCRYPT_SET_CONTEXT_MAX_SIZE 28 #define FSCRYPT_SET_CONTEXT_MAX_SIZE 28
#if __FS_HAS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
#include <linux/fscrypt_supp.h> /*
#else * fscrypt superblock flags
#include <linux/fscrypt_notsupp.h> */
#endif #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 * fscrypt_require_key - require an inode's encryption key
@ -89,7 +489,7 @@ static inline int fscrypt_require_key(struct inode *inode)
* in an encrypted directory tree use the same encryption policy. * in an encrypted directory tree use the same encryption policy.
* *
* Return: 0 on success, -ENOKEY if the directory's encryption key is missing, * Return: 0 on success, -ENOKEY if the directory's encryption key is missing,
* -EPERM if the link would result in an inconsistent encryption policy, or * -EXDEV if the link would result in an inconsistent encryption policy, or
* another -errno code. * another -errno code.
*/ */
static inline int fscrypt_prepare_link(struct dentry *old_dentry, static inline int fscrypt_prepare_link(struct dentry *old_dentry,
@ -119,7 +519,7 @@ static inline int fscrypt_prepare_link(struct dentry *old_dentry,
* We also verify that the rename will not violate the constraint that all files * We also verify that the rename will not violate the constraint that all files
* in an encrypted directory tree use the same encryption policy. * in an encrypted directory tree use the same encryption policy.
* *
* Return: 0 on success, -ENOKEY if an encryption key is missing, -EPERM if the * Return: 0 on success, -ENOKEY if an encryption key is missing, -EXDEV if the
* rename would cause inconsistent encryption policies, or another -errno code. * rename would cause inconsistent encryption policies, or another -errno code.
*/ */
static inline int fscrypt_prepare_rename(struct inode *old_dir, static inline int fscrypt_prepare_rename(struct inode *old_dir,

View File

@ -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 */

View File

@ -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 */