From: Or Ozeri Date: Thu, 24 Dec 2020 21:35:33 +0000 (+0200) Subject: librbd: check image size on crypto format X-Git-Tag: v16.1.0~87^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0440604c35ec12609bd3b0f63b5affd384bacf9b;p=ceph.git librbd: check image size on crypto format This commit adds a check to verify that an image is big enough before crypto formatting it. Signed-off-by: Or Ozeri --- diff --git a/src/librbd/crypto/luks/FormatRequest.cc b/src/librbd/crypto/luks/FormatRequest.cc index 7bf77dff8862..205c118d779f 100644 --- a/src/librbd/crypto/luks/FormatRequest.cc +++ b/src/librbd/crypto/luks/FormatRequest.cc @@ -92,6 +92,17 @@ void FormatRequest::send() { return; } + m_image_ctx->image_lock.lock_shared(); + uint64_t image_size = m_image_ctx->get_image_size(CEPH_NOSNAP); + m_image_ctx->image_lock.unlock_shared(); + + if (m_header.get_data_offset() >= image_size) { + lderr(m_image_ctx->cct) << "image is too small. format requires more than " + << m_header.get_data_offset() << " bytes" << dendl; + finish(-ENOSPC); + return; + } + // add keyslot (volume key encrypted with passphrase) r = m_header.add_keyslot(m_passphrase.c_str(), m_passphrase.size()); if (r != 0) { diff --git a/src/test/librbd/crypto/luks/test_mock_FormatRequest.cc b/src/test/librbd/crypto/luks/test_mock_FormatRequest.cc index 36f99fef6d36..0b7c71e26291 100644 --- a/src/test/librbd/crypto/luks/test_mock_FormatRequest.cc +++ b/src/test/librbd/crypto/luks/test_mock_FormatRequest.cc @@ -29,6 +29,7 @@ struct TestMockCryptoLuksFormatRequest : public TestMockFixture { typedef FormatRequest MockFormatRequest; const size_t OBJECT_SIZE = 4 * 1024 * 1024; + const size_t IMAGE_SIZE = 1024 * 1024 * 1024; const char* passphrase_cstr = "password"; std::string passphrase = passphrase_cstr; @@ -60,6 +61,11 @@ struct TestMockCryptoLuksFormatRequest : public TestMockFixture { EXPECT_CALL(*mock_image_ctx->io_object_dispatcher, exists( io::OBJECT_DISPATCH_LAYER_CRYPTO)).WillOnce(Return(exists)); } + + void expect_get_image_size(uint64_t image_size) { + EXPECT_CALL(*mock_image_ctx, get_image_size(CEPH_NOSNAP)).WillOnce(Return( + image_size)); + } void expect_image_write() { EXPECT_CALL(*mock_image_ctx->io_image_dispatcher, send(_)) @@ -114,6 +120,7 @@ TEST_F(TestMockCryptoLuksFormatRequest, LUKS1) { on_finish, true); expect_crypto_layer_exists_check(); expect_get_object_size(); + expect_get_image_size(IMAGE_SIZE); expect_image_write(); mock_format_request->send(); ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0)); @@ -129,6 +136,7 @@ TEST_F(TestMockCryptoLuksFormatRequest, AES128) { on_finish, true); expect_crypto_layer_exists_check(); expect_get_object_size(); + expect_get_image_size(IMAGE_SIZE); expect_image_write(); mock_format_request->send(); ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0)); @@ -144,6 +152,7 @@ TEST_F(TestMockCryptoLuksFormatRequest, AES256) { on_finish, true); expect_crypto_layer_exists_check(); expect_get_object_size(); + expect_get_image_size(IMAGE_SIZE); expect_image_write(); mock_format_request->send(); ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0)); @@ -162,6 +171,17 @@ TEST_F(TestMockCryptoLuksFormatRequest, CryptoAlreadyLoaded) { ASSERT_EQ(-EEXIST, finished_cond.wait()); } +TEST_F(TestMockCryptoLuksFormatRequest, ImageTooSmall) { + auto mock_format_request = MockFormatRequest::create( + mock_image_ctx, RBD_ENCRYPTION_FORMAT_LUKS2, + RBD_ENCRYPTION_ALGORITHM_AES256, std::move(passphrase), on_finish, + true); + expect_get_object_size(); + expect_get_image_size(1024*1024); + mock_format_request->send(); + ASSERT_EQ(-ENOSPC, finished_cond.wait()); +} + TEST_F(TestMockCryptoLuksFormatRequest, WriteFail) { auto mock_format_request = MockFormatRequest::create( mock_image_ctx, DiskEncryptionFormat::DISK_ENCRYPTION_FORMAT_LUKS2, @@ -169,6 +189,7 @@ TEST_F(TestMockCryptoLuksFormatRequest, WriteFail) { on_finish, true); expect_crypto_layer_exists_check(); expect_get_object_size(); + expect_get_image_size(IMAGE_SIZE); expect_image_write(); mock_format_request->send(); ASSERT_EQ(ETIMEDOUT, finished_cond.wait_for(0));