1. 13 8月, 2019 1 次提交
  2. 29 5月, 2019 6 次提交
    • E
      fscrypt: support decrypting multiple filesystem blocks per page · aa8bc1ac
      Eric Biggers 提交于
      Rename fscrypt_decrypt_page() to fscrypt_decrypt_pagecache_blocks() and
      redefine its behavior to decrypt all filesystem blocks in the given
      region of the given page, rather than assuming that the region consists
      of just one filesystem block.  Also remove the 'inode' and 'lblk_num'
      parameters, since they can be retrieved from the page as it's already
      assumed to be a pagecache page.
      
      This is in preparation for allowing encryption on ext4 filesystems with
      blocksize != PAGE_SIZE.
      
      This is based on work by Chandan Rajendra.
      Reviewed-by: NChandan Rajendra <chandan@linux.ibm.com>
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      aa8bc1ac
    • E
      fscrypt: introduce fscrypt_decrypt_block_inplace() · 41adbcb7
      Eric Biggers 提交于
      Currently fscrypt_decrypt_page() does one of two logically distinct
      things depending on whether FS_CFLG_OWN_PAGES is set in the filesystem's
      fscrypt_operations: decrypt a pagecache page in-place, or decrypt a
      filesystem block in-place in any page.  Currently these happen to share
      the same implementation, but this conflates the notion of blocks and
      pages.  It also makes it so that all callers have to provide inode and
      lblk_num, when fscrypt could determine these itself for pagecache pages.
      
      Therefore, move the FS_CFLG_OWN_PAGES behavior into a new function
      fscrypt_decrypt_block_inplace().  This mirrors
      fscrypt_encrypt_block_inplace().
      
      This is in preparation for allowing encryption on ext4 filesystems with
      blocksize != PAGE_SIZE.
      Reviewed-by: NChandan Rajendra <chandan@linux.ibm.com>
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      41adbcb7
    • E
      fscrypt: support encrypting multiple filesystem blocks per page · 53bc1d85
      Eric Biggers 提交于
      Rename fscrypt_encrypt_page() to fscrypt_encrypt_pagecache_blocks() and
      redefine its behavior to encrypt all filesystem blocks from the given
      region of the given page, rather than assuming that the region consists
      of just one filesystem block.  Also remove the 'inode' and 'lblk_num'
      parameters, since they can be retrieved from the page as it's already
      assumed to be a pagecache page.
      
      This is in preparation for allowing encryption on ext4 filesystems with
      blocksize != PAGE_SIZE.
      
      This is based on work by Chandan Rajendra.
      Reviewed-by: NChandan Rajendra <chandan@linux.ibm.com>
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      53bc1d85
    • E
      fscrypt: introduce fscrypt_encrypt_block_inplace() · 03569f2f
      Eric Biggers 提交于
      fscrypt_encrypt_page() behaves very differently depending on whether the
      filesystem set FS_CFLG_OWN_PAGES in its fscrypt_operations.  This makes
      the function difficult to understand and document.  It also makes it so
      that all callers have to provide inode and lblk_num, when fscrypt could
      determine these itself for pagecache pages.
      
      Therefore, move the FS_CFLG_OWN_PAGES behavior into a new function
      fscrypt_encrypt_block_inplace().
      
      This is in preparation for allowing encryption on ext4 filesystems with
      blocksize != PAGE_SIZE.
      Reviewed-by: NChandan Rajendra <chandan@linux.ibm.com>
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      03569f2f
    • E
      fscrypt: remove the "write" part of struct fscrypt_ctx · 2a415a02
      Eric Biggers 提交于
      Now that fscrypt_ctx is not used for writes, remove the 'w' fields.
      Reviewed-by: NChandan Rajendra <chandan@linux.ibm.com>
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      2a415a02
    • E
      fscrypt: simplify bounce page handling · d2d0727b
      Eric Biggers 提交于
      Currently, bounce page handling for writes to encrypted files is
      unnecessarily complicated.  A fscrypt_ctx is allocated along with each
      bounce page, page_private(bounce_page) points to this fscrypt_ctx, and
      fscrypt_ctx::w::control_page points to the original pagecache page.
      
      However, because writes don't use the fscrypt_ctx for anything else,
      there's no reason why page_private(bounce_page) can't just point to the
      original pagecache page directly.
      
      Therefore, this patch makes this change.  In the process, it also cleans
      up the API exposed to filesystems that allows testing whether a page is
      a bounce page, getting the pagecache page from a bounce page, and
      freeing a bounce page.
      Reviewed-by: NChandan Rajendra <chandan@linux.ibm.com>
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      d2d0727b
  3. 08 5月, 2019 1 次提交
  4. 18 4月, 2019 1 次提交
    • E
      fscrypt: cache decrypted symlink target in ->i_link · 2c58d548
      Eric Biggers 提交于
      Path lookups that traverse encrypted symlink(s) are very slow because
      each encrypted symlink needs to be decrypted each time it's followed.
      This also involves dropping out of rcu-walk mode.
      
      Make encrypted symlinks faster by caching the decrypted symlink target
      in ->i_link.  The first call to fscrypt_get_symlink() sets it.  Then,
      the existing VFS path lookup code uses the non-NULL ->i_link to take the
      fast path where ->get_link() isn't called, and lookups in rcu-walk mode
      remain in rcu-walk mode.
      
      Also set ->i_link immediately when a new encrypted symlink is created.
      
      To safely free the symlink target after an RCU grace period has elapsed,
      introduce a new function fscrypt_free_inode(), and make the relevant
      filesystems call it just before actually freeing the inode.
      
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      2c58d548
  5. 17 4月, 2019 6 次提交
    • E
      fscrypt: fix race where ->lookup() marks plaintext dentry as ciphertext · b01531db
      Eric Biggers 提交于
      ->lookup() in an encrypted directory begins as follows:
      
      1. fscrypt_prepare_lookup():
          a. Try to load the directory's encryption key.
          b. If the key is unavailable, mark the dentry as a ciphertext name
             via d_flags.
      2. fscrypt_setup_filename():
          a. Try to load the directory's encryption key.
          b. If the key is available, encrypt the name (treated as a plaintext
             name) to get the on-disk name.  Otherwise decode the name
             (treated as a ciphertext name) to get the on-disk name.
      
      But if the key is concurrently added, it may be found at (2a) but not at
      (1a).  In this case, the dentry will be wrongly marked as a ciphertext
      name even though it was actually treated as plaintext.
      
      This will cause the dentry to be wrongly invalidated on the next lookup,
      potentially causing problems.  For example, if the racy ->lookup() was
      part of sys_mount(), then the new mount will be detached when anything
      tries to access it.  This is despite the mountpoint having a plaintext
      path, which should remain valid now that the key was added.
      
      Of course, this is only possible if there's a userspace race.  Still,
      the additional kernel-side race is confusing and unexpected.
      
      Close the kernel-side race by changing fscrypt_prepare_lookup() to also
      set the on-disk filename (step 2b), consistent with the d_flags update.
      
      Fixes: 28b4c263 ("ext4 crypto: revalidate dentry after adding or removing the key")
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      b01531db
    • E
      fs, fscrypt: clear DCACHE_ENCRYPTED_NAME when unaliasing directory · 0bf3d5c1
      Eric Biggers 提交于
      Make __d_move() clear DCACHE_ENCRYPTED_NAME on the source dentry.  This
      is needed for when d_splice_alias() moves a directory's encrypted alias
      to its decrypted alias as a result of the encryption key being added.
      
      Otherwise, the decrypted alias will incorrectly be invalidated on the
      next lookup, causing problems such as unmounting a mount the user just
      mount()ed there.
      
      Note that we don't have to support arbitrary moves of this flag because
      fscrypt doesn't allow dentries with DCACHE_ENCRYPTED_NAME to be the
      source or target of a rename().
      
      Fixes: 28b4c263 ("ext4 crypto: revalidate dentry after adding or removing the key")
      Reported-by: NSarthak Kukreti <sarthakkukreti@chromium.org>
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      0bf3d5c1
    • E
      fscrypt: fix race allowing rename() and link() of ciphertext dentries · 968dd6d0
      Eric Biggers 提交于
      Close some race conditions where fscrypt allowed rename() and link() on
      ciphertext dentries that had been looked up just prior to the key being
      concurrently added.  It's better to return -ENOKEY in this case.
      
      This avoids doing the nonsensical thing of encrypting the names a second
      time when searching for the actual on-disk dir entries.  It also
      guarantees that DCACHE_ENCRYPTED_NAME dentries are never rename()d, so
      the dcache won't have support all possible combinations of moving
      DCACHE_ENCRYPTED_NAME around during __d_move().
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      968dd6d0
    • E
      fscrypt: clean up and improve dentry revalidation · 6cc24868
      Eric Biggers 提交于
      Make various improvements to fscrypt dentry revalidation:
      
      - Don't try to handle the case where the per-directory key is removed,
        as this can't happen without the inode (and dentries) being evicted.
      
      - Flag ciphertext dentries rather than plaintext dentries, since it's
        ciphertext dentries that need the special handling.
      
      - Avoid doing unnecessary work for non-ciphertext dentries.
      
      - When revalidating ciphertext dentries, try to set up the directory's
        i_crypt_info to make sure the key is really still absent, rather than
        invalidating all negative dentries as the previous code did.  An old
        comment suggested we can't do this for locking reasons, but AFAICT
        this comment was outdated and it actually works fine.
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      6cc24868
    • E
      fscrypt: use READ_ONCE() to access ->i_crypt_info · e37a784d
      Eric Biggers 提交于
      ->i_crypt_info starts out NULL and may later be locklessly set to a
      non-NULL value by the cmpxchg() in fscrypt_get_encryption_info().
      
      But ->i_crypt_info is used directly, which technically is incorrect.
      It's a data race, and it doesn't include the data dependency barrier
      needed to safely dereference the pointer on at least one architecture.
      
      Fix this by using READ_ONCE() instead.  Note: we don't need to use
      smp_load_acquire(), since dereferencing the pointer only requires a data
      dependency barrier, which is already included in READ_ONCE().  We also
      don't need READ_ONCE() in places where ->i_crypt_info is unconditionally
      dereferenced, since it must have already been checked.
      
      Also downgrade the cmpxchg() to cmpxchg_release(), since RELEASE
      semantics are sufficient on the write side.
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      e37a784d
    • E
      fscrypt: drop inode argument from fscrypt_get_ctx() · cd0265fc
      Eric Biggers 提交于
      The only reason the inode is being passed to fscrypt_get_ctx() is to
      verify that the encryption key is available.  However, all callers
      already ensure this because if we get as far as trying to do I/O to an
      encrypted file without the key, there's already a bug.
      
      Therefore, remove this unnecessary argument.
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      cd0265fc
  6. 24 1月, 2019 2 次提交
    • E
      fscrypt: return -EXDEV for incompatible rename or link into encrypted dir · f5e55e77
      Eric Biggers 提交于
      Currently, trying to rename or link a regular file, directory, or
      symlink into an encrypted directory fails with EPERM when the source
      file is unencrypted or is encrypted with a different encryption policy,
      and is on the same mountpoint.  It is correct for the operation to fail,
      but the choice of EPERM breaks tools like 'mv' that know to copy rather
      than rename if they see EXDEV, but don't know what to do with EPERM.
      
      Our original motivation for EPERM was to encourage users to securely
      handle their data.  Encrypting files by "moving" them into an encrypted
      directory can be insecure because the unencrypted data may remain in
      free space on disk, where it can later be recovered by an attacker.
      It's much better to encrypt the data from the start, or at least try to
      securely delete the source data e.g. using the 'shred' program.
      
      However, the current behavior hasn't been effective at achieving its
      goal because users tend to be confused, hack around it, and complain;
      see e.g. https://github.com/google/fscrypt/issues/76.  And in some cases
      it's actually inconsistent or unnecessary.  For example, 'mv'-ing files
      between differently encrypted directories doesn't work even in cases
      where it can be secure, such as when in userspace the same passphrase
      protects both directories.  Yet, you *can* already 'mv' unencrypted
      files into an encrypted directory if the source files are on a different
      mountpoint, even though doing so is often insecure.
      
      There are probably better ways to teach users to securely handle their
      files.  For example, the 'fscrypt' userspace tool could provide a
      command that migrates unencrypted files into an encrypted directory,
      acting like 'shred' on the source files and providing appropriate
      warnings depending on the type of the source filesystem and disk.
      
      Receiving errors on unimportant files might also force some users to
      disable encryption, thus making the behavior counterproductive.  It's
      desirable to make encryption as unobtrusive as possible.
      
      Therefore, change the error code from EPERM to EXDEV so that tools
      looking for EXDEV will fall back to a copy.
      
      This, of course, doesn't prevent users from still doing the right things
      to securely manage their files.  Note that this also matches the
      behavior when a file is renamed between two project quota hierarchies;
      so there's precedent for using EXDEV for things other than mountpoints.
      
      xfstests generic/398 will require an update with this change.
      
      [Rewritten from an earlier patch series by Michael Halcrow.]
      
      Cc: Michael Halcrow <mhalcrow@google.com>
      Cc: Joe Richey <joerichey@google.com>
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      f5e55e77
    • C
      fscrypt: remove filesystem specific build config option · 643fa961
      Chandan Rajendra 提交于
      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.
      Reviewed-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NChandan Rajendra <chandan@linux.vnet.ibm.com>
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      643fa961
  7. 12 1月, 2018 10 次提交
  8. 19 10月, 2017 7 次提交
  9. 06 7月, 2017 1 次提交
    • T
      ext4: fix __ext4_new_inode() journal credits calculation · af65207c
      Tahsin Erdogan 提交于
      ea_inode feature allows creating extended attributes that are up to
      64k in size. Update __ext4_new_inode() to pick increased credit limits.
      
      To avoid overallocating too many journal credits, update
      __ext4_xattr_set_credits() to make a distinction between xattr create
      vs update. This helps __ext4_new_inode() because all attributes are
      known to be new, so we can save credits that are normally needed to
      delete old values.
      
      Also, have fscrypt specify its maximum context size so that we don't
      end up allocating credits for 64k size.
      Signed-off-by: NTahsin Erdogan <tahsin@google.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      af65207c
  10. 24 6月, 2017 2 次提交
    • E
      fscrypt: make ->dummy_context() return bool · c250b7dd
      Eric Biggers 提交于
      This makes it consistent with ->is_encrypted(), ->empty_dir(), and
      fscrypt_dummy_context_enabled().
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      c250b7dd
    • D
      fscrypt: add support for AES-128-CBC · b7e7cf7a
      Daniel Walter 提交于
      fscrypt provides facilities to use different encryption algorithms which
      are selectable by userspace when setting the encryption policy. Currently,
      only AES-256-XTS for file contents and AES-256-CBC-CTS for file names are
      implemented. This is a clear case of kernel offers the mechanism and
      userspace selects a policy. Similar to what dm-crypt and ecryptfs have.
      
      This patch adds support for using AES-128-CBC for file contents and
      AES-128-CBC-CTS for file name encryption. To mitigate watermarking
      attacks, IVs are generated using the ESSIV algorithm. While AES-CBC is
      actually slightly less secure than AES-XTS from a security point of view,
      there is more widespread hardware support. Using AES-CBC gives us the
      acceptable performance while still providing a moderate level of security
      for persistent storage.
      
      Especially low-powered embedded devices with crypto accelerators such as
      CAAM or CESA often only support AES-CBC. Since using AES-CBC over AES-XTS
      is basically thought of a last resort, we use AES-128-CBC over AES-256-CBC
      since it has less encryption rounds and yields noticeable better
      performance starting from a file size of just a few kB.
      Signed-off-by: NDaniel Walter <dwalter@sigma-star.at>
      [david@sigma-star.at: addressed review comments]
      Signed-off-by: NDavid Gstir <david@sigma-star.at>
      Reviewed-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      b7e7cf7a
  11. 30 4月, 2017 1 次提交
  12. 16 3月, 2017 1 次提交
    • E
      fscrypt: eliminate ->prepare_context() operation · 94840e3c
      Eric Biggers 提交于
      The only use of the ->prepare_context() fscrypt operation was to allow
      ext4 to evict inline data from the inode before ->set_context().
      However, there is no reason why this cannot be done as simply the first
      step in ->set_context(), and in fact it makes more sense to do it that
      way because then the policy modes and flags get validated before any
      real work is done.  Therefore, merge ext4_prepare_context() into
      ext4_set_context(), and remove ->prepare_context().
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      94840e3c
  13. 07 2月, 2017 1 次提交
    • E
      fscrypt: split supp and notsupp declarations into their own headers · 46f47e48
      Eric Biggers 提交于
      Previously, each filesystem configured without encryption support would
      define all the public fscrypt functions to their notsupp_* stubs.  This
      list of #defines had to be updated in every filesystem whenever a change
      was made to the public fscrypt functions.  To make things more
      maintainable now that we have three filesystems using fscrypt, split the
      old header fscrypto.h into several new headers.  fscrypt_supp.h contains
      the real declarations and is included by filesystems when configured
      with encryption support, whereas fscrypt_notsupp.h contains the inline
      stubs and is included by filesystems when configured without encryption
      support.  fscrypt_common.h contains common declarations needed by both.
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NTheodore Ts'o <tytso@mit.edu>
      46f47e48