CVE-2026-45949CWE-362

CVE-2026-45949

Medium · published May 27, 2026

CVSS v3.1
4.7
EPSS
0%
Percentile
1.1
In the wild
Unconfirmed
What it is

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.

The record
Technical detail
CVSS v3.1
4.7 · MEDIUM
Vector
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H
CVSS v4.0
Not supplied
EPSS
0.00107 · 1.1th percentile
Weakness
CWE-362 · Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')
Published
2026-05-27T18:17Z
Affected products (3)
ProductVersionsFixed in
linux/linux_kernel≥ 3.17, < 6.12.756.12.75
linux/linux_kernel≥ 6.13, < 6.18.146.18.14
linux/linux_kernel≥ 6.19, < 6.19.46.19.4
References (5)
EPSS history
Timeline
  • 27 MAY 12:18Z
    hwrng: core - use RCU and work_struct to fix race condition
    cvelistv5