diff options
| author | Eric Biggers <ebiggers@kernel.org> | 2026-06-18 11:06:51 -0700 |
|---|---|---|
| committer | Eric Biggers <ebiggers@kernel.org> | 2026-06-22 12:12:11 -0700 |
| commit | dd015b566d505d698386103e9c80b739c7336eb8 (patch) | |
| tree | bab740f68bb70a0b57cf614687b754a9d41b901d /include/asm-i386/git@git.tavy.me:linux.git | |
| parent | 1dc18801be29bc54709aa355b8acd80e183b03cd (diff) | |
fscrypt: Fix key setup in edge case with multiple data unit sizes
The addition of support for customizable data unit sizes introduced an
edge case where a file's contents can be en/decrypted with the wrong
data unit size. It occurs when there are multiple v2 policies that:
- Have *different* data unit sizes, via the log2_data_unit_size field
- Share the same master_key_identifier, contents_encryption_mode, and
either FSCRYPT_POLICY_FLAG_DIRECT_KEY,
FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32, or
FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64
- Are being used on the same filesystem, which also must be mounted with
the "inlinecrypt" mount option.
Fortunately this edge case doesn't actually occur in practice. I just
found it via code review. But it needs to be fixed regardless.
The bug is caused by the data unit size not being fully considered when
blk_crypto_keys are cached in mk_direct_keys, mk_iv_ino_lblk_32_keys,
and mk_iv_ino_lblk_64_keys. They're differentiated only by master key,
encryption mode, and flag. However, each one actually has a data unit
size too. Only the first data unit size that is cached is used.
To fix this, start using the data unit size to differentiate the cached
keys. For several reasons, including avoiding increasing the size of
struct fscrypt_master_key, just replace all three arrays with a single
linked list instead of changing them into two-dimensional arrays. This
works well when considering that in practice at most 2 entries are used
across all three arrays, so it was already mostly wasted space.
For simplicity, make the list also take over the publish/subscribe of
the prepared key itself. That is, create separate list nodes for
blk_crypto_keys vs crypto_skciphers, and add nodes to the list only when
their key is actually prepared. (Note that the legacy
fscrypt_direct_keys table in fs/crypto/keysetup_v1.c already works this
way.) This eliminates the need for the additional memory barriers when
reading and writing the fields of struct fscrypt_prepared_key.
Note that I technically should have included the data unit size in the
HKDF info string as well. But it's too late to change that.
Fixes: 5b1188847180 ("fscrypt: support crypto data unit size less than filesystem block size")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260618180652.52742-1-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Diffstat (limited to 'include/asm-i386/git@git.tavy.me:linux.git')
0 files changed, 0 insertions, 0 deletions
