linux/fs/crypto
Baokun Li cf66375465 fscrypt: Fix missing barrier in fscrypt_find_mode_key()
fscrypt_find_mode_key() walks an RCU list and hands out a per-mode
key without an acquire:

  setup task
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  setup_per_mode_enc_key()
   ├─ fscrypt_prepare_key()
   │  └─ fscrypt_prepare_inline_crypt_key()
   │     └─ blk_crypto_start_using_key()
   │        └─ blk_crypto_fallback_start_using_mode()
   │           ├─ init profile, keyslots, tfms[]
   │           └─ smp_store_release(tfms_inited[mode])  # init order
   └─ list_add_tail_rcu(&new_node->link, ...)  # release -> finder

  finding task (later submits the I/O itself)
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  fscrypt_find_mode_key()
   ├─ list_for_each_entry_rcu(node, ...)
   └─ return &node->key                 # no acquire, chain breaks
  ...
  blk_crypto_fallback_bio_prep()        # WRITE path
   ├─ tfms_inited[mode]                 # addr-dep, reads true
   ├─ blk_crypto_fallback_profile       # no dependency
   ├─ blk_crypto_keyslots               # no dependency
   └─ slotp->tfms[mode]                 # no dependency

RCU publishes the node and the key reachable from it, so
tfms_inited[mode] reads true through the address dependency.  The
independent fallback globals are not covered by it and can be read as
uninitialized.

On a weakly ordered machine, a WRITE bio can crash in
blk_crypto_get_keyslot() or crypto_sync_skcipher_setkey().

Other tasks reach the key through fscrypt_inode_info's
cmpxchg_release()/smp_load_acquire(), which is already ordered after
the list walk; only the finding task's own later I/O was not.

Fix this by upgrading the control dependency to an acquire with
smp_acquire__after_ctrl_dep() once a matching entry has been found.

Fixes: dd015b566d ("fscrypt: Fix key setup in edge case with multiple data unit sizes")
Cc: stable@vger.kernel.org
Suggested-by: Eric Biggers <ebiggers@kernel.org>
Link: https://lore.kernel.org/r/20261014161153.GC322435@quark
Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
Link: https://patch.msgid.link/20261024104350.2257313-1-libaokun@linux.alibaba.com
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
2026-10-24 10:59:58 -07:00
..
block.c fscrypt: Merge bio.c and inline_crypt.c into block.c 2026-07-20 10:39:26 -07:00
crypto.c mm.git review status for linus..mm-stable 2026-10-23 07:42:11 -10:00
fname.c fs: add helpers name_is_dot{,dot,_dotdot} 2026-01-29 10:06:59 +01:00
fscrypt_private.h fscrypt: Move several items from fscrypt_private.h to .c files 2026-09-25 13:40:12 -07:00
hkdf.c fscrypt: use HMAC-SHA512 library for HKDF 2025-09-05 21:01:51 -07:00
hooks.c fscrypt: Move several items from fscrypt_private.h to .c files 2026-09-25 13:40:12 -07:00
Kconfig fscrypt: Use aes_ecb_encrypt() for v1 key derivation 2026-09-17 19:20:33 -07:00
keyring.c fscrypt: Explicitly zeroize sw_secret in error path 2026-10-24 10:59:53 -07:00
keysetup_v1.c fscrypt: Use aes_ecb_encrypt() for v1 key derivation 2026-09-17 19:20:33 -07:00
keysetup.c fscrypt: Fix missing barrier in fscrypt_find_mode_key() 2026-10-24 10:59:58 -07:00
Makefile fscrypt: Merge bio.c and inline_crypt.c into block.c 2026-07-20 10:39:26 -07:00
policy.c fscrypt updates for 7.3 2026-08-17 19:04:16 -07:00