PT-2026-43816 · Linux · Linux
Published
2026-05-27
·
Updated
2026-05-27
·
CVE-2026-45949
None
No severity ratings or metrics are available. When they are, we'll update the corresponding info on the page.
In the Linux kernel, the following vulnerability has been resolved:
hwrng: core - use RCU and work struct to fix race condition
Currently, hwrng fill is not cleared until the hwrng fillfn() thread
exits. Since hwrng unregister() reads hwrng fill outside the rng mutex
lock, a concurrent hwrng unregister() may call kthread stop() again on
the same task.
Additionally, if hwrng unregister() is called immediately after
hwrng register(), the stopped thread may have never been executed. Thus,
hwrng fill remains dirty even after hwrng unregister() returns. In this
case, subsequent calls to hwrng register() will fail to start new
threads, and hwrng unregister() will call kthread stop() on the same
freed task. In both cases, a use-after-free occurs:
refcount t: addition on 0; use-after-free.
WARNING: ... at lib/refcount.c:25 refcount warn saturate+0xec/0x1c0
Call Trace:
kthread stop+0x181/0x360
hwrng unregister+0x288/0x380
virtrng remove+0xe3/0x200
This patch fixes the race by protecting the global hwrng fill pointer
inside the rng mutex lock, so that hwrng fillfn() thread is stopped only
once, and calls to kthread run() and kthread stop() are serialized
with the lock held.
To avoid deadlock in hwrng fillfn() while being stopped with the lock
held, we convert current rng to RCU, so that get current rng() can read
current rng without holding the lock. To remove the lock from put rng(),
we also delay the actual cleanup into a work struct.
Since get current rng() no longer returns ERR PTR values, the IS ERR()
checks are removed from its callers.
With hwrng fill protected by the rng mutex lock, hwrng fillfn() can no
longer clear hwrng fill itself. Therefore, if hwrng fillfn() returns
directly after current rng is dropped, kthread stop() would be called on
a freed task struct later. To fix this, hwrng fillfn() calls schedule()
now to keep the task alive until being stopped. The kthread stop() call
is also moved from hwrng unregister() to drop current rng(), ensuring
kthread stop() is called on all possible paths where current rng becomes
NULL, so that the thread would not wait forever.
Found an issue in the description? Have something to add? Feel free to write us 👾
Related Identifiers
Affected Products
Linux