Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 30 Jan 2020 23:17:05 +0000 (15:17 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 30 Jan 2020 23:17:05 +0000 (15:17 -0800)
Pull ext4 updates from Ted Ts'o:
 "This merge window, we've added some performance improvements in how we
  handle inode locking in the read/write paths, and improving the
  performance of Direct I/O overwrites.

  We also now record the error code which caused the first and most
  recent ext4_error() report in the superblock, to make it easier to
  root cause problems in production systems.

  There are also many of the usual cleanups and miscellaneous bug fixes"

* tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (49 commits)
  jbd2: clean __jbd2_journal_abort_hard() and __journal_abort_soft()
  jbd2: make sure ESHUTDOWN to be recorded in the journal superblock
  ext4, jbd2: ensure panic when aborting with zero errno
  jbd2: switch to use jbd2_journal_abort() when failed to submit the commit record
  jbd2_seq_info_next should increase position index
  jbd2: remove pointless assertion in __journal_remove_journal_head
  ext4,jbd2: fix comment and code style
  jbd2: delete the duplicated words in the comments
  ext4: fix extent_status trace points
  ext4: fix symbolic enum printing in trace output
  ext4: choose hardlimit when softlimit is larger than hardlimit in ext4_statfs_project()
  ext4: fix race conditions in ->d_compare() and ->d_hash()
  ext4: make dioread_nolock the default
  ext4: fix extent_status fragmentation for plain files
  jbd2: clear JBD2_ABORT flag before journal_reset to update log tail info when load journal
  ext4: drop ext4_kvmalloc()
  ext4: Add EXT4_IOC_FSGETXATTR/EXT4_IOC_FSSETXATTR to compat_ioctl
  ext4: remove unused macro MPAGE_DA_EXTENT_TAIL
  ext4: add missing braces in ext4_ext_drop_refs()
  ext4: fix some nonstandard indentation in extents.c
  ...

1  2 
Documentation/filesystems/fscrypt.rst
fs/ext4/Kconfig
fs/ext4/dir.c

@@@ -234,8 -234,8 +234,8 @@@ HKDF is more flexible, is nonreversible
  entropy from the master key.  HKDF is also standardized and widely
  used by other software, whereas the AES-128-ECB based KDF is ad-hoc.
  
 -Per-file keys
 --------------
 +Per-file encryption keys
 +------------------------
  
  Since each master key can protect many files, it is necessary to
  "tweak" the encryption of each file so that the same plaintext in two
@@@ -268,9 -268,9 +268,9 @@@ is greater than that of an AES-256-XTS 
  Therefore, to improve performance and save memory, for Adiantum a
  "direct key" configuration is supported.  When the user has enabled
  this by setting FSCRYPT_POLICY_FLAG_DIRECT_KEY in the fscrypt policy,
 -per-file keys are not used.  Instead, whenever any data (contents or
 -filenames) is encrypted, the file's 16-byte nonce is included in the
 -IV.  Moreover:
 +per-file encryption keys are not used.  Instead, whenever any data
 +(contents or filenames) is encrypted, the file's 16-byte nonce is
 +included in the IV.  Moreover:
  
  - For v1 encryption policies, the encryption is done directly with the
    master key.  Because of this, users **must not** use the same master
@@@ -302,16 -302,6 +302,16 @@@ For master keys used for v2 encryption 
  identifier" is also derived using the KDF.  This value is stored in
  the clear, since it is needed to reliably identify the key itself.
  
 +Dirhash keys
 +------------
 +
 +For directories that are indexed using a secret-keyed dirhash over the
 +plaintext filenames, the KDF is also used to derive a 128-bit
 +SipHash-2-4 key per directory in order to hash filenames.  This works
 +just like deriving a per-file encryption key, except that a different
 +KDF context is used.  Currently, only casefolded ("case-insensitive")
 +encrypted directories use this style of hashing.
 +
  Encryption modes and usage
  ==========================
  
@@@ -335,11 -325,11 +335,11 @@@ used
  Adiantum is a (primarily) stream cipher-based mode that is fast even
  on CPUs without dedicated crypto instructions.  It's also a true
  wide-block mode, unlike XTS.  It can also eliminate the need to derive
 -per-file keys.  However, it depends on the security of two primitives,
 -XChaCha12 and AES-256, rather than just one.  See the paper
 -"Adiantum: length-preserving encryption for entry-level processors"
 -(https://eprint.iacr.org/2018/720.pdf) for more details.  To use
 -Adiantum, CONFIG_CRYPTO_ADIANTUM must be enabled.  Also, fast
 +per-file encryption keys.  However, it depends on the security of two
 +primitives, XChaCha12 and AES-256, rather than just one.  See the
 +paper "Adiantum: length-preserving encryption for entry-level
 +processors" (https://eprint.iacr.org/2018/720.pdf) for more details.
 +To use Adiantum, CONFIG_CRYPTO_ADIANTUM must be enabled.  Also, fast
  implementations of ChaCha and NHPoly1305 should be enabled, e.g.
  CONFIG_CRYPTO_CHACHA20_NEON and CONFIG_CRYPTO_NHPOLY1305_NEON for ARM.
  
@@@ -523,9 -513,7 +523,9 @@@ FS_IOC_SET_ENCRYPTION_POLICY can fail w
  - ``EEXIST``: the file is already encrypted with an encryption policy
    different from the one specified
  - ``EINVAL``: an invalid encryption policy was specified (invalid
 -  version, mode(s), or flags; or reserved bits were set)
 +  version, mode(s), or flags; or reserved bits were set); or a v1
 +  encryption policy was specified but the directory has the casefold
 +  flag enabled (casefolding is incompatible with v1 policies).
  - ``ENOKEY``: a v2 encryption policy was specified, but the key with
    the specified ``master_key_identifier`` has not been added, nor does
    the process have the CAP_FOWNER capability in the initial user
@@@ -650,8 -638,7 +650,8 @@@ follows:
      struct fscrypt_add_key_arg {
              struct fscrypt_key_specifier key_spec;
              __u32 raw_size;
 -            __u32 __reserved[9];
 +            __u32 key_id;
 +            __u32 __reserved[8];
              __u8 raw[];
      };
  
              } u;
      };
  
 +    struct fscrypt_provisioning_key_payload {
 +            __u32 type;
 +            __u32 __reserved;
 +            __u8 raw[];
 +    };
 +
  :c:type:`struct fscrypt_add_key_arg` must be zeroed, then initialized
  as follows:
  
    ``Documentation/security/keys/core.rst``).
  
  - ``raw_size`` must be the size of the ``raw`` key provided, in bytes.
 +  Alternatively, if ``key_id`` is nonzero, this field must be 0, since
 +  in that case the size is implied by the specified Linux keyring key.
 +
 +- ``key_id`` is 0 if the raw key is given directly in the ``raw``
 +  field.  Otherwise ``key_id`` is the ID of a Linux keyring key of
 +  type "fscrypt-provisioning" whose payload is a :c:type:`struct
 +  fscrypt_provisioning_key_payload` whose ``raw`` field contains the
 +  raw key and whose ``type`` field matches ``key_spec.type``.  Since
 +  ``raw`` is variable-length, the total size of this key's payload
 +  must be ``sizeof(struct fscrypt_provisioning_key_payload)`` plus the
 +  raw key size.  The process must have Search permission on this key.
 +
 +  Most users should leave this 0 and specify the raw key directly.
 +  The support for specifying a Linux keyring key is intended mainly to
 +  allow re-adding keys after a filesystem is unmounted and re-mounted,
 +  without having to store the raw keys in userspace memory.
  
  - ``raw`` is a variable-length field which must contain the actual
 -  key, ``raw_size`` bytes long.
 +  key, ``raw_size`` bytes long.  Alternatively, if ``key_id`` is
 +  nonzero, then this field is unused.
  
  For v2 policy keys, the kernel keeps track of which user (identified
  by effective user ID) added the key, and only allows the key to be
@@@ -737,16 -701,11 +737,16 @@@ FS_IOC_ADD_ENCRYPTION_KEY can fail wit
  
  - ``EACCES``: FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR was specified, but the
    caller does not have the CAP_SYS_ADMIN capability in the initial
 -  user namespace
 +  user namespace; or the raw key was specified by Linux key ID but the
 +  process lacks Search permission on the key.
  - ``EDQUOT``: the key quota for this user would be exceeded by adding
    the key
  - ``EINVAL``: invalid key size or key specifier type, or reserved bits
    were set
 +- ``EKEYREJECTED``: the raw key was specified by Linux key ID, but the
 +  key has the wrong type
 +- ``ENOKEY``: the raw key was specified by Linux key ID, but no key
 +  exists with that ID
  - ``ENOTTY``: this type of filesystem does not implement encryption
  - ``EOPNOTSUPP``: the kernel was not configured with encryption
    support for this filesystem, or the filesystem superblock has not
@@@ -1016,9 -975,9 +1016,9 @@@ astute users may notice some difference
  - 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.
  
- - The fallocate operations FALLOC_FL_COLLAPSE_RANGE,
-   FALLOC_FL_INSERT_RANGE, and FALLOC_FL_ZERO_RANGE are not supported
-   on encrypted files and will fail with EOPNOTSUPP.
+ - The fallocate operations FALLOC_FL_COLLAPSE_RANGE and
+   FALLOC_FL_INSERT_RANGE are not supported on encrypted files and will
+   fail with EOPNOTSUPP.
  
  - Online defragmentation of encrypted files is not supported.  The
    EXT4_IOC_MOVE_EXT and F2FS_IOC_MOVE_RANGE ioctls will fail with
@@@ -1149,8 -1108,8 +1149,8 @@@ The context structs contain the same in
  policy structs (see `Setting an encryption policy`_), except that the
  context structs also contain a nonce.  The nonce is randomly generated
  by the kernel and is used as KDF input or as a tweak to cause
 -different files to be encrypted differently; see `Per-file keys`_ and
 -`DIRECT_KEY policies`_.
 +different files to be encrypted differently; see `Per-file encryption
 +keys`_ and `DIRECT_KEY policies`_.
  
  Data path changes
  -----------------
@@@ -1202,7 -1161,7 +1202,7 @@@ filesystem-specific hash(es) needed fo
  allows the filesystem to still, with a high degree of confidence, map
  the filename given in ->lookup() back to a particular directory entry
  that was previously listed by readdir().  See :c:type:`struct
 -fscrypt_digested_name` in the source for more details.
 +fscrypt_nokey_name` in the source for more details.
  
  Note that the precise way that filenames are presented to userspace
  without the key is subject to change in the future.  It is only meant
diff --combined fs/ext4/Kconfig
@@@ -4,12 -4,7 +4,7 @@@
  # kernels after the removal of ext3 driver.
  config EXT3_FS
        tristate "The Extended 3 (ext3) filesystem"
-       # These must match EXT4_FS selects...
        select EXT4_FS
-       select JBD2
-       select CRC16
-       select CRYPTO
-       select CRYPTO_CRC32C
        help
          This config option is here only for backward compatibility. ext3
          filesystem is now handled by the ext4 driver.
@@@ -33,13 -28,11 +28,12 @@@ config EXT3_FS_SECURIT
  
  config EXT4_FS
        tristate "The Extended 4 (ext4) filesystem"
-       # Please update EXT3_FS selects when changing these
        select JBD2
        select CRC16
        select CRYPTO
        select CRYPTO_CRC32C
        select FS_IOMAP
 +      select FS_ENCRYPTION_ALGS if FS_ENCRYPTION
        help
          This is the next generation of the ext3 filesystem.
  
@@@ -109,7 -102,7 +103,7 @@@ config EXT4_DEBU
                echo 1 > /sys/module/ext4/parameters/mballoc_debug
  
  config EXT4_KUNIT_TESTS
 -      bool "KUnit tests for ext4"
 +      tristate "KUnit tests for ext4"
        select EXT4_FS
        depends on KUNIT
        help
diff --combined fs/ext4/dir.c
@@@ -120,7 -120,7 +120,7 @@@ static int ext4_readdir(struct file *fi
  
        if (IS_ENCRYPTED(inode)) {
                err = fscrypt_get_encryption_info(inode);
 -              if (err && err != -ENOKEY)
 +              if (err)
                        return err;
        }
  
@@@ -462,7 -462,6 +462,6 @@@ int ext4_htree_store_dirent(struct fil
        new_fn->name_len = ent_name->len;
        new_fn->file_type = dirent->file_type;
        memcpy(new_fn->name, ent_name->name, ent_name->len);
-       new_fn->name[ent_name->len] = 0;
  
        while (*p) {
                parent = *p;
@@@ -672,9 -671,11 +671,11 @@@ static int ext4_d_compare(const struct 
                          const char *str, const struct qstr *name)
  {
        struct qstr qstr = {.name = str, .len = len };
-       struct inode *inode = dentry->d_parent->d_inode;
+       const struct dentry *parent = READ_ONCE(dentry->d_parent);
+       const struct inode *inode = READ_ONCE(parent->d_inode);
  
-       if (!IS_CASEFOLDED(inode) || !EXT4_SB(inode->i_sb)->s_encoding) {
+       if (!inode || !IS_CASEFOLDED(inode) ||
+           !EXT4_SB(inode->i_sb)->s_encoding) {
                if (len != name->len)
                        return -1;
                return memcmp(str, name->name, len);
@@@ -687,10 -688,11 +688,11 @@@ static int ext4_d_hash(const struct den
  {
        const struct ext4_sb_info *sbi = EXT4_SB(dentry->d_sb);
        const struct unicode_map *um = sbi->s_encoding;
+       const struct inode *inode = READ_ONCE(dentry->d_inode);
        unsigned char *norm;
        int len, ret = 0;
  
-       if (!IS_CASEFOLDED(dentry->d_inode) || !um)
+       if (!inode || !IS_CASEFOLDED(inode) || !um)
                return 0;
  
        norm = kmalloc(PATH_MAX, GFP_ATOMIC);