18 Mar, 2020

1 commit

  • commit 2b4eae95c7361e0a147b838715c8baa1380a428f upstream.

    After FS_IOC_REMOVE_ENCRYPTION_KEY removes a key, it syncs the
    filesystem and tries to get and put all inodes that were unlocked by the
    key so that unused inodes get evicted via fscrypt_drop_inode().
    Normally, the inodes are all clean due to the sync.

    However, after the filesystem is sync'ed, userspace can modify and close
    one of the files. (Userspace is *supposed* to close the files before
    removing the key. But it doesn't always happen, and the kernel can't
    assume it.) This causes the inode to be dirtied and have i_count == 0.
    Then, fscrypt_drop_inode() failed to consider this case and indicated
    that the inode can be dropped, causing the write to be lost.

    On f2fs, other problems such as a filesystem freeze could occur due to
    the inode being freed while still on f2fs's dirty inode list.

    Fix this bug by making fscrypt_drop_inode() only drop clean inodes.

    I've written an xfstest which detects this bug on ext4, f2fs, and ubifs.

    Fixes: b1c0ec3599f4 ("fscrypt: add FS_IOC_REMOVE_ENCRYPTION_KEY ioctl")
    Cc: # v5.4+
    Link: https://lore.kernel.org/r/20200305084138.653498-1-ebiggers@kernel.org
    Signed-off-by: Eric Biggers
    Signed-off-by: Greg Kroah-Hartman

    Eric Biggers
     

11 Feb, 2020

1 commit

  • commit 13a10da94615d81087e718517794f2868a8b3fab upstream.

    When an encryption key can't be fully removed due to file(s) protected
    by it still being in-use, we shouldn't really print the path to one of
    these files to the kernel log, since parts of this path are likely to be
    encrypted on-disk, and (depending on how the system is set up) the
    confidentiality of this path might be lost by printing it to the log.

    This is a trade-off: a single file path often doesn't matter at all,
    especially if it's a directory; the kernel log might still be protected
    in some way; and I had originally hoped that any "inode(s) still busy"
    bugs (which are security weaknesses in their own right) would be quickly
    fixed and that to do so it would be super helpful to always know the
    file path and not have to run 'find dir -inum $inum' after the fact.

    But in practice, these bugs can be hard to fix (e.g. due to asynchronous
    process killing that is difficult to eliminate, for performance
    reasons), and also not tied to specific files, so knowing a file path
    doesn't necessarily help.

    So to be safe, for now let's just show the inode number, not the path.
    If someone really wants to know a path they can use 'find -inum'.

    Fixes: b1c0ec3599f4 ("fscrypt: add FS_IOC_REMOVE_ENCRYPTION_KEY ioctl")
    Cc: # v5.4+
    Link: https://lore.kernel.org/r/20200120060732.390362-1-ebiggers@kernel.org
    Signed-off-by: Eric Biggers
    Signed-off-by: Greg Kroah-Hartman

    Eric Biggers
     

13 Aug, 2019

20 commits

  • By looking up the master keys in a filesystem-level keyring rather than
    in the calling processes' key hierarchy, it becomes possible for a user
    to set an encryption policy which refers to some key they don't actually
    know, then encrypt their files using that key. Cryptographically this
    isn't much of a problem, but the semantics of this would be a bit weird.
    Thus, enforce that a v2 encryption policy can only be set if the user
    has previously added the key, or has capable(CAP_FOWNER).

    We tolerate that this problem will continue to exist for v1 encryption
    policies, however; there is no way around that.

    Reviewed-by: Theodore Ts'o
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Add a root-only variant of the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl which
    removes all users' claims of the key, not just the current user's claim.
    I.e., it always removes the key itself, no matter how many users have
    added it.

    This is useful for forcing a directory to be locked, without having to
    figure out which user ID(s) the key was added under. This is planned to
    be used by a command like 'sudo fscrypt lock DIR --all-users' in the
    fscrypt userspace tool (http://github.com/google/fscrypt).

    Reviewed-by: Theodore Ts'o
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Allow the FS_IOC_ADD_ENCRYPTION_KEY and FS_IOC_REMOVE_ENCRYPTION_KEY
    ioctls to be used by non-root users to add and remove encryption keys
    from the filesystem-level crypto keyrings, subject to limitations.

    Motivation: while privileged fscrypt key management is sufficient for
    some users (e.g. Android and Chromium OS, where a privileged process
    manages all keys), the old API by design also allows non-root users to
    set up and use encrypted directories, and we don't want to regress on
    that. Especially, we don't want to force users to continue using the
    old API, running into the visibility mismatch between files and keyrings
    and being unable to "lock" encrypted directories.

    Intuitively, the ioctls have to be privileged since they manipulate
    filesystem-level state. However, it's actually safe to make them
    unprivileged if we very carefully enforce some specific limitations.

    First, each key must be identified by a cryptographic hash so that a
    user can't add the wrong key for another user's files. For v2
    encryption policies, we use the key_identifier for this. v1 policies
    don't have this, so managing keys for them remains privileged.

    Second, each key a user adds is charged to their quota for the keyrings
    service. Thus, a user can't exhaust memory by adding a huge number of
    keys. By default each non-root user is allowed up to 200 keys; this can
    be changed using the existing sysctl 'kernel.keys.maxkeys'.

    Third, if multiple users add the same key, we keep track of those users
    of the key (of which there remains a single copy), and won't really
    remove the key, i.e. "lock" the encrypted files, until all those users
    have removed it. This prevents denial of service attacks that would be
    possible under simpler schemes, such allowing the first user who added a
    key to remove it -- since that could be a malicious user who has
    compromised the key. Of course, encryption keys should be kept secret,
    but the idea is that using encryption should never be *less* secure than
    not using encryption, even if your key was compromised.

    We tolerate that a user will be unable to really remove a key, i.e.
    unable to "lock" their encrypted files, if another user has added the
    same key. But in a sense, this is actually a good thing because it will
    avoid providing a false notion of security where a key appears to have
    been removed when actually it's still in memory, available to any
    attacker who compromises the operating system kernel.

    Reviewed-by: Theodore Ts'o
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Add a new fscrypt policy version, "v2". It has the following changes
    from the original policy version, which we call "v1" (*):

    - Master keys (the user-provided encryption keys) are only ever used as
    input to HKDF-SHA512. This is more flexible and less error-prone, and
    it avoids the quirks and limitations of the AES-128-ECB based KDF.
    Three classes of cryptographically isolated subkeys are defined:

    - Per-file keys, like used in v1 policies except for the new KDF.

    - Per-mode keys. These implement the semantics of the DIRECT_KEY
    flag, which for v1 policies made the master key be used directly.
    These are also planned to be used for inline encryption when
    support for it is added.

    - Key identifiers (see below).

    - Each master key is identified by a 16-byte master_key_identifier,
    which is derived from the key itself using HKDF-SHA512. This prevents
    users from associating the wrong key with an encrypted file or
    directory. This was easily possible with v1 policies, which
    identified the key by an arbitrary 8-byte master_key_descriptor.

    - The key must be provided in the filesystem-level keyring, not in a
    process-subscribed keyring.

    The following UAPI additions are made:

    - The existing ioctl FS_IOC_SET_ENCRYPTION_POLICY can now be passed a
    fscrypt_policy_v2 to set a v2 encryption policy. It's disambiguated
    from fscrypt_policy/fscrypt_policy_v1 by the version code prefix.

    - A new ioctl FS_IOC_GET_ENCRYPTION_POLICY_EX is added. It allows
    getting the v1 or v2 encryption policy of an encrypted file or
    directory. The existing FS_IOC_GET_ENCRYPTION_POLICY ioctl could not
    be used because it did not have a way for userspace to indicate which
    policy structure is expected. The new ioctl includes a size field, so
    it is extensible to future fscrypt policy versions.

    - The ioctls FS_IOC_ADD_ENCRYPTION_KEY, FS_IOC_REMOVE_ENCRYPTION_KEY,
    and FS_IOC_GET_ENCRYPTION_KEY_STATUS now support managing keys for v2
    encryption policies. Such keys are kept logically separate from keys
    for v1 encryption policies, and are identified by 'identifier' rather
    than by 'descriptor'. The 'identifier' need not be provided when
    adding a key, since the kernel will calculate it anyway.

    This patch temporarily keeps adding/removing v2 policy keys behind the
    same permission check done for adding/removing v1 policy keys:
    capable(CAP_SYS_ADMIN). However, the next patch will carefully take
    advantage of the cryptographically secure master_key_identifier to allow
    non-root users to add/remove v2 policy keys, thus providing a full
    replacement for v1 policies.

    (*) Actually, in the API fscrypt_policy::version is 0 while on-disk
    fscrypt_context::format is 1. But I believe it makes the most sense
    to advance both to '2' to have them be in sync, and to consider the
    numbering to start at 1 except for the API quirk.

    Reviewed-by: Paul Crowley
    Reviewed-by: Theodore Ts'o
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Add an implementation of HKDF (RFC 5869) to fscrypt, for the purpose of
    deriving additional key material from the fscrypt master keys for v2
    encryption policies. HKDF is a key derivation function built on top of
    HMAC. We choose SHA-512 for the underlying unkeyed hash, and use an
    "hmac(sha512)" transform allocated from the crypto API.

    We'll be using this to replace the AES-ECB based KDF currently used to
    derive the per-file encryption keys. While the AES-ECB based KDF is
    believed to meet the original security requirements, it is nonstandard
    and has problems that don't exist in modern KDFs such as HKDF:

    1. It's reversible. Given a derived key and nonce, an attacker can
    easily compute the master key. This is okay if the master key and
    derived keys are equally hard to compromise, but now we'd like to be
    more robust against threats such as a derived key being compromised
    through a timing attack, or a derived key for an in-use file being
    compromised after the master key has already been removed.

    2. It doesn't evenly distribute the entropy from the master key; each 16
    input bytes only affects the corresponding 16 output bytes.

    3. It isn't easily extensible to deriving other values or keys, such as
    a public hash for securely identifying the key, or per-mode keys.
    Per-mode keys will be immediately useful for Adiantum encryption, for
    which fscrypt currently uses the master key directly, introducing
    unnecessary usage constraints. Per-mode keys will also be useful for
    hardware inline encryption, which is currently being worked on.

    HKDF solves all the above problems.

    Reviewed-by: Paul Crowley
    Reviewed-by: Theodore Ts'o
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Add a new fscrypt ioctl, FS_IOC_GET_ENCRYPTION_KEY_STATUS. Given a key
    specified by 'struct fscrypt_key_specifier' (the same way a key is
    specified for the other fscrypt key management ioctls), it returns
    status information in a 'struct fscrypt_get_key_status_arg'.

    The main motivation for this is that applications need to be able to
    check whether an encrypted directory is "unlocked" or not, so that they
    can add the key if it is not, and avoid adding the key (which may
    involve prompting the user for a passphrase) if it already is.

    It's possible to use some workarounds such as checking whether opening a
    regular file fails with ENOKEY, or checking whether the filenames "look
    like gibberish" or not. However, no workaround is usable in all cases.

    Like the other key management ioctls, the keyrings syscalls may seem at
    first to be a good fit for this. Unfortunately, they are not. Even if
    we exposed the keyring ID of the ->s_master_keys keyring and gave
    everyone Search permission on it (note: currently the keyrings
    permission system would also allow everyone to "invalidate" the keyring
    too), the fscrypt keys have an additional state that doesn't map cleanly
    to the keyrings API: the secret can be removed, but we can be still
    tracking the files that were using the key, and the removal can be
    re-attempted or the secret added again.

    After later patches, some applications will also need a way to determine
    whether a key was added by the current user vs. by some other user.
    Reserved fields are included in fscrypt_get_key_status_arg for this and
    other future extensions.

    Reviewed-by: Theodore Ts'o
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Add a new fscrypt ioctl, FS_IOC_REMOVE_ENCRYPTION_KEY. This ioctl
    removes an encryption key that was added by FS_IOC_ADD_ENCRYPTION_KEY.
    It wipes the secret key itself, then "locks" the encrypted files and
    directories that had been unlocked using that key -- implemented by
    evicting the relevant dentries and inodes from the VFS caches.

    The problem this solves is that many fscrypt users want the ability to
    remove encryption keys, causing the corresponding encrypted directories
    to appear "locked" (presented in ciphertext form) again. Moreover,
    users want removing an encryption key to *really* remove it, in the
    sense that the removed keys cannot be recovered even if kernel memory is
    compromised, e.g. by the exploit of a kernel security vulnerability or
    by a physical attack. This is desirable after a user logs out of the
    system, for example. In many cases users even already assume this to be
    the case and are surprised to hear when it's not.

    It is not sufficient to simply unlink the master key from the keyring
    (or to revoke or invalidate it), since the actual encryption transform
    objects are still pinned in memory by their inodes. Therefore, to
    really remove a key we must also evict the relevant inodes.

    Currently one workaround is to run 'sync && echo 2 >
    /proc/sys/vm/drop_caches'. But, that evicts all unused inodes in the
    system rather than just the inodes associated with the key being
    removed, causing severe performance problems. Moreover, it requires
    root privileges, so regular users can't "lock" their encrypted files.

    Another workaround, used in Chromium OS kernels, is to add a new
    VFS-level ioctl FS_IOC_DROP_CACHE which is a more restricted version of
    drop_caches that operates on a single super_block. It does:

    shrink_dcache_sb(sb);
    invalidate_inodes(sb, false);

    But it's still a hack. Yet, the major users of filesystem encryption
    want this feature badly enough that they are actually using these hacks.

    To properly solve the problem, start maintaining a list of the inodes
    which have been "unlocked" using each master key. Originally this
    wasn't possible because the kernel didn't keep track of in-use master
    keys at all. But, with the ->s_master_keys keyring it is now possible.

    Then, add an ioctl FS_IOC_REMOVE_ENCRYPTION_KEY. It finds the specified
    master key in ->s_master_keys, then wipes the secret key itself, which
    prevents any additional inodes from being unlocked with the key. Then,
    it syncs the filesystem and evicts the inodes in the key's list. The
    normal inode eviction code will free and wipe the per-file keys (in
    ->i_crypt_info). Note that freeing ->i_crypt_info without evicting the
    inodes was also considered, but would have been racy.

    Some inodes may still be in use when a master key is removed, and we
    can't simply revoke random file descriptors, mmap's, etc. Thus, the
    ioctl simply skips in-use inodes, and returns -EBUSY to indicate that
    some inodes weren't evicted. The master key *secret* is still removed,
    but the fscrypt_master_key struct remains to keep track of the remaining
    inodes. Userspace can then retry the ioctl to evict the remaining
    inodes. Alternatively, if userspace adds the key again, the refreshed
    secret will be associated with the existing list of inodes so they
    remain correctly tracked for future key removals.

    The ioctl doesn't wipe pagecache pages. Thus, we tolerate that after a
    kernel compromise some portions of plaintext file contents may still be
    recoverable from memory. This can be solved by enabling page poisoning
    system-wide, which security conscious users may choose to do. But it's
    very difficult to solve otherwise, e.g. note that plaintext file
    contents may have been read in other places than pagecache pages.

    Like FS_IOC_ADD_ENCRYPTION_KEY, FS_IOC_REMOVE_ENCRYPTION_KEY is
    initially restricted to privileged users only. This is sufficient for
    some use cases, but not all. A later patch will relax this restriction,
    but it will require introducing key hashes, among other changes.

    Reviewed-by: Theodore Ts'o
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Add a new fscrypt ioctl, FS_IOC_ADD_ENCRYPTION_KEY. This ioctl adds an
    encryption key to the filesystem's fscrypt keyring ->s_master_keys,
    making any files encrypted with that key appear "unlocked".

    Why we need this
    ~~~~~~~~~~~~~~~~

    The main problem is that the "locked/unlocked" (ciphertext/plaintext)
    status of encrypted files is global, but the fscrypt keys are not.
    fscrypt only looks for keys in the keyring(s) the process accessing the
    filesystem is subscribed to: the thread keyring, process keyring, and
    session keyring, where the session keyring may contain the user keyring.

    Therefore, userspace has to put fscrypt keys in the keyrings for
    individual users or sessions. But this means that when a process with a
    different keyring tries to access encrypted files, whether they appear
    "unlocked" or not is nondeterministic. This is because it depends on
    whether the files are currently present in the inode cache.

    Fixing this by consistently providing each process its own view of the
    filesystem depending on whether it has the key or not isn't feasible due
    to how the VFS caches work. Furthermore, while sometimes users expect
    this behavior, it is misguided for two reasons. First, it would be an
    OS-level access control mechanism largely redundant with existing access
    control mechanisms such as UNIX file permissions, ACLs, LSMs, etc.
    Encryption is actually for protecting the data at rest.

    Second, almost all users of fscrypt actually do need the keys to be
    global. The largest users of fscrypt, Android and Chromium OS, achieve
    this by having PID 1 create a "session keyring" that is inherited by
    every process. This works, but it isn't scalable because it prevents
    session keyrings from being used for any other purpose.

    On general-purpose Linux distros, the 'fscrypt' userspace tool [1] can't
    similarly abuse the session keyring, so to make 'sudo' work on all
    systems it has to link all the user keyrings into root's user keyring
    [2]. This is ugly and raises security concerns. Moreover it can't make
    the keys available to system services, such as sshd trying to access the
    user's '~/.ssh' directory (see [3], [4]) or NetworkManager trying to
    read certificates from the user's home directory (see [5]); or to Docker
    containers (see [6], [7]).

    By having an API to add a key to the *filesystem* we'll be able to fix
    the above bugs, remove userspace workarounds, and clearly express the
    intended semantics: the locked/unlocked status of an encrypted directory
    is global, and encryption is orthogonal to OS-level access control.

    Why not use the add_key() syscall
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    We use an ioctl for this API rather than the existing add_key() system
    call because the ioctl gives us the flexibility needed to implement
    fscrypt-specific semantics that will be introduced in later patches:

    - Supporting key removal with the semantics such that the secret is
    removed immediately and any unused inodes using the key are evicted;
    also, the eviction of any in-use inodes can be retried.

    - Calculating a key-dependent cryptographic identifier and returning it
    to userspace.

    - Allowing keys to be added and removed by non-root users, but only keys
    for v2 encryption policies; and to prevent denial-of-service attacks,
    users can only remove keys they themselves have added, and a key is
    only really removed after all users who added it have removed it.

    Trying to shoehorn these semantics into the keyrings syscalls would be
    very difficult, whereas the ioctls make things much easier.

    However, to reuse code the implementation still uses the keyrings
    service internally. Thus we get lockless RCU-mode key lookups without
    having to re-implement it, and the keys automatically show up in
    /proc/keys for debugging purposes.

    References:

    [1] https://github.com/google/fscrypt
    [2] https://goo.gl/55cCrI#heading=h.vf09isp98isb
    [3] https://github.com/google/fscrypt/issues/111#issuecomment-444347939
    [4] https://github.com/google/fscrypt/issues/116
    [5] https://bugs.launchpad.net/ubuntu/+source/fscrypt/+bug/1770715
    [6] https://github.com/google/fscrypt/issues/128
    [7] https://askubuntu.com/questions/1130306/cannot-run-docker-on-an-encrypted-filesystem

    Reviewed-by: Theodore Ts'o
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Rename keyinfo.c to keysetup.c since this better describes what the file
    does (sets up the key), and it matches the new file keysetup_v1.c.

    Reviewed-by: Theodore Ts'o
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • In preparation for introducing v2 encryption policies which will find
    and derive encryption keys differently from the current v1 encryption
    policies, move the v1 policy-specific key setup code from keyinfo.c into
    keysetup_v1.c.

    Reviewed-by: Theodore Ts'o
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Do some more refactoring of the key setup code, in preparation for
    introducing a filesystem-level keyring and v2 encryption policies:

    - Now that ci_inode exists, don't pass around the inode unnecessarily.

    - Define a function setup_file_encryption_key() which handles the crypto
    key setup given an under-construction fscrypt_info. Don't pass the
    fscrypt_context, since everything is in the fscrypt_info.
    [This will be extended for v2 policies and the fs-level keyring.]

    - Define a function fscrypt_set_derived_key() which sets the per-file
    key, without depending on anything specific to v1 policies.
    [This will also be used for v2 policies.]

    - Define a function fscrypt_setup_v1_file_key() which takes the raw
    master key, thus separating finding the key from using it.
    [This will also be used if the key is found in the fs-level keyring.]

    Reviewed-by: Theodore Ts'o
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • In preparation for introducing a filesystem-level keyring which will
    contain fscrypt master keys, rename the existing 'struct
    fscrypt_master_key' to 'struct fscrypt_direct_key'. This is the
    structure in the existing table of master keys that's maintained to
    deduplicate the crypto transforms for v1 DIRECT_KEY policies.

    I've chosen to keep this table as-is rather than make it automagically
    add/remove the keys to/from the filesystem-level keyring, since that
    would add a lot of extra complexity to the filesystem-level keyring.

    Reviewed-by: Theodore Ts'o
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Add an inode back-pointer to 'struct fscrypt_info', such that
    inode->i_crypt_info->ci_inode == inode.

    This will be useful for:

    1. Evicting the inodes when a fscrypt key is removed, since we'll track
    the inodes using a given key by linking their fscrypt_infos together,
    rather than the inodes directly. This avoids bloating 'struct inode'
    with a new list_head.

    2. Simplifying the per-file key setup, since the inode pointer won't
    have to be passed around everywhere just in case something goes wrong
    and it's needed for fscrypt_warn().

    Reviewed-by: Theodore Ts'o
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Update fs/crypto/ to use the new names for the UAPI constants rather
    than the old names, then make the old definitions conditional on
    !__KERNEL__.

    Reviewed-by: Theodore Ts'o
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Return ENOPKG rather than ENOENT when trying to open a file that's
    encrypted using algorithms not available in the kernel's crypto API.

    This avoids an ambiguity, since ENOENT is also returned when the file
    doesn't exist.

    Note: this is the same approach I'm taking for fs-verity.

    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Users of fscrypt with non-default algorithms will encounter an error
    like the following if they fail to include the needed algorithms into
    the crypto API when configuring the kernel (as per the documentation):

    Error allocating 'adiantum(xchacha12,aes)' transform: -2

    This requires that the user figure out what the "-2" error means.
    Make it more friendly by printing a warning like the following instead:

    Missing crypto API support for Adiantum (API name: "adiantum(xchacha12,aes)")

    Also upgrade the log level for *other* errors to KERN_ERR.

    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • When fs/crypto/ encounters an inode with an invalid encryption context,
    currently it prints a warning if the pair of encryption modes are
    unrecognized, but it's silent if there are other problems such as
    unsupported context size, format, or flags. To help people debug such
    situations, add more warning messages.

    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Most of the warning and error messages in fs/crypto/ are for situations
    related to a specific inode, not merely to a super_block. So to make
    things easier, make fscrypt_msg() take an inode rather than a
    super_block, and make it print the inode number.

    Note: This is the same approach I'm taking for fsverity_msg().

    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Some minor cleanups for the code that base64 encodes and decodes
    encrypted filenames and long name digests:

    - Rename "digest_{encode,decode}()" => "base64_{encode,decode}()" since
    they are used for filenames too, not just for long name digests.
    - Replace 'while' loops with more conventional 'for' loops.
    - Use 'u8' for binary data. Keep 'char' for string data.
    - Fully constify the lookup table (pointer was not const).
    - Improve comment.

    No actual change in behavior.

    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Since commit 643fa9612bf1 ("fscrypt: remove filesystem specific build
    config option"), fs/crypto/ can no longer be built as a loadable module.
    Thus it no longer needs a module_exit function, nor a MODULE_LICENSE.
    So remove them, and change module_init to late_initcall.

    Reviewed-by: Chandan Rajendra
    Signed-off-by: Eric Biggers

    Eric Biggers
     

28 Jun, 2019

1 commit

  • fscrypt only uses SHA-256 for AES-128-CBC-ESSIV, which isn't the default
    and is only recommended on platforms that have hardware accelerated
    AES-CBC but not AES-XTS. There's no link-time dependency, since SHA-256
    is requested via the crypto API on first use.

    To reduce bloat, we should limit FS_ENCRYPTION to selecting the default
    algorithms only. SHA-256 by itself isn't that much bloat, but it's
    being discussed to move ESSIV into a crypto API template, which would
    incidentally bring in other things like "authenc" support, which would
    all end up being built-in since FS_ENCRYPTION is now a bool.

    For Adiantum encryption we already just document that users who want to
    use it have to enable CONFIG_CRYPTO_ADIANTUM themselves. So, let's do
    the same for AES-128-CBC-ESSIV and CONFIG_CRYPTO_SHA256.

    Acked-by: Ard Biesheuvel
    Reviewed-by: Theodore Ts'o
    Signed-off-by: Eric Biggers

    Eric Biggers
     

11 Jun, 2019

1 commit


29 May, 2019

11 commits

  • The directory may have been removed when entering
    fscrypt_ioctl_set_policy(). If so, the empty_dir() check will return
    error for ext4 file system.

    ext4_rmdir() sets i_size = 0, then ext4_empty_dir() reports an error
    because 'inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2)'. If
    the fs is mounted with errors=panic, it will trigger a panic issue.

    Add the check IS_DEADDIR() to fix this problem.

    Fixes: 9bd8212f981e ("ext4 crypto: add encryption policy and password salt support")
    Cc: # v4.1+
    Signed-off-by: Hongjie Fang
    Signed-off-by: Eric Biggers

    Hongjie Fang
     
  • In __fscrypt_decrypt_bio(), only decrypt the blocks that actually
    comprise the bio, rather than assuming blocksize == PAGE_SIZE and
    decrypting the entirety of every page used in the bio.

    This is in preparation for allowing encryption on ext4 filesystems with
    blocksize != PAGE_SIZE.

    This is based on work by Chandan Rajendra.

    Reviewed-by: Chandan Rajendra
    Signed-off-by: Eric Biggers

    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: Chandan Rajendra
    Signed-off-by: Eric Biggers

    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: Chandan Rajendra
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Adjust fscrypt_zeroout_range() to encrypt a block at a time rather than
    a page at a time, so that it works when blocksize < PAGE_SIZE.

    This isn't optimized for performance, but then again this function
    already wasn't optimized for performance. As a future optimization, we
    could submit much larger bios here.

    This is in preparation for allowing encryption on ext4 filesystems with
    blocksize != PAGE_SIZE.

    This is based on work by Chandan Rajendra.

    Reviewed-by: Chandan Rajendra
    Signed-off-by: Eric Biggers

    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: Chandan Rajendra
    Signed-off-by: Eric Biggers

    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: Chandan Rajendra
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Replace some BUG_ON()s with WARN_ON_ONCE() and returning an error code,
    and move the check for len divisible by FS_CRYPTO_BLOCK_SIZE into
    fscrypt_crypt_block() so that it's done for both encryption and
    decryption, not just encryption.

    Reviewed-by: Chandan Rajendra
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • fscrypt_do_page_crypto() only does a single encryption or decryption
    operation, with a single logical block number (single IV). So it
    actually operates on a filesystem block, not a "page" per se. To
    reflect this, rename it to fscrypt_crypt_block().

    Reviewed-by: Chandan Rajendra
    Signed-off-by: Eric Biggers

    Eric Biggers
     
  • Now that fscrypt_ctx is not used for writes, remove the 'w' fields.

    Reviewed-by: Chandan Rajendra
    Signed-off-by: Eric Biggers

    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: Chandan Rajendra
    Signed-off-by: Eric Biggers

    Eric Biggers
     

21 May, 2019

3 commits

  • Add SPDX license identifiers to all Make/Kconfig files which:

    - Have no license information of any form

    These files fall under the project license, GPL v2 only. The resulting SPDX
    license identifier is:

    GPL-2.0-only

    Signed-off-by: Thomas Gleixner
    Signed-off-by: Greg Kroah-Hartman

    Thomas Gleixner
     
  • Add SPDX license identifiers to all files which:

    - Have no license information of any form

    - Have MODULE_LICENCE("GPL*") inside which was used in the initial
    scan/conversion to ignore the file

    These files fall under the project license, GPL v2 only. The resulting SPDX
    license identifier is:

    GPL-2.0-only

    Signed-off-by: Thomas Gleixner
    Signed-off-by: Greg Kroah-Hartman

    Thomas Gleixner
     
  • Add SPDX license identifiers to all files which:

    - Have no license information of any form

    - Have EXPORT_.*_SYMBOL_GPL inside which was used in the
    initial scan/conversion to ignore the file

    These files fall under the project license, GPL v2 only. The resulting SPDX
    license identifier is:

    GPL-2.0-only

    Signed-off-by: Thomas Gleixner
    Signed-off-by: Greg Kroah-Hartman

    Thomas Gleixner
     

08 May, 2019

2 commits

  • Pull fscrypt updates from Ted Ts'o:
    "Clean up fscrypt's dcache revalidation support, and other
    miscellaneous cleanups"

    * tag 'fscrypt_for_linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt:
    fscrypt: cache decrypted symlink target in ->i_link
    vfs: use READ_ONCE() to access ->i_link
    fscrypt: fix race where ->lookup() marks plaintext dentry as ciphertext
    fscrypt: only set dentry_operations on ciphertext dentries
    fs, fscrypt: clear DCACHE_ENCRYPTED_NAME when unaliasing directory
    fscrypt: fix race allowing rename() and link() of ciphertext dentries
    fscrypt: clean up and improve dentry revalidation
    fscrypt: use READ_ONCE() to access ->i_crypt_info
    fscrypt: remove WARN_ON_ONCE() when decryption fails
    fscrypt: drop inode argument from fscrypt_get_ctx()

    Linus Torvalds
     
  • Pull block updates from Jens Axboe:
    "Nothing major in this series, just fixes and improvements all over the
    map. This contains:

    - Series of fixes for sed-opal (David, Jonas)

    - Fixes and performance tweaks for BFQ (via Paolo)

    - Set of fixes for bcache (via Coly)

    - Set of fixes for md (via Song)

    - Enabling multi-page for passthrough requests (Ming)

    - Queue release fix series (Ming)

    - Device notification improvements (Martin)

    - Propagate underlying device rotational status in loop (Holger)

    - Removal of mtip32xx trim support, which has been disabled for years
    (Christoph)

    - Improvement and cleanup of nvme command handling (Christoph)

    - Add block SPDX tags (Christoph)

    - Cleanup/hardening of bio/bvec iteration (Christoph)

    - A few NVMe pull requests (Christoph)

    - Removal of CONFIG_LBDAF (Christoph)

    - Various little fixes here and there"

    * tag 'for-5.2/block-20190507' of git://git.kernel.dk/linux-block: (164 commits)
    block: fix mismerge in bvec_advance
    block: don't drain in-progress dispatch in blk_cleanup_queue()
    blk-mq: move cancel of hctx->run_work into blk_mq_hw_sysfs_release
    blk-mq: always free hctx after request queue is freed
    blk-mq: split blk_mq_alloc_and_init_hctx into two parts
    blk-mq: free hw queue's resource in hctx's release handler
    blk-mq: move cancel of requeue_work into blk_mq_release
    blk-mq: grab .q_usage_counter when queuing request from plug code path
    block: fix function name in comment
    nvmet: protect discovery change log event list iteration
    nvme: mark nvme_core_init and nvme_core_exit static
    nvme: move command size checks to the core
    nvme-fabrics: check more command sizes
    nvme-pci: check more command sizes
    nvme-pci: remove an unneeded variable initialization
    nvme-pci: unquiesce admin queue on shutdown
    nvme-pci: shutdown on timeout during deletion
    nvme-pci: fix psdt field for single segment sgls
    nvme-multipath: don't print ANA group state by default
    nvme-multipath: split bios with the ns_head bio_set before submitting
    ...

    Linus Torvalds