CVE-2026-90276: md/md-llbitmap: stop daemon timer rearm on destroy
In the Linux kernel, the following vulnerability has been resolved:
md/md-llbitmap: stop daemon timer rearm on destroy
llbitmapdestroy() deletes pendingtimer before flushing mdllbitmapiowq. However, daemonwork can still be queued or running after the timer has been deleted, and the daemon path can arm pendingtimer again when it finds dirty chunks that are not ready to flush yet.
If that happens during teardown, pendingtimer can remain armed after llbitmap is freed and later dereference freed memory.
Add a BITMAPSHUTDOWN bit to llbitmap->flags, set it before deleting the timer, and make the timer and daemon paths stop queueing or rearming work once teardown starts. Cancel daemonwork before flushing the shared workqueue so no already queued daemon instance can race with the free. Use timershutdownsync() so a daemon instance that passed the shutdown check before teardown cannot rearm the timer afterward.
BITMAPSHUTDOWN is a runtime-only state. Mask it out when reading and updating the llbitmap superblock so the shutdown state is never loaded from disk or persisted to disk.
Affected Software
Event History
Frequently Asked Questions
Which deployments are affected by this issue?
The issue is in the Linux kernel md llbitmap code path. It can occur when an llbitmap is being torn down while its daemon work is queued or running.
What conditions are needed to trigger the use-after-free?
During teardown, the daemon path must find dirty chunks that are not ready to flush and rearm the pending timer after the llbitmap has been freed. This leaves a timer that can later dereference freed memory.
Does the shutdown state alter bitmap data stored on disk?
No. The BITMAP_SHUTDOWN state is runtime-only and is masked when llbitmap superblock state is read or updated, so it is neither loaded from nor persisted to disk.
What does the fix do to prevent the race?
It marks the bitmap as shutting down before timer deletion, prevents timer and daemon paths from queueing or rearming work, cancels queued daemon work, and uses timer_shutdown_sync() to prevent a concurrent daemon instance from rearming the timer.