Skip to content

Commit

Permalink
returns E_ARGUMENT if the block range extends beyond the volume bound…
Browse files Browse the repository at this point in the history
…ary (#1475)
  • Loading branch information
sdimanx91 authored Aug 20, 2024
1 parent af346f3 commit d8c6b20
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 4 deletions.
6 changes: 6 additions & 0 deletions cloud/blockstore/libs/storage/volume/volume_actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,12 @@ NKikimr::NMetrics::TResourceMetrics* TVolumeActor::GetResourceMetrics()
return Executor()->GetResourceMetrics();
}

bool TVolumeActor::CheckReadWriteBlockRange(const TBlockRange64& range) const
{
return TBlockRange64::WithLength(0, State->GetBlocksCount())
.Contains(range);
}

////////////////////////////////////////////////////////////////////////////////

void TVolumeActor::HandlePoisonPill(
Expand Down
2 changes: 2 additions & 0 deletions cloud/blockstore/libs/storage/volume/volume_actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,8 @@ class TVolumeActor final

NKikimr::NMetrics::TResourceMetrics* GetResourceMetrics();

bool CheckReadWriteBlockRange(const TBlockRange64& range) const;

private:
STFUNC(StateBoot);
STFUNC(StateInit);
Expand Down
14 changes: 14 additions & 0 deletions cloud/blockstore/libs/storage/volume/volume_actor_forward.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,20 @@ void TVolumeActor::ForwardRequest(
}
}

/*
* Validation of the request blocks range
*/
if constexpr (IsReadOrWriteMethod<TMethod>) {
const auto range = BuildRequestBlockRange(*msg, State->GetBlockSize());
if (!CheckReadWriteBlockRange(range)) {
replyError(MakeError(
E_ARGUMENT,
TStringBuilder()
<< "invalid block range " << DescribeRange(range)));
return;
}
}

/*
* Passing the request to the underlying (storage) layer.
*/
Expand Down
106 changes: 102 additions & 4 deletions cloud/blockstore/libs/storage/volume/volume_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5604,16 +5604,20 @@ Y_UNIT_TEST_SUITE(TVolumeTest)
0);
volume.AddClient(clientInfo);

auto request = volume.CreateWriteBlocksRequest(
TBlockRange64::MakeClosedInterval(1024 * 0, 1024 * 24),
// PartitionRequestActor should return an error,
// to do this we will try to write data to disk using a buffer of the
// incorrect size
TString data(10u, 1);
auto request = volume.CreateWriteBlocksLocalRequest(
TBlockRange64::MakeClosedInterval(0, 1024 * 5),
clientInfo.GetClientId(),
1
data
);
request->Record.MutableHeaders()->MutableInternal()->MutableTrace()->SetIsTraced(true);

volume.SendToPipe(std::move(request));

auto response = volume.RecvWriteBlocksResponse();
auto response = volume.RecvWriteBlocksLocalResponse();

UNIT_ASSERT(FAILED(response->GetStatus()));

Expand Down Expand Up @@ -8209,6 +8213,100 @@ Y_UNIT_TEST_SUITE(TVolumeTest)
UNIT_ASSERT(describeRequest);
}

Y_UNIT_TEST(ShouldReturnErrorOnInvalidBlockRange)
{
auto runtime = PrepareTestActorRuntime();
auto clientInfo = CreateVolumeClientInfo(
NProto::VOLUME_ACCESS_READ_WRITE,
NProto::VOLUME_MOUNT_LOCAL,
0);

TVolumeClient volume(*runtime);
volume.UpdateVolumeConfig(
0, // maxBandwidth
0, // maxIops
0, // burstPercentage
0, // maxPostponedWeight
false, // throttlingEnabled
1, // version
NCloud::NProto::STORAGE_MEDIA_SSD_NONREPLICATED,
2048, // block count per partition
"vol0", // diskId
"cloud", // cloudId
"folder", // folderId
1, // partition count
2, // blocksPerStripe
"track-used", // tags
"base_disk", // baseDiskId
"checkpoint" // baseDiskCheckpointId
);
volume.AddClient(clientInfo);
volume.WaitReady();

// WriteBlocks
{
auto request = volume.CreateWriteBlocksRequest(
TBlockRange64::WithLength(2048, 1024),
clientInfo.GetClientId(),
1
);
volume.SendToPipe(std::move(request));
auto response = volume.RecvWriteBlocksResponse();
UNIT_ASSERT(response);
UNIT_ASSERT_VALUES_EQUAL(E_ARGUMENT, response->GetStatus());
}

// WriteBlocksLocal
{
TString data(DefaultBlockSize, 2);
auto request = volume.CreateWriteBlocksLocalRequest(
TBlockRange64::WithLength(1024 * 6, 1024),
clientInfo.GetClientId(),
data);
volume.SendToPipe(std::move(request));
auto response = volume.RecvWriteBlocksLocalResponse();
UNIT_ASSERT(response);
UNIT_ASSERT_VALUES_EQUAL(E_ARGUMENT, response->GetStatus());
}

// ReadBlocks
{
auto request = volume.CreateReadBlocksRequest(
TBlockRange64::WithLength(2048, 1024),
clientInfo.GetClientId()
);
volume.SendToPipe(std::move(request));
auto response = volume.RecvReadBlocksResponse();
UNIT_ASSERT(response);
UNIT_ASSERT_VALUES_EQUAL(E_ARGUMENT, response->GetStatus());
}

// ReadBlocksLocal
{
TGuardedSgList list;
auto request = volume.CreateReadBlocksLocalRequest(
TBlockRange64::WithLength(2048, 1024),
list,
clientInfo.GetClientId()
);
volume.SendToPipe(std::move(request));
auto response = volume.RecvReadBlocksLocalResponse();
UNIT_ASSERT(response);
UNIT_ASSERT_VALUES_EQUAL(E_ARGUMENT, response->GetStatus());
}

// ZeroRequest
{
auto request = volume.CreateZeroBlocksRequest(
TBlockRange64::WithLength(1024 * 10, 1048),
clientInfo.GetClientId());
volume.SendToPipe(std::move(request));
auto response = volume.RecvZeroBlocksResponse();
UNIT_ASSERT(response);
UNIT_ASSERT_VALUES_EQUAL(E_ARGUMENT, response->GetStatus());
}
}

Y_UNIT_TEST(ShouldReportLongRunningForBaseDisk)
{
NProto::TStorageServiceConfig storageServiceConfig;
Expand Down

0 comments on commit d8c6b20

Please sign in to comment.