mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 13:14:02 +02:00
keys: fix lost wakeup when reaping a dead key type
clear_bit() is atomic with respect to the word it modifies, but it is
an unordered operation: it implies no memory barrier on either side
(Documentation/atomic_bitops.txt).
key_garbage_collector() clears KEY_GC_REAPING_KEYTYPE with clear_bit()
and calls wake_up_bit() after reaping a dead key type. wake_up_bit()
uses a lockless waitqueue check and requires a full barrier after the
clear.
The existing smp_mb() is before clear_bit(), so nothing orders the clear
against that check. The GC can see an empty waitqueue while
unregister_key_type() still sees the bit set. The final wakeup is then
lost, leaving module unload stuck in wait_on_bit().
Use clear_and_wake_up_bit(). Its clear_bit_unlock() has RELEASE
semantics, so the completed GC work stays ordered before the clear, and
its smp_mb__after_atomic() orders the clear before the waitqueue check.
Fixes: 0c061b5707 ("KEYS: Correctly destroy key payloads when their keytype is removed")
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://lore.kernel.org/r/20260821025327.61488-1-kmehltretter@gmail.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
This commit is contained in:
parent
827751b699
commit
2725ab3f5a
|
|
@ -318,9 +318,7 @@ static void key_garbage_collector(struct work_struct *work)
|
|||
|
||||
if (unlikely(gc_state & KEY_GC_REAPING_DEAD_3)) {
|
||||
kdebug("dead wake");
|
||||
smp_mb();
|
||||
clear_bit(KEY_GC_REAPING_KEYTYPE, &key_gc_flags);
|
||||
wake_up_bit(&key_gc_flags, KEY_GC_REAPING_KEYTYPE);
|
||||
clear_and_wake_up_bit(KEY_GC_REAPING_KEYTYPE, &key_gc_flags);
|
||||
}
|
||||
|
||||
if (gc_state & KEY_GC_REAP_AGAIN)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user