diff options
| author | Xiubo Li <xiubo.li@clyso.com> | 2026-07-14 16:13:43 +0800 |
|---|---|---|
| committer | Ilya Dryomov <idryomov@gmail.com> | 2026-08-26 19:57:28 +0200 |
| commit | 7af4c4f01305b0935adf6d4301b1ec407025485d (patch) | |
| tree | 7ac066cab7268cb5b8c0d5e83ab5475f9208ee48 /scripts/const_structs.checkpatch | |
| parent | 0cb176595797466da1792aaff1124b74d9df6e81 (diff) | |
| download | linux-7af4c4f01305b0935adf6d4301b1ec407025485d.tar.gz linux-7af4c4f01305b0935adf6d4301b1ec407025485d.zip | |
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.
Cc: stable@vger.kernel.org
Signed-off-by: Xiubo Li <xiubo.li@clyso.com>
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'scripts/const_structs.checkpatch')
0 files changed, 0 insertions, 0 deletions
