CVE-2026-89655 PUBLISHED

ceph: fix UAF in __kick_flushing_caps() on cf entry freed during unlock

Assigner: Linux
Reserved: 11.09.2026 Published: 11.09.2026 Updated: 13.09.2026

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.

Metrics

CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CVSS Score: 9.8

AV:N - handle_cap_flush_ack() runs in the ceph-msgr kworker on CEPH_MSG_CLIENT_CAPS FLUSH_ACK from the MDS over TCP; a malicious or compromised MDS frees the ceph_cap_flush while __kick_flushing_caps() still holds that pointer after dropping i_ceph_lock to send FLUSH. AC:L - The MDS controls both sides of the race: it can induce kicking without s_mutex (reconnect sets CEPH_I_KICK_FLUSH, then delayed ceph_check_caps or revoke-queued writeback) and immediately send FLUSH_ACK for the known flush tid in the unlock window around __send_cap(). PR:N - The attacker is the remote MDS peer on an already-connected kernel CephFS client and needs no Linux UID, capability, or init-namespace root on the victim, matching other MDS-driven client CVEs such as CVE-2026-89651. UI:N - Once CephFS is mounted (standard in Rook/Kubernetes/OpenStack), cap-flush kicking runs from mdsc delayed work and writeback, and FLUSH_ACK is processed automatically in kworker context with no further victim mount or interactive step at exploit time. S:U - The use-after-free is of a ceph_cap_flush object in the host kernel heap and stays inside the same kernel security authority; it does not cross a VM, IOMMU, or sandbox boundary. C:H - After ceph_free_cap_flush(), __kick_flushing_caps() does list_next_entry() on the freed cf; reclaiming the dedicated ceph_cap_flush slab with attacker-controlled objects yields a fake next pointer and arbitrary kernel read, scored High per UAF guidance. I:H - The iterator then treats the sprayed object as a live ceph_cap_flush (tid, caps, is_capsnap, i_list) and continues sending cap state from it, giving a heap-reuse write and control-flow hijack primitive scored High for use-after-free. A:H - Dereferencing freed cf->i_list.next oopses or panics the kicker thread even without full exploitation, and a malicious MDS can retrigger the race on every cap flush.

Product Status

Vendor Linux
Product Linux
Versions Default: unaffected
  • affected from e4500b5e35c213e0f97be7cb69328c0877203a79 to 2701431aa3cc8b23efe6890182e7b04f5e76fab5 (excl.)
  • affected from e4500b5e35c213e0f97be7cb69328c0877203a79 to fe46746087b5b9c5bb2d022df6c7819218494ced (excl.)
  • affected from e4500b5e35c213e0f97be7cb69328c0877203a79 to 2dba24dcd5050be4b7b119e6f0b01f62203b5d26 (excl.)
  • affected from e4500b5e35c213e0f97be7cb69328c0877203a79 to 7af4c4f01305b0935adf6d4301b1ec407025485d (excl.)
Vendor Linux
Product Linux
Versions Default: affected
  • Version 4.8 is affected
  • unaffected from 0 to 4.8 (excl.)
  • unaffected from 6.12.109 to 6.12.* (incl.)
  • unaffected from 6.18.50 to 6.18.* (incl.)
  • unaffected from 7.2.4 to 7.2.* (incl.)
  • unaffected from 7.3-rc1 to * (incl.)

References