]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore/../segment_manager: add more validations 44478/head
authorYingxin Cheng <yingxin.cheng@intel.com>
Thu, 6 Jan 2022 08:03:20 +0000 (16:03 +0800)
committerYingxin Cheng <yingxin.cheng@intel.com>
Wed, 12 Jan 2022 05:43:52 +0000 (13:43 +0800)
Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
src/crimson/os/seastore/segment_manager.h
src/crimson/os/seastore/segment_manager/block.cc

index 7b501706420a75f83b895614eb84f03de3f09595..5a7c48a00a597c7886248e64cc09cafe92d0dda1 100644 (file)
@@ -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&);
index 320b0620e684466899b9983db7edfb2d853d68a5..f27942d5d3e77b09430e6d6481b4d139cff44daa 100644 (file)
@@ -304,6 +304,7 @@ write_superblock(
 {
   LOG_PREFIX(block_write_superblock);
   DEBUG("D{} write {}", device_id, sb);
+  sb.validate();
   assert(ceph::encoded_sizeof<block_sm_superblock_t>(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<block_sm_superblock_t>(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,