From 06e8fd11501daebc02f1d1ce0afd11b42ade1235 Mon Sep 17 00:00:00 2001 From: Mohit Agrawal Date: Thu, 3 Jul 2025 17:58:29 +0530 Subject: [PATCH] seastore: support validating device signature for ceph-lvm Write the SEASTORE_SUPERBLOCK_SIGN at offset 0 before encoding the superblock. If the signature is added inside the block_sm_superblock_t structure (via DENC), it won't be written at offset 0 because DENC encoding add some metadata. Therefore prepend the signature to the bufferlist before encoding the superblock sothat signature always appears at the start of the written data Fixes: https://tracker.ceph.com/issues/71954 Signed-off-by: Mohit Agrawal --- src/crimson/os/seastore/seastore_types.h | 5 +++++ src/crimson/os/seastore/segment_manager/block.cc | 16 ++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/crimson/os/seastore/seastore_types.h b/src/crimson/os/seastore/seastore_types.h index 5a80c6ef720f5..c5cb9472f3491 100644 --- a/src/crimson/os/seastore/seastore_types.h +++ b/src/crimson/os/seastore/seastore_types.h @@ -118,6 +118,11 @@ constexpr device_id_t DEVICE_ID_SEGMENTED_MIN = 0; constexpr device_id_t DEVICE_ID_RANDOM_BLOCK_MIN = 1 << (std::numeric_limits::digits - 1); +// TODO this Signature is only applicable for segment devices(SSD/HDD) not +// for other two devices like ZBD/RANDOM_BLOCK_SSD +constexpr const char SEASTORE_SUPERBLOCK_SIGN[] = "seastore block device\n"; +constexpr std::size_t SEASTORE_SUPERBLOCK_SIGN_LEN = sizeof(SEASTORE_SUPERBLOCK_SIGN) - 1; + struct device_id_printer_t { device_id_t id; }; diff --git a/src/crimson/os/seastore/segment_manager/block.cc b/src/crimson/os/seastore/segment_manager/block.cc index 98a3d1bb9282d..185c139b358dd 100644 --- a/src/crimson/os/seastore/segment_manager/block.cc +++ b/src/crimson/os/seastore/segment_manager/block.cc @@ -293,7 +293,10 @@ write_superblock( bufferptr(ceph::buffer::create_page_aligned(sb.block_size)), [=, &device](auto &bp) { + // Encode SEASTORE_SUPERBLOCK_SIGN at offset 0 before + // encoding anything else bufferlist bl; + bl.append(SEASTORE_SUPERBLOCK_SIGN); encode(sb, bl); auto iter = bl.begin(); assert(bl.length() < sb.block_size); @@ -323,14 +326,23 @@ read_superblock(seastar::file &device, seastar::stat_data sd) bl.push_back(bp); block_sm_superblock_t ret; auto bliter = bl.cbegin(); + // Validate the magic prefix + std::string sb_magic; + bliter.copy(SEASTORE_SUPERBLOCK_SIGN_LEN, sb_magic); + if (sb_magic != SEASTORE_SUPERBLOCK_SIGN) { + ERROR("invalid superblock signature: got '{}' expected '{}'", + sb_magic, SEASTORE_SUPERBLOCK_SIGN); + ceph_abort_msg("invalid superblock signature"); + } + try { decode(ret, bliter); } catch (...) { ERROR("got decode error!"); ceph_assert(0 == "invalid superblock"); } - assert(ceph::encoded_sizeof(ret) < - sd.block_size); + assert(ceph::encoded_sizeof(ret) + + SEASTORE_SUPERBLOCK_SIGN_LEN <= sd.block_size); return BlockSegmentManager::access_ertr::future( BlockSegmentManager::access_ertr::ready_future_marker{}, ret); -- 2.39.5