CVE-2026-97619: io_uring/rw: end write accounting from ->ki_complete
In the Linux kernel, the following vulnerability has been resolved:
iouring/rw: end write accounting from ->kicomplete
Commit b000145e9907 moved both the fsnotify calls and the write accounting out of the kiocb completion handler and into the ioreqrwcomplete() taskwork. However, only the fsnotify part actually needed to move as it may sleep. Ending the write accounting is just a percpuupread() on the superblock writers sem.
Deferring it is a problem, because it makes dropping SBFREEZEWRITE protection depend on the ring owner getting to running taskwork. But the task may be blocked in freezesuper(), causing it to never get to that:
task io-wq worker -------------------------------------------------------------- iowrite() iokiocbstartwrite() (takes sbwriters, hidden from lockdep by sbwritersrelease) writeiter() -> -EIOCBQUEUED ioctl(FSIOCSHUTDOWN) bdevfreeze() freezesuper() percpudownwrite() <- waits for the reader above iowrite() kiocbstartwrite() percpudownread() <- queued behind the writer <bio completes> iocompleterw() queues ioreqrwcomplete() <- never runs, task is in D state
End the write from iocompleterw() instead, and leave only the fsnotify calls in taskwork.
Affected Software
Event History
Frequently Asked Questions
What conditions are needed to trigger the deadlock?
An io_uring write must start write accounting and complete asynchronously after write_iter() returns -EIOCBQUEUED. A filesystem or block-device freeze operation must then wait for the superblock writers semaphore while completion work remains queued for the ring owner.
Which systems are most exposed?
Systems that use io_uring asynchronous writes and can concurrently invoke filesystem or block-device shutdown/freezing operations are exposed to this condition. The described path includes FS_IOC_SHUTDOWN, bdev_freeze(), and freeze_super().
How could this appear on an affected system?
The ring-owning task can be blocked in freeze_super() in D state while the asynchronous I/O completion queues io_req_rw_complete() task_work that never runs. The freeze waits for write protection to be dropped, but that accounting is deferred until the blocked task runs its task_work.