]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: apply CryptoObjectDispatch layer only to DATA area
authorIlya Dryomov <idryomov@gmail.com>
Fri, 9 Sep 2022 16:34:49 +0000 (18:34 +0200)
committerIlya Dryomov <idryomov@gmail.com>
Sun, 4 Dec 2022 17:19:19 +0000 (18:19 +0100)
Objects in CRYPTO_HEADER area should not be subjected to encryption.
Unit tests needed adjustment because MockCryptoInterface is configured
with DATA_OFFSET = 4 * 1024 * 1024, thus disqualifying object 0.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
src/librbd/crypto/CryptoObjectDispatch.cc
src/librbd/crypto/CryptoObjectDispatch.h
src/test/librbd/crypto/test_mock_CryptoObjectDispatch.cc

index 8a5ff82cded0a7170cb60a0cec58b5efc7d234ad..05c634abd3b09b040433bc5d724ad08313cb194b 100644 (file)
@@ -5,6 +5,7 @@
 #include "include/ceph_assert.h"
 #include "include/neorados/RADOS.hpp"
 #include "common/dout.h"
+#include "osdc/Striper.h"
 #include "librbd/ImageCtx.h"
 #include "librbd/Utils.h"
 #include "librbd/crypto/CryptoInterface.h"
@@ -431,6 +432,8 @@ template <typename I>
 CryptoObjectDispatch<I>::CryptoObjectDispatch(
     I* image_ctx, CryptoInterface* crypto)
   : m_image_ctx(image_ctx), m_crypto(crypto) {
+  m_data_offset_object_no = Striper::get_num_objects(image_ctx->layout,
+                                                     crypto->get_data_offset());
 }
 
 template <typename I>
@@ -445,6 +448,10 @@ bool CryptoObjectDispatch<I>::read(
     uint64_t* version, int* object_dispatch_flags,
     io::DispatchResult* dispatch_result, Context** on_finish,
     Context* on_dispatched) {
+  if (object_no < m_data_offset_object_no) {
+    return false;
+  }
+
   auto cct = m_image_ctx->cct;
   ldout(cct, 20) << data_object_name(m_image_ctx, object_no) << " "
                  << *extents << dendl;
@@ -476,6 +483,10 @@ bool CryptoObjectDispatch<I>::write(
     const ZTracer::Trace &parent_trace, int* object_dispatch_flags,
     uint64_t* journal_tid, io::DispatchResult* dispatch_result,
     Context** on_finish, Context* on_dispatched) {
+  if (object_no < m_data_offset_object_no) {
+    return false;
+  }
+
   auto cct = m_image_ctx->cct;
   ldout(cct, 20) << data_object_name(m_image_ctx, object_no) << " "
                  << object_off << "~" << data.length() << dendl;
@@ -509,6 +520,10 @@ bool CryptoObjectDispatch<I>::write_same(
     const ZTracer::Trace &parent_trace, int* object_dispatch_flags,
     uint64_t* journal_tid, io::DispatchResult* dispatch_result,
     Context** on_finish, Context* on_dispatched) {
+  if (object_no < m_data_offset_object_no) {
+    return false;
+  }
+
   auto cct = m_image_ctx->cct;
   ldout(cct, 20) << data_object_name(m_image_ctx, object_no) << " "
                  << object_off << "~" << object_len << dendl;
@@ -544,6 +559,10 @@ bool CryptoObjectDispatch<I>::compare_and_write(
     int* object_dispatch_flags, uint64_t* journal_tid,
     io::DispatchResult* dispatch_result, Context** on_finish,
     Context* on_dispatched) {
+  if (object_no < m_data_offset_object_no) {
+    return false;
+  }
+
   auto cct = m_image_ctx->cct;
   ldout(cct, 20) << data_object_name(m_image_ctx, object_no) << " "
                  << object_off << "~" << write_data.length()
@@ -568,6 +587,10 @@ bool CryptoObjectDispatch<I>::discard(
         const ZTracer::Trace &parent_trace, int* object_dispatch_flags,
         uint64_t* journal_tid, io::DispatchResult* dispatch_result,
         Context** on_finish, Context* on_dispatched) {
+  if (object_no < m_data_offset_object_no) {
+    return false;
+  }
+
   auto cct = m_image_ctx->cct;
   ldout(cct, 20) << data_object_name(m_image_ctx, object_no) << " "
                  << object_off << "~" << object_len << dendl;
@@ -597,6 +620,10 @@ template <typename I>
 int CryptoObjectDispatch<I>::prepare_copyup(
         uint64_t object_no,
         io::SnapshotSparseBufferlist* snapshot_sparse_bufferlist) {
+  if (object_no < m_data_offset_object_no) {
+    return 0;
+  }
+
   ceph::bufferlist current_bl;
   current_bl.append_zero(m_image_ctx->get_object_size());
 
index 579f8d30166345c482a96bc61679158ecfb0095e..b72fe194888215e271a9bb075e6ccbdd8e4d4696 100644 (file)
@@ -104,6 +104,7 @@ public:
 private:
   ImageCtxT* m_image_ctx;
   CryptoInterface* m_crypto;
+  uint64_t m_data_offset_object_no;
 };
 
 } // namespace crypto
index 928d47a5311f43437a5a449683e0cda33d831ed9..7ad4efa4e3459c624008c60ad1d6a9872af62a3d 100644 (file)
@@ -275,7 +275,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, Flush) {
 TEST_F(TestMockCryptoCryptoObjectDispatch, Discard) {
   expect_object_write_same();
   ASSERT_TRUE(mock_crypto_object_dispatch->discard(
-          0, 0, 4096, mock_image_ctx->get_data_io_context(), 0, {},
+          11, 0, 4096, mock_image_ctx->get_data_io_context(), 0, {},
           &object_dispatch_flags, nullptr, &dispatch_result, &on_finish,
           on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
@@ -289,7 +289,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, AlignedReadFail) {
   io::ReadExtents extents = {{0, 4096}};
   expect_object_read(&extents);
   ASSERT_TRUE(mock_crypto_object_dispatch->read(
-      0, &extents, mock_image_ctx->get_data_io_context(), 0, 0, {},
+      11, &extents, mock_image_ctx->get_data_io_context(), 0, 0, {},
       nullptr, &object_dispatch_flags, &dispatch_result,
       &on_finish, on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
@@ -308,7 +308,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, AlignedRead) {
   extents[1].bl.append(std::string(4096, '0'));
   expect_object_read(&extents);
   ASSERT_TRUE(mock_crypto_object_dispatch->read(
-          0, &extents, mock_image_ctx->get_data_io_context(), 0, 0, {},
+          11, &extents, mock_image_ctx->get_data_io_context(), 0, 0, {},
           nullptr, &object_dispatch_flags, &dispatch_result,
           &on_finish, on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
@@ -332,9 +332,9 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, AlignedRead) {
 TEST_F(TestMockCryptoCryptoObjectDispatch, ReadFromParent) {
   io::ReadExtents extents = {{0, 4096}, {8192, 4096}};
   expect_object_read(&extents);
-  expect_read_parent(mock_utils, 0, &extents, CEPH_NOSNAP, 8192);
+  expect_read_parent(mock_utils, 11, &extents, CEPH_NOSNAP, 8192);
   ASSERT_TRUE(mock_crypto_object_dispatch->read(
-          0, &extents, mock_image_ctx->get_data_io_context(), 0, 0, {},
+          11, &extents, mock_image_ctx->get_data_io_context(), 0, 0, {},
           nullptr, &object_dispatch_flags, &dispatch_result,
           &on_finish, on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
@@ -350,7 +350,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, ReadFromParentDisabled) {
   io::ReadExtents extents = {{0, 4096}, {8192, 4096}};
   expect_object_read(&extents);
   ASSERT_TRUE(mock_crypto_object_dispatch->read(
-          0, &extents, mock_image_ctx->get_data_io_context(), 0,
+          11, &extents, mock_image_ctx->get_data_io_context(), 0,
           io::READ_FLAG_DISABLE_READ_FROM_PARENT, {},
           nullptr, &object_dispatch_flags, &dispatch_result,
           &on_finish, on_dispatched));
@@ -379,7 +379,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, UnalignedRead) {
 
   expect_object_read(&aligned_extents);
   ASSERT_TRUE(mock_crypto_object_dispatch->read(
-          0, &extents, mock_image_ctx->get_data_io_context(), 0, 0, {},
+          11, &extents, mock_image_ctx->get_data_io_context(), 0, 0, {},
           nullptr, &object_dispatch_flags, &dispatch_result,
           &on_finish, on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
@@ -403,7 +403,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, UnalignedRead) {
 TEST_F(TestMockCryptoCryptoObjectDispatch, AlignedWrite) {
   expect_encrypt();
   ASSERT_TRUE(mock_crypto_object_dispatch->write(
-        0, 0, std::move(data), mock_image_ctx->get_data_io_context(), 0, 0,
+        11, 0, std::move(data), mock_image_ctx->get_data_io_context(), 0, 0,
         std::nullopt, {}, nullptr, nullptr, &dispatch_result, &on_finish,
         on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_CONTINUE);
@@ -421,7 +421,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, UnalignedWrite) {
   extents[1].bl.append(std::string(4096, '3'));
   expect_object_read(&extents, version);
   ASSERT_TRUE(mock_crypto_object_dispatch->write(
-          0, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
+          11, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
           0, 0, std::nullopt, {}, nullptr, nullptr, &dispatch_result,
           &on_finish, on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
@@ -442,7 +442,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, UnalignedWriteWithNoObject) {
   io::ReadExtents extents = {{0, 4096}, {8192, 4096}};
   expect_object_read(&extents);
   ASSERT_TRUE(mock_crypto_object_dispatch->write(
-          0, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
+          11, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
           0, 0, std::nullopt, {}, nullptr, nullptr, &dispatch_result,
           &on_finish, on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
@@ -466,7 +466,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, UnalignedWriteFailCreate) {
   io::ReadExtents extents = {{0, 4096}, {8192, 4096}};
   expect_object_read(&extents);
   ASSERT_TRUE(mock_crypto_object_dispatch->write(
-          0, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
+          11, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
           0, 0, std::nullopt, {}, nullptr, nullptr, &dispatch_result,
           &on_finish, on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
@@ -508,19 +508,20 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, UnalignedWriteCopyup) {
   io::ReadExtents extents = {{0, 4096}, {8192, 4096}};
   expect_object_read(&extents);
   ASSERT_TRUE(mock_crypto_object_dispatch->write(
-          0, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
+          11, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
           0, 0, std::nullopt, {}, nullptr, nullptr, &dispatch_result,
           &on_finish, on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
   ASSERT_EQ(on_finish, &finished_cond);
 
   expect_get_object_size();
-  expect_get_parent_overlap(mock_image_ctx->layout.object_size);
-  expect_remap_to_logical(0, mock_image_ctx->layout.object_size);
+  expect_get_parent_overlap(100 << 20);
+  expect_remap_to_logical(11 * mock_image_ctx->layout.object_size,
+                          mock_image_ctx->layout.object_size);
   expect_prune_parent_extents(mock_image_ctx->layout.object_size);
   EXPECT_CALL(mock_exclusive_lock, is_lock_owner()).WillRepeatedly(
           Return(true));
-  EXPECT_CALL(*mock_image_ctx->object_map, object_may_exist(0)).WillOnce(
+  EXPECT_CALL(*mock_image_ctx->object_map, object_may_exist(11)).WillOnce(
           Return(false));
   MockAbstractObjectWriteRequest *write_request = nullptr;
   expect_copyup(&write_request, 0);
@@ -553,19 +554,20 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, UnalignedWriteEmptyCopyup) {
   io::ReadExtents extents = {{0, 4096}, {8192, 4096}};
   expect_object_read(&extents);
   ASSERT_TRUE(mock_crypto_object_dispatch->write(
-          0, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
+          11, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
           0, 0, std::nullopt, {}, nullptr, nullptr, &dispatch_result,
           &on_finish, on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
   ASSERT_EQ(on_finish, &finished_cond);
 
   expect_get_object_size();
-  expect_get_parent_overlap(mock_image_ctx->layout.object_size);
-  expect_remap_to_logical(0, mock_image_ctx->layout.object_size);
+  expect_get_parent_overlap(100 << 20);
+  expect_remap_to_logical(11 * mock_image_ctx->layout.object_size,
+                          mock_image_ctx->layout.object_size);
   expect_prune_parent_extents(mock_image_ctx->layout.object_size);
   EXPECT_CALL(mock_exclusive_lock, is_lock_owner()).WillRepeatedly(
           Return(true));
-  EXPECT_CALL(*mock_image_ctx->object_map, object_may_exist(0)).WillOnce(
+  EXPECT_CALL(*mock_image_ctx->object_map, object_may_exist(11)).WillOnce(
           Return(false));
   MockAbstractObjectWriteRequest *write_request = nullptr;
   expect_copyup(&write_request, 0);
@@ -595,7 +597,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, UnalignedWriteFailVersionCheck) {
   extents[1].bl.append(std::string(4096, '3'));
   expect_object_read(&extents, version);
   ASSERT_TRUE(mock_crypto_object_dispatch->write(
-          0, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
+          11, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
           0, 0, std::nullopt, {}, nullptr, nullptr, &dispatch_result,
           &on_finish, on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
@@ -631,7 +633,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, UnalignedWriteWithAssertVersion) {
   extents[1].bl.append(std::string(4096, '3'));
   expect_object_read(&extents, version);
   ASSERT_TRUE(mock_crypto_object_dispatch->write(
-          0, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
+          11, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
           0, 0, std::make_optional(assert_version), {}, nullptr, nullptr,
           &dispatch_result, &on_finish, on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
@@ -649,7 +651,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, UnalignedWriteWithExclusiveCreate) {
   extents[1].bl.append(std::string(4096, '3'));
   expect_object_read(&extents);
   ASSERT_TRUE(mock_crypto_object_dispatch->write(
-          0, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
+          11, 1, std::move(write_data), mock_image_ctx->get_data_io_context(),
           0, io::OBJECT_WRITE_FLAG_CREATE_EXCLUSIVE, std::nullopt, {}, nullptr,
           nullptr, &dispatch_result, &on_finish, on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
@@ -672,7 +674,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, CompareAndWrite) {
   expect_object_read(&extents, version);
 
   ASSERT_TRUE(mock_crypto_object_dispatch->compare_and_write(
-          0, 1, std::move(cmp_data), std::move(write_data),
+          11, 1, std::move(cmp_data), std::move(write_data),
           mock_image_ctx->get_data_io_context(), 0, {}, nullptr, nullptr,
           nullptr, &dispatch_result, &on_finish, on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
@@ -701,7 +703,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, CompareAndWriteFail) {
 
   uint64_t mismatch_offset;
   ASSERT_TRUE(mock_crypto_object_dispatch->compare_and_write(
-          0, 1, std::move(cmp_data), std::move(write_data),
+          11, 1, std::move(cmp_data), std::move(write_data),
           mock_image_ctx->get_data_io_context(), 0, {}, &mismatch_offset,
           nullptr, nullptr, &dispatch_result, &on_finish, on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
@@ -718,7 +720,7 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, WriteSame) {
   write_data.append(std::string("12"));
   expect_object_write(0, std::string("12121") , 0, std::nullopt);
   ASSERT_TRUE(mock_crypto_object_dispatch->write_same(
-          0, 0, 5, {{0, 5}}, std::move(write_data),
+          11, 0, 5, {{0, 5}}, std::move(write_data),
           mock_image_ctx->get_data_io_context(), 0, {}, nullptr, nullptr,
           &dispatch_result, &on_finish, on_dispatched));
   ASSERT_EQ(dispatch_result, io::DISPATCH_RESULT_COMPLETE);
@@ -750,14 +752,15 @@ TEST_F(TestMockCryptoCryptoObjectDispatch, PrepareCopyup) {
   expect_get_object_size();
   expect_encrypt(6);
   InSequence seq;
-  expect_remap_to_logical(0, 4096);
-  expect_remap_to_logical(4096, 4096);
-  expect_remap_to_logical(8192, 4096);
-  expect_remap_to_logical(0, 4096);
-  expect_remap_to_logical(4096, 8192);
-  expect_remap_to_logical(16384, 4096);
+  uint64_t base = 11 * mock_image_ctx->layout.object_size;
+  expect_remap_to_logical(base, 4096);
+  expect_remap_to_logical(base + 4096, 4096);
+  expect_remap_to_logical(base + 8192, 4096);
+  expect_remap_to_logical(base, 4096);
+  expect_remap_to_logical(base + 4096, 8192);
+  expect_remap_to_logical(base + 16384, 4096);
   ASSERT_EQ(0, mock_crypto_object_dispatch->prepare_copyup(
-          0, &snapshot_sparse_bufferlist));
+      11, &snapshot_sparse_bufferlist));
 
   ASSERT_EQ(2, snapshot_sparse_bufferlist.size());