1. 20 10月, 2022 1 次提交
  2. 22 9月, 2022 2 次提交
    • C
      fscrypt: work on block_devices instead of request_queues · 0e91fc1e
      Christoph Hellwig 提交于
      request_queues are a block layer implementation detail that should not
      leak into file systems.  Change the fscrypt inline crypto code to
      retrieve block devices instead of request_queues from the file system.
      As part of that, clean up the interaction with multi-device file systems
      by returning both the number of devices and the actual device array in a
      single method call.
      Signed-off-by: NChristoph Hellwig <hch@lst.de>
      [ebiggers: bug fixes and minor tweaks]
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Link: https://lore.kernel.org/r/20220901193208.138056-4-ebiggers@kernel.org
      0e91fc1e
    • E
      fscrypt: stop using keyrings subsystem for fscrypt_master_key · d7e7b9af
      Eric Biggers 提交于
      The approach of fs/crypto/ internally managing the fscrypt_master_key
      structs as the payloads of "struct key" objects contained in a
      "struct key" keyring has outlived its usefulness.  The original idea was
      to simplify the code by reusing code from the keyrings subsystem.
      However, several issues have arisen that can't easily be resolved:
      
      - When a master key struct is destroyed, blk_crypto_evict_key() must be
        called on any per-mode keys embedded in it.  (This started being the
        case when inline encryption support was added.)  Yet, the keyrings
        subsystem can arbitrarily delay the destruction of keys, even past the
        time the filesystem was unmounted.  Therefore, currently there is no
        easy way to call blk_crypto_evict_key() when a master key is
        destroyed.  Currently, this is worked around by holding an extra
        reference to the filesystem's request_queue(s).  But it was overlooked
        that the request_queue reference is *not* guaranteed to pin the
        corresponding blk_crypto_profile too; for device-mapper devices that
        support inline crypto, it doesn't.  This can cause a use-after-free.
      
      - When the last inode that was using an incompletely-removed master key
        is evicted, the master key removal is completed by removing the key
        struct from the keyring.  Currently this is done via key_invalidate().
        Yet, key_invalidate() takes the key semaphore.  This can deadlock when
        called from the shrinker, since in fscrypt_ioctl_add_key(), memory is
        allocated with GFP_KERNEL under the same semaphore.
      
      - More generally, the fact that the keyrings subsystem can arbitrarily
        delay the destruction of keys (via garbage collection delay, or via
        random processes getting temporary key references) is undesirable, as
        it means we can't strictly guarantee that all secrets are ever wiped.
      
      - Doing the master key lookups via the keyrings subsystem results in the
        key_permission LSM hook being called.  fscrypt doesn't want this, as
        all access control for encrypted files is designed to happen via the
        files themselves, like any other files.  The workaround which SELinux
        users are using is to change their SELinux policy to grant key search
        access to all domains.  This works, but it is an odd extra step that
        shouldn't really have to be done.
      
      The fix for all these issues is to change the implementation to what I
      should have done originally: don't use the keyrings subsystem to keep
      track of the filesystem's fscrypt_master_key structs.  Instead, just
      store them in a regular kernel data structure, and rework the reference
      counting, locking, and lifetime accordingly.  Retain support for
      RCU-mode key lookups by using a hash table.  Replace fscrypt_sb_free()
      with fscrypt_sb_delete(), which releases the keys synchronously and runs
      a bit earlier during unmount, so that block devices are still available.
      
      A side effect of this patch is that neither the master keys themselves
      nor the filesystem keyrings will be listed in /proc/keys anymore.
      ("Master key users" and the master key users keyrings will still be
      listed.)  However, this was mostly an implementation detail, and it was
      intended just for debugging purposes.  I don't know of anyone using it.
      
      This patch does *not* change how "master key users" (->mk_users) works;
      that still uses the keyrings subsystem.  That is still needed for key
      quotas, and changing that isn't necessary to solve the issues listed
      above.  If we decide to change that too, it would be a separate patch.
      
      I've marked this as fixing the original commit that added the fscrypt
      keyring, but as noted above the most important issue that this patch
      fixes wasn't introduced until the addition of inline encryption support.
      
      Fixes: 22d94f49 ("fscrypt: add FS_IOC_ADD_ENCRYPTION_KEY ioctl")
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Link: https://lore.kernel.org/r/20220901193208.138056-2-ebiggers@kernel.org
      d7e7b9af
  3. 12 9月, 2022 1 次提交
  4. 07 9月, 2022 1 次提交
  5. 23 8月, 2022 1 次提交
  6. 03 8月, 2022 2 次提交
    • J
      fscrypt: add fscrypt_context_for_new_inode · 637fa738
      Jeff Layton 提交于
      Most filesystems just call fscrypt_set_context on new inodes, which
      usually causes a setxattr. That's a bit late for ceph, which can send
      along a full set of attributes with the create request.
      
      Doing so allows it to avoid race windows that where the new inode could
      be seen by other clients without the crypto context attached. It also
      avoids the separate round trip to the server.
      
      Refactor the fscrypt code a bit to allow us to create a new crypto
      context, attach it to the inode, and write it to the buffer, but without
      calling set_context on it. ceph can later use this to marshal the
      context into the attributes we send along with the create request.
      Signed-off-by: NJeff Layton <jlayton@kernel.org>
      Reviewed-by: NXiubo Li <xiubli@redhat.com>
      Acked-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NIlya Dryomov <idryomov@gmail.com>
      637fa738
    • J
      fscrypt: export fscrypt_fname_encrypt and fscrypt_fname_encrypted_size · d3e94fdc
      Jeff Layton 提交于
      For ceph, we want to use our own scheme for handling filenames that are
      are longer than NAME_MAX after encryption and Base64 encoding. This
      allows us to have a consistent view of the encrypted filenames for
      clients that don't support fscrypt and clients that do but that don't
      have the key.
      
      Currently, fs/crypto only supports encrypting filenames using
      fscrypt_setup_filename, but that also handles encoding nokey names. Ceph
      can't use that because it handles nokey names in a different way.
      
      Export fscrypt_fname_encrypt. Rename fscrypt_fname_encrypted_size to
      __fscrypt_fname_encrypted_size and add a new wrapper called
      fscrypt_fname_encrypted_size that takes an inode argument rather than a
      pointer to a fscrypt_policy union.
      Signed-off-by: NJeff Layton <jlayton@kernel.org>
      Reviewed-by: NXiubo Li <xiubli@redhat.com>
      Acked-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NIlya Dryomov <idryomov@gmail.com>
      d3e94fdc
  7. 10 5月, 2022 1 次提交
    • E
      fscrypt: add new helper functions for test_dummy_encryption · 218d921b
      Eric Biggers 提交于
      Unfortunately the design of fscrypt_set_test_dummy_encryption() doesn't
      work properly for the new mount API, as it combines too many steps into
      one function:
      
        - Parse the argument to test_dummy_encryption
        - Check the setting against the filesystem instance
        - Apply the setting to the filesystem instance
      
      The new mount API has split these into separate steps.  ext4 partially
      worked around this by duplicating some of the logic, but it still had
      some bugs.  To address this, add some new helper functions that split up
      the steps of fscrypt_set_test_dummy_encryption():
      
        - fscrypt_parse_test_dummy_encryption()
        - fscrypt_dummy_policies_equal()
        - fscrypt_add_test_dummy_key()
      
      While we're add it, also add a function fscrypt_is_dummy_policy_set()
      which will be useful to avoid some #ifdef's.
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Link: https://lore.kernel.org/r/20220501050857.538984-5-ebiggers@kernel.org
      218d921b
  8. 14 4月, 2022 1 次提交
    • E
      fscrypt: split up FS_CRYPTO_BLOCK_SIZE · 63cec138
      Eric Biggers 提交于
      FS_CRYPTO_BLOCK_SIZE is neither the filesystem block size nor the
      granularity of encryption.  Rather, it defines two logically separate
      constraints that both arise from the block size of the AES cipher:
      
      - The alignment required for the lengths of file contents blocks
      - The minimum input/output length for the filenames encryption modes
      
      Since there are way too many things called the "block size", and the
      connection with the AES block size is not easily understood, split
      FS_CRYPTO_BLOCK_SIZE into two constants FSCRYPT_CONTENTS_ALIGNMENT and
      FSCRYPT_FNAME_MIN_MSG_LEN that more clearly describe what they are.
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      Link: https://lore.kernel.org/r/20220405010914.18519-1-ebiggers@kernel.org
      63cec138
  9. 09 2月, 2022 1 次提交
    • E
      fscrypt: add functions for direct I/O support · c6c89783
      Eric Biggers 提交于
      Encrypted files traditionally haven't supported DIO, due to the need to
      encrypt/decrypt the data.  However, when the encryption is implemented
      using inline encryption (blk-crypto) instead of the traditional
      filesystem-layer encryption, it is straightforward to support DIO.
      
      In preparation for supporting this, add the following functions:
      
      - fscrypt_dio_supported() checks whether a DIO request is supported as
        far as encryption is concerned.  Encrypted files will only support DIO
        when inline encryption is used and the I/O request is properly
        aligned; this function checks these preconditions.
      
      - fscrypt_limit_io_blocks() limits the length of a bio to avoid crossing
        a place in the file that a bio with an encryption context cannot
        cross due to a DUN discontiguity.  This function is needed by
        filesystems that use the iomap DIO implementation (which operates
        directly on logical ranges, so it won't use fscrypt_mergeable_bio())
        and that support FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32.
      Co-developed-by: NSatya Tangirala <satyat@google.com>
      Signed-off-by: NSatya Tangirala <satyat@google.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Link: https://lore.kernel.org/r/20220128233940.79464-2-ebiggers@kernel.orgSigned-off-by: NEric Biggers <ebiggers@google.com>
      c6c89783
  10. 21 9月, 2021 1 次提交
  11. 29 7月, 2021 1 次提交
  12. 26 7月, 2021 1 次提交
    • E
      fscrypt: add fscrypt_symlink_getattr() for computing st_size · d1876056
      Eric Biggers 提交于
      Add a helper function fscrypt_symlink_getattr() which will be called
      from the various filesystems' ->getattr() methods to read and decrypt
      the target of encrypted symlinks in order to report the correct st_size.
      
      Detailed explanation:
      
      As required by POSIX and as documented in various man pages, st_size for
      a symlink is supposed to be the length of the symlink target.
      Unfortunately, st_size has always been wrong for encrypted symlinks
      because st_size is populated from i_size from disk, which intentionally
      contains the length of the encrypted symlink target.  That's slightly
      greater than the length of the decrypted symlink target (which is the
      symlink target that userspace usually sees), and usually won't match the
      length of the no-key encoded symlink target either.
      
      This hadn't been fixed yet because reporting the correct st_size would
      require reading the symlink target from disk and decrypting or encoding
      it, which historically has been considered too heavyweight to do in
      ->getattr().  Also historically, the wrong st_size had only broken a
      test (LTP lstat03) and there were no known complaints from real users.
      (This is probably because the st_size of symlinks isn't used too often,
      and when it is, typically it's for a hint for what buffer size to pass
      to readlink() -- which a slightly-too-large size still works for.)
      
      However, a couple things have changed now.  First, there have recently
      been complaints about the current behavior from real users:
      
      - Breakage in rpmbuild:
        https://github.com/rpm-software-management/rpm/issues/1682
        https://github.com/google/fscrypt/issues/305
      
      - Breakage in toybox cpio:
        https://www.mail-archive.com/toybox@lists.landley.net/msg07193.html
      
      - Breakage in libgit2: https://issuetracker.google.com/issues/189629152
        (on Android public issue tracker, requires login)
      
      Second, we now cache decrypted symlink targets in ->i_link.  Therefore,
      taking the performance hit of reading and decrypting the symlink target
      in ->getattr() wouldn't be as big a deal as it used to be, since usually
      it will just save having to do the same thing later.
      
      Also note that eCryptfs ended up having to read and decrypt symlink
      targets in ->getattr() as well, to fix this same issue; see
      commit 3a60a168 ("eCryptfs: Decrypt symlink target for stat size").
      
      So, let's just bite the bullet, and read and decrypt the symlink target
      in ->getattr() in order to report the correct st_size.  Add a function
      fscrypt_symlink_getattr() which the filesystems will call to do this.
      
      (Alternatively, we could store the decrypted size of symlinks on-disk.
      But there isn't a great place to do so, and encryption is meant to hide
      the original size to some extent; that property would be lost.)
      
      Cc: stable@vger.kernel.org
      Link: https://lore.kernel.org/r/20210702065350.209646-2-ebiggers@kernel.orgSigned-off-by: NEric Biggers <ebiggers@google.com>
      d1876056
  13. 03 12月, 2020 6 次提交
  14. 25 11月, 2020 2 次提交
    • E
      fscrypt: remove unnecessary calls to fscrypt_require_key() · 234f1b7f
      Eric Biggers 提交于
      In an encrypted directory, a regular dentry (one that doesn't have the
      no-key name flag) can only be created if the directory's encryption key
      is available.
      
      Therefore the calls to fscrypt_require_key() in __fscrypt_prepare_link()
      and __fscrypt_prepare_rename() are unnecessary, as these functions
      already check that the dentries they're given aren't no-key names.
      
      Remove these unnecessary calls to fscrypt_require_key().
      
      Link: https://lore.kernel.org/r/20201118075609.120337-6-ebiggers@kernel.orgSigned-off-by: NEric Biggers <ebiggers@google.com>
      234f1b7f
    • E
      fscrypt: add fscrypt_is_nokey_name() · 159e1de2
      Eric Biggers 提交于
      It's possible to create a duplicate filename in an encrypted directory
      by creating a file concurrently with adding the encryption key.
      
      Specifically, sys_open(O_CREAT) (or sys_mkdir(), sys_mknod(), or
      sys_symlink()) can lookup the target filename while the directory's
      encryption key hasn't been added yet, resulting in a negative no-key
      dentry.  The VFS then calls ->create() (or ->mkdir(), ->mknod(), or
      ->symlink()) because the dentry is negative.  Normally, ->create() would
      return -ENOKEY due to the directory's key being unavailable.  However,
      if the key was added between the dentry lookup and ->create(), then the
      filesystem will go ahead and try to create the file.
      
      If the target filename happens to already exist as a normal name (not a
      no-key name), a duplicate filename may be added to the directory.
      
      In order to fix this, we need to fix the filesystems to prevent
      ->create(), ->mkdir(), ->mknod(), and ->symlink() on no-key names.
      (->rename() and ->link() need it too, but those are already handled
      correctly by fscrypt_prepare_rename() and fscrypt_prepare_link().)
      
      In preparation for this, add a helper function fscrypt_is_nokey_name()
      that filesystems can use to do this check.  Use this helper function for
      the existing checks that fs/crypto/ does for rename and link.
      
      Cc: stable@vger.kernel.org
      Link: https://lore.kernel.org/r/20201118075609.120337-2-ebiggers@kernel.orgSigned-off-by: NEric Biggers <ebiggers@google.com>
      159e1de2
  15. 29 9月, 2020 1 次提交
  16. 24 9月, 2020 2 次提交
  17. 22 9月, 2020 5 次提交
    • E
      fscrypt: make fscrypt_set_test_dummy_encryption() take a 'const char *' · c8c868ab
      Eric Biggers 提交于
      fscrypt_set_test_dummy_encryption() requires that the optional argument
      to the test_dummy_encryption mount option be specified as a substring_t.
      That doesn't work well with filesystems that use the new mount API,
      since the new way of parsing mount options doesn't use substring_t.
      
      Make it take the argument as a 'const char *' instead.
      
      Instead of moving the match_strdup() into the callers in ext4 and f2fs,
      make them just use arg->from directly.  Since the pattern is
      "test_dummy_encryption=%s", the argument will be null-terminated.
      Acked-by: NJeff Layton <jlayton@kernel.org>
      Link: https://lore.kernel.org/r/20200917041136.178600-14-ebiggers@kernel.orgSigned-off-by: NEric Biggers <ebiggers@google.com>
      c8c868ab
    • E
      fscrypt: handle test_dummy_encryption in more logical way · ac4acb1f
      Eric Biggers 提交于
      The behavior of the test_dummy_encryption mount option is that when a
      new file (or directory or symlink) is created in an unencrypted
      directory, it's automatically encrypted using a dummy encryption policy.
      That's it; in particular, the encryption (or lack thereof) of existing
      files (or directories or symlinks) doesn't change.
      
      Unfortunately the implementation of test_dummy_encryption is a bit weird
      and confusing.  When test_dummy_encryption is enabled and a file is
      being created in an unencrypted directory, we set up an encryption key
      (->i_crypt_info) for the directory.  This isn't actually used to do any
      encryption, however, since the directory is still unencrypted!  Instead,
      ->i_crypt_info is only used for inheriting the encryption policy.
      
      One consequence of this is that the filesystem ends up providing a
      "dummy context" (policy + nonce) instead of a "dummy policy".  In
      commit ed318a6c ("fscrypt: support test_dummy_encryption=v2"), I
      mistakenly thought this was required.  However, actually the nonce only
      ends up being used to derive a key that is never used.
      
      Another consequence of this implementation is that it allows for
      'inode->i_crypt_info != NULL && !IS_ENCRYPTED(inode)', which is an edge
      case that can be forgotten about.  For example, currently
      FS_IOC_GET_ENCRYPTION_POLICY on an unencrypted directory may return the
      dummy encryption policy when the filesystem is mounted with
      test_dummy_encryption.  That seems like the wrong thing to do, since
      again, the directory itself is not actually encrypted.
      
      Therefore, switch to a more logical and maintainable implementation
      where the dummy encryption policy inheritance is done without setting up
      keys for unencrypted directories.  This involves:
      
      - Adding a function fscrypt_policy_to_inherit() which returns the
        encryption policy to inherit from a directory.  This can be a real
        policy, a dummy policy, or no policy.
      
      - Replacing struct fscrypt_dummy_context, ->get_dummy_context(), etc.
        with struct fscrypt_dummy_policy, ->get_dummy_policy(), etc.
      
      - Making fscrypt_fname_encrypted_size() take an fscrypt_policy instead
        of an inode.
      Acked-by: NJaegeuk Kim <jaegeuk@kernel.org>
      Acked-by: NJeff Layton <jlayton@kernel.org>
      Link: https://lore.kernel.org/r/20200917041136.178600-13-ebiggers@kernel.orgSigned-off-by: NEric Biggers <ebiggers@google.com>
      ac4acb1f
    • E
      fscrypt: move fscrypt_prepare_symlink() out-of-line · 31114726
      Eric Biggers 提交于
      In preparation for moving the logic for "get the encryption policy
      inherited by new files in this directory" to a single place, make
      fscrypt_prepare_symlink() a regular function rather than an inline
      function that wraps __fscrypt_prepare_symlink().
      
      This way, the new function fscrypt_policy_to_inherit() won't need to be
      exported to filesystems.
      Acked-by: NJeff Layton <jlayton@kernel.org>
      Link: https://lore.kernel.org/r/20200917041136.178600-12-ebiggers@kernel.orgSigned-off-by: NEric Biggers <ebiggers@google.com>
      31114726
    • E
      fscrypt: remove fscrypt_inherit_context() · e9d5e31d
      Eric Biggers 提交于
      Now that all filesystems have been converted to use
      fscrypt_prepare_new_inode() and fscrypt_set_context(),
      fscrypt_inherit_context() is no longer used.  Remove it.
      Acked-by: NJeff Layton <jlayton@kernel.org>
      Link: https://lore.kernel.org/r/20200917041136.178600-8-ebiggers@kernel.orgSigned-off-by: NEric Biggers <ebiggers@google.com>
      e9d5e31d
    • E
      fscrypt: add fscrypt_prepare_new_inode() and fscrypt_set_context() · a992b20c
      Eric Biggers 提交于
      fscrypt_get_encryption_info() is intended to be GFP_NOFS-safe.  But
      actually it isn't, since it uses functions like crypto_alloc_skcipher()
      which aren't GFP_NOFS-safe, even when called under memalloc_nofs_save().
      Therefore it can deadlock when called from a context that needs
      GFP_NOFS, e.g. during an ext4 transaction or between f2fs_lock_op() and
      f2fs_unlock_op().  This happens when creating a new encrypted file.
      
      We can't fix this by just not setting up the key for new inodes right
      away, since new symlinks need their key to encrypt the symlink target.
      
      So we need to set up the new inode's key before starting the
      transaction.  But just calling fscrypt_get_encryption_info() earlier
      doesn't work, since it assumes the encryption context is already set,
      and the encryption context can't be set until the transaction.
      
      The recently proposed fscrypt support for the ceph filesystem
      (https://lkml.kernel.org/linux-fscrypt/20200821182813.52570-1-jlayton@kernel.org/T/#u)
      will have this same ordering problem too, since ceph will need to
      encrypt new symlinks before setting their encryption context.
      
      Finally, f2fs can deadlock when the filesystem is mounted with
      '-o test_dummy_encryption' and a new file is created in an existing
      unencrypted directory.  Similarly, this is caused by holding too many
      locks when calling fscrypt_get_encryption_info().
      
      To solve all these problems, add new helper functions:
      
      - fscrypt_prepare_new_inode() sets up a new inode's encryption key
        (fscrypt_info), using the parent directory's encryption policy and a
        new random nonce.  It neither reads nor writes the encryption context.
      
      - fscrypt_set_context() persists the encryption context of a new inode,
        using the information from the fscrypt_info already in memory.  This
        replaces fscrypt_inherit_context().
      
      Temporarily keep fscrypt_inherit_context() around until all filesystems
      have been converted to use fscrypt_set_context().
      Acked-by: NJeff Layton <jlayton@kernel.org>
      Link: https://lore.kernel.org/r/20200917041136.178600-2-ebiggers@kernel.orgSigned-off-by: NEric Biggers <ebiggers@google.com>
      a992b20c
  18. 08 9月, 2020 1 次提交
  19. 22 7月, 2020 1 次提交
    • E
      fscrypt: use smp_load_acquire() for ->i_crypt_info · ab673b98
      Eric Biggers 提交于
      Normally smp_store_release() or cmpxchg_release() is paired with
      smp_load_acquire().  Sometimes smp_load_acquire() can be replaced with
      the more lightweight READ_ONCE().  However, for this to be safe, all the
      published memory must only be accessed in a way that involves the
      pointer itself.  This may not be the case if allocating the object also
      involves initializing a static or global variable, for example.
      
      fscrypt_info includes various sub-objects which are internal to and are
      allocated by other kernel subsystems such as keyrings and crypto.  So by
      using READ_ONCE() for ->i_crypt_info, we're relying on internal
      implementation details of these other kernel subsystems.
      
      Remove this fragile assumption by using smp_load_acquire() instead.
      
      (Note: I haven't seen any real-world problems here.  This change is just
      fixing the code to be guaranteed correct and less fragile.)
      
      Fixes: e37a784d ("fscrypt: use READ_ONCE() to access ->i_crypt_info")
      Link: https://lore.kernel.org/r/20200721225920.114347-5-ebiggers@kernel.orgSigned-off-by: NEric Biggers <ebiggers@google.com>
      ab673b98
  20. 09 7月, 2020 1 次提交
    • S
      fscrypt: add inline encryption support · 5fee3609
      Satya Tangirala 提交于
      Add support for inline encryption to fs/crypto/.  With "inline
      encryption", the block layer handles the decryption/encryption as part
      of the bio, instead of the filesystem doing the crypto itself via
      Linux's crypto API. This model is needed in order to take advantage of
      the inline encryption hardware present on most modern mobile SoCs.
      
      To use inline encryption, the filesystem needs to be mounted with
      '-o inlinecrypt'. Blk-crypto will then be used instead of the traditional
      filesystem-layer crypto whenever possible to encrypt the contents
      of any encrypted files in that filesystem. Fscrypt still provides the key
      and IV to use, and the actual ciphertext on-disk is still the same;
      therefore it's testable using the existing fscrypt ciphertext verification
      tests.
      
      Note that since blk-crypto has a fallback to Linux's crypto API, and
      also supports all the encryption modes currently supported by fscrypt,
      this feature is usable and testable even without actual inline
      encryption hardware.
      
      Per-filesystem changes will be needed to set encryption contexts when
      submitting bios and to implement the 'inlinecrypt' mount option.  This
      patch just adds the common code.
      Signed-off-by: NSatya Tangirala <satyat@google.com>
      Reviewed-by: NJaegeuk Kim <jaegeuk@kernel.org>
      Reviewed-by: NEric Biggers <ebiggers@google.com>
      Reviewed-by: NTheodore Ts'o <tytso@mit.edu>
      Link: https://lore.kernel.org/r/20200702015607.1215430-3-satyat@google.comCo-developed-by: NEric Biggers <ebiggers@google.com>
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      5fee3609
  21. 19 5月, 2020 1 次提交
    • E
      fscrypt: support test_dummy_encryption=v2 · ed318a6c
      Eric Biggers 提交于
      v1 encryption policies are deprecated in favor of v2, and some new
      features (e.g. encryption+casefolding) are only being added for v2.
      
      Therefore, the "test_dummy_encryption" mount option (which is used for
      encryption I/O testing with xfstests) needs to support v2 policies.
      
      To do this, extend its syntax to be "test_dummy_encryption=v1" or
      "test_dummy_encryption=v2".  The existing "test_dummy_encryption" (no
      argument) also continues to be accepted, to specify the default setting
      -- currently v1, but the next patch changes it to v2.
      
      To cleanly support both v1 and v2 while also making it easy to support
      specifying other encryption settings in the future (say, accepting
      "$contents_mode:$filenames_mode:v2"), make ext4 and f2fs maintain a
      pointer to the dummy fscrypt_context rather than using mount flags.
      
      To avoid concurrency issues, don't allow test_dummy_encryption to be set
      or changed during a remount.  (The former restriction is new, but
      xfstests doesn't run into it, so no one should notice.)
      
      Tested with 'gce-xfstests -c {ext4,f2fs}/encrypt -g auto'.  On ext4,
      there are two regressions, both of which are test bugs: ext4/023 and
      ext4/028 fail because they set an xattr and expect it to be stored
      inline, but the increase in size of the fscrypt_context from
      24 to 40 bytes causes this xattr to be spilled into an external block.
      
      Link: https://lore.kernel.org/r/20200512233251.118314-4-ebiggers@kernel.orgAcked-by: NJaegeuk Kim <jaegeuk@kernel.org>
      Reviewed-by: NTheodore Ts'o <tytso@mit.edu>
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      ed318a6c
  22. 13 5月, 2020 3 次提交
  23. 20 3月, 2020 1 次提交
    • E
      fscrypt: add FS_IOC_GET_ENCRYPTION_NONCE ioctl · e98ad464
      Eric Biggers 提交于
      Add an ioctl FS_IOC_GET_ENCRYPTION_NONCE which retrieves the nonce from
      an encrypted file or directory.  The nonce is the 16-byte random value
      stored in the inode's encryption xattr.  It is normally used together
      with the master key to derive the inode's actual encryption key.
      
      The nonces are needed by automated tests that verify the correctness of
      the ciphertext on-disk.  Except for the IV_INO_LBLK_64 case, there's no
      way to replicate a file's ciphertext without knowing that file's nonce.
      
      The nonces aren't secret, and the existing ciphertext verification tests
      in xfstests retrieve them from disk using debugfs or dump.f2fs.  But in
      environments that lack these debugging tools, getting the nonces by
      manually parsing the filesystem structure would be very hard.
      
      To make this important type of testing much easier, let's just add an
      ioctl that retrieves the nonce.
      
      Link: https://lore.kernel.org/r/20200314205052.93294-2-ebiggers@kernel.orgReviewed-by: NTheodore Ts'o <tytso@mit.edu>
      Signed-off-by: NEric Biggers <ebiggers@google.com>
      e98ad464
  24. 23 1月, 2020 2 次提交
    • D
      fscrypt: improve format of no-key names · edc440e3
      Daniel Rosenberg 提交于
      When an encrypted directory is listed without the key, the filesystem
      must show "no-key names" that uniquely identify directory entries, are
      at most 255 (NAME_MAX) bytes long, and don't contain '/' or '\0'.
      Currently, for short names the no-key name is the base64 encoding of the
      ciphertext filename, while for long names it's the base64 encoding of
      the ciphertext filename's dirhash and second-to-last 16-byte block.
      
      This format has the following problems:
      
      - Since it doesn't always include the dirhash, it's incompatible with
        directories that will use a secret-keyed dirhash over the plaintext
        filenames.  In this case, the dirhash won't be computable from the
        ciphertext name without the key, so it instead must be retrieved from
        the directory entry and always included in the no-key name.
        Casefolded encrypted directories will use this type of dirhash.
      
      - It's ambiguous: it's possible to craft two filenames that map to the
        same no-key name, since the method used to abbreviate long filenames
        doesn't use a proper cryptographic hash function.
      
      Solve both these problems by switching to a new no-key name format that
      is the base64 encoding of a variable-length structure that contains the
      dirhash, up to 149 bytes of the ciphertext filename, and (if any bytes
      remain) the SHA-256 of the remaining bytes of the ciphertext filename.
      
      This ensures that each no-key name contains everything needed to find
      the directory entry again, contains only legal characters, doesn't
      exceed NAME_MAX, is unambiguous unless there's a SHA-256 collision, and
      that we only take the performance hit of SHA-256 on very long filenames.
      
      Note: this change does *not* address the existing issue where users can
      modify the 'dirhash' part of a no-key name and the filesystem may still
      accept the name.
      Signed-off-by: NDaniel Rosenberg <drosen@google.com>
      [EB: improved comments and commit message, fixed checking return value
       of base64_decode(), check for SHA-256 error, continue to set disk_name
       for short names to keep matching simpler, and many other cleanups]
      Link: https://lore.kernel.org/r/20200120223201.241390-7-ebiggers@kernel.orgSigned-off-by: NEric Biggers <ebiggers@google.com>
      edc440e3
    • D
      fscrypt: derive dirhash key for casefolded directories · aa408f83
      Daniel Rosenberg 提交于
      When we allow indexed directories to use both encryption and
      casefolding, for the dirhash we can't just hash the ciphertext filenames
      that are stored on-disk (as is done currently) because the dirhash must
      be case insensitive, but the stored names are case-preserving.  Nor can
      we hash the plaintext names with an unkeyed hash (or a hash keyed with a
      value stored on-disk like ext4's s_hash_seed), since that would leak
      information about the names that encryption is meant to protect.
      
      Instead, if we can accept a dirhash that's only computable when the
      fscrypt key is available, we can hash the plaintext names with a keyed
      hash using a secret key derived from the directory's fscrypt master key.
      We'll use SipHash-2-4 for this purpose.
      
      Prepare for this by deriving a SipHash key for each casefolded encrypted
      directory.  Make sure to handle deriving the key not only when setting
      up the directory's fscrypt_info, but also in the case where the casefold
      flag is enabled after the fscrypt_info was already set up.  (We could
      just always derive the key regardless of casefolding, but that would
      introduce unnecessary overhead for people not using casefolding.)
      Signed-off-by: NDaniel Rosenberg <drosen@google.com>
      [EB: improved commit message, updated fscrypt.rst, squashed with change
       that avoids unnecessarily deriving the key, and many other cleanups]
      Link: https://lore.kernel.org/r/20200120223201.241390-3-ebiggers@kernel.orgSigned-off-by: NEric Biggers <ebiggers@google.com>
      aa408f83