From 84d2aad05fd96e63f67face5c14da773ae7bc2b6 Mon Sep 17 00:00:00 2001 From: Edwin Rodriguez Date: Tue, 5 Aug 2025 08:56:46 -0400 Subject: [PATCH] common/async:: Update delete operator in CompletionImpl for improved memory management Fix UB in CompletionImpl 'operator delete' to eliminate uninitialized memory access Fixes: https://tracker.ceph.com/issues/72478 Signed-off-by: Edwin Rodriguez --- src/common/async/completion.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/common/async/completion.h b/src/common/async/completion.h index 6cdfaaa63b7..a8d0aa847ba 100644 --- a/src/common/async/completion.h +++ b/src/common/async/completion.h @@ -246,8 +246,17 @@ class CompletionImpl final : public Completion { std::forward(args)...)}; } - static void operator delete(void *p) { - static_cast(p)->destroy(); + // C++20 destroying delete. + // When this overload is selected by `delete ptr`, the compiler does NOT call + // ~CompletionImpl(). We must do the full teardown here. We route through + // destroy() so that: + // - the completion’s custom lifecycle (defer/dispatch/post) is honored, + // - the object’s destructor is invoked, and + // - deallocation is performed using the matching allocator (RebindAlloc2). + // Keep this function noexcept; destroy() is responsible for both destruction + // and allocator-aware deallocation. + static void operator delete(CompletionImpl* ptr, std::destroying_delete_t) noexcept { + ptr->destroy(); } }; -- 2.39.5