From 8aaaeea814c429e9e477f69cb4b5a72fc3192405 Mon Sep 17 00:00:00 2001 From: Yingxin Cheng Date: Thu, 6 Jan 2022 16:03:20 +0800 Subject: [PATCH] crimson/os/seastore/../segment_manager: add more validations Signed-off-by: Yingxin Cheng --- src/crimson/os/seastore/segment_manager.h | 24 +++++++++++++++++++ .../os/seastore/segment_manager/block.cc | 12 +++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/crimson/os/seastore/segment_manager.h b/src/crimson/os/seastore/segment_manager.h index 7b501706420a..5a7c48a00a59 100644 --- a/src/crimson/os/seastore/segment_manager.h +++ b/src/crimson/os/seastore/segment_manager.h @@ -73,6 +73,30 @@ struct block_sm_superblock_t { } DENC_FINISH(p); } + + void validate() const { + ceph_assert(block_size > 0); + ceph_assert(segment_size > 0 && + segment_size % block_size == 0); + ceph_assert(size > segment_size && + size % block_size == 0); + ceph_assert(segments > 0); + ceph_assert(tracker_offset > 0 && + tracker_offset % block_size == 0); + ceph_assert(first_segment_offset > tracker_offset && + first_segment_offset % block_size == 0); + ceph_assert(magic != 0); + ceph_assert(dtype == device_type_t::SEGMENTED); + ceph_assert(device_id <= DEVICE_ID_MAX_VALID); + for (const auto& [k, v] : secondary_devices) { + ceph_assert(k != device_id); + ceph_assert(k <= DEVICE_ID_MAX_VALID); + ceph_assert(k == v.id); + ceph_assert(v.magic != 0); + ceph_assert(v.dtype > device_type_t::NONE); + ceph_assert(v.dtype < device_type_t::NUM_TYPES); + } + } }; std::ostream& operator<<(std::ostream&, const block_sm_superblock_t&); diff --git a/src/crimson/os/seastore/segment_manager/block.cc b/src/crimson/os/seastore/segment_manager/block.cc index 320b0620e684..f27942d5d3e7 100644 --- a/src/crimson/os/seastore/segment_manager/block.cc +++ b/src/crimson/os/seastore/segment_manager/block.cc @@ -304,6 +304,7 @@ write_superblock( { LOG_PREFIX(block_write_superblock); DEBUG("D{} write {}", device_id, sb); + sb.validate(); assert(ceph::encoded_sizeof(sb) < sb.block_size); return seastar::do_with( @@ -382,7 +383,8 @@ Segment::write_ertr::future<> BlockSegment::write( manager.get_offset(paddr)); if (offset < write_pointer || - offset % manager.superblock.block_size != 0) { + offset % manager.superblock.block_size != 0 || + bl.length() % manager.superblock.block_size != 0) { ERROR("D{} S{} offset={}~{} poffset={} invalid write", id.device_id(), id.device_segment_id(), @@ -460,6 +462,7 @@ BlockSegmentManager::mount_ret BlockSegmentManager::mount() }).safe_then([=](auto sb) { set_device_id(sb.device_id); INFO("D{} read {}", get_device_id(), sb); + sb.validate(); superblock = sb; stats.data_read.increment( ceph::encoded_sizeof(superblock)); @@ -616,6 +619,13 @@ SegmentManager::read_ertr::future<> BlockSegmentManager::read( assert(addr.get_device_id() == get_device_id()); + if (s_off % superblock.block_size != 0 || + len % superblock.block_size != 0) { + ERROR("D{} S{} offset={}~{} poffset={} invalid read", + get_device_id(), s_id, s_off, len, p_off); + return crimson::ct_error::invarg::make(); + } + if (s_id >= get_num_segments()) { ERROR("D{} S{} offset={}~{} poffset={} segment-id out of range {}", get_device_id(), s_id, s_off, len, p_off, -- 2.47.3