Skip to content

Commit a9b6b34

Browse files
os: Page class: disable move operations and improve custom delete operator for proper memory management
Fix UB in Page 'operator delete' to eliminate uninitialized memory access Fixes: https://tracker.ceph.com/issues/72404 Signed-off-by: Edwin Rodriguez <[email protected]>
1 parent fb8387a commit a9b6b34

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

src/os/memstore/PageSet.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,24 @@ struct Page {
7575
// copy disabled
7676
Page(const Page&) = delete;
7777
const Page& operator=(const Page&) = delete;
78+
Page(Page&&) = delete;
79+
Page& operator=(Page&&) = delete;
7880

7981
private: // private constructor, use create() instead
8082
Page(char *data, uint64_t offset) : data(data), offset(offset), nrefs(1) {}
8183

82-
static void operator delete(void *p) {
83-
delete[] reinterpret_cast<Page*>(p)->data;
84+
// Custom delete operator that uses std::destroying_delete_t to ensure proper cleanup
85+
// of the buffer-Page layout. Since Page is placed at the end of a larger allocated buffer
86+
// containing both the data array and the Page object itself, we need to:
87+
// 1. Store the buffer pointer before destroying the Page object
88+
// 2. Call the Page destructor explicitly to destroy the object in-place
89+
// 3. Delete the entire buffer containing both data and Page
90+
// Without std::destroying_delete_t, the compiler would call the destructor
91+
// before our delete operator, leading to unitialized memory access.
92+
static void operator delete(Page *p, std::destroying_delete_t) {
93+
auto* buffer = p->data;
94+
p->~Page();
95+
delete[] buffer;
8496
}
8597
};
8698

0 commit comments

Comments
 (0)