PT-2026-90371 · Linux · Linux
CVE-2026-89655
·
Published
2026-09-11
·
Updated
2026-09-11
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:
ceph: fix UAF in kick flushing caps() on cf entry freed during unlock
list for each entry() iterates ci->i cap flush list but drops
i ceph lock to send cap messages. During the unlock window,
handle cap flush ack() can acquire i ceph lock, detach cf entries
with tid <= flush tid from the list, release i ceph lock, and free
them via ceph free cap flush() outside any lock. When the original
thread reacquires i ceph lock and the for-loop macro advances via
cf = list next entry(cf, i list), it dereferences cf->i list.next
on freed memory.
The race timeline:
kick flushing caps() handle cap flush ack()
holds i ceph lock <---
iterates to cf (tid=10)
prepares FLUSH message
drops i ceph lock <---
send cap() ── FLUSH(tid=10)
MDS sends FLUSH ACK(tid=10)
---> acquires i ceph lock
cf->tid(10) <= flush tid(10),
detaches cf from i cap flush list
drops i ceph lock
ceph free cap flush(cf) <- frees it!
acquires i ceph lock <---
for-loop advances:
cf = list next entry(cf, i list)
-- UAF on freed cf->i list.next
The cf was just sent by kick flushing caps itself via send cap().
The MDS may respond with FLUSH ACK quickly enough that
handle cap flush ack() frees cf before kick flushing caps can
finish the iteration.
Fix by converting to a manual while loop: save the next pointer
under i ceph lock before dropping it, then use the saved pointer
after reacquiring, so the potentially-freed cf is never accessed again.
Found an issue in the description? Have something to add? Feel free to write us 👾
Related Identifiers
Affected Products
Linux