]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commit
librbd: fix use-after-free releasing object map locks in deep copy 69620/head
authorKefu Chai <k.chai@proxmox.com>
Sun, 21 Jun 2026 23:44:20 +0000 (07:44 +0800)
committerKefu Chai <k.chai@proxmox.com>
Mon, 22 Jun 2026 00:25:53 +0000 (08:25 +0800)
commitecd883a1b3924b981042df3903cb1dc6b55d5920
tree20817cca63e55b38061aec93224bacb8abf40e9f
parentc5693b3ccaa0f3a0cb9158d0ae43d154fe7d7801
librbd: fix use-after-free releasing object map locks in deep copy

DeepCopyRequest::send_copy_object_map() holds the destination image's
owner_lock and image_lock (shared), issues an asynchronous
object_map->rollback(), and then releases the two locks through
m_dst_image_ctx.  The rollback callback drives the rest of the request to
completion (handle_copy_object_map() ... finish() -> put()) on other
threads.  That path needs image_lock, so it only proceeds once this method
releases it, and can then run to completion and free 'this' before the
following owner_lock.unlock_shared() executes, dereferencing the freed
DeepCopyRequest.

ASan reported this as a heap-use-after-free in
TestImageReplayer.StartReplayAndWrite: the object was freed on the finisher
thread (handle_copy_metadata() -> finish()) while the io_context thread was
still in send_copy_object_map().

The destination image ctx outlives the request, so operate through a local
reference to it and release the locks through that reference rather than
through 'this', as
operation/SnapshotRollbackRequest::send_rollback_object_map() already does.

Keep the explicit lock_shared()/unlock_shared() calls rather than scoped
std::shared_lock guards: unlike
operation/SnapshotRollbackRequest::send_rollback_object_map(),
send_copy_object_map() has four exit paths (send_copy_metadata(),
send_refresh_object_map(), finish(), and the object map rollback), each of
which must release the locks before running a different continuation, so
RAII guards would push that continuation out of the locked scope and read
less clearly than unlocking at each exit.

Fixes: https://tracker.ceph.com/issues/77551
Signed-off-by: Kefu Chai <k.chai@proxmox.com>
src/librbd/DeepCopyRequest.cc