mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
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>
This commit is contained in:
parent
2c3afbb5c7
commit
cf66375465
|
|
@ -205,8 +205,14 @@ fscrypt_find_mode_key(struct fscrypt_master_key *mk, u8 hkdf_context,
|
|||
if (node->hkdf_context == hkdf_context &&
|
||||
node->mode_num == mode_num &&
|
||||
node->data_unit_bits == ci->ci_data_unit_bits &&
|
||||
fscrypt_is_key_prepared(&node->key, ci))
|
||||
fscrypt_is_key_prepared(&node->key, ci)) {
|
||||
/*
|
||||
* Upgrade the RCU dereference to a full ACQUIRE, so
|
||||
* that blk-crypto global state is seen as initialized.
|
||||
*/
|
||||
smp_acquire__after_ctrl_dep();
|
||||
return &node->key;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user