Skip to content

Commit d9192b5

Browse files
committed
librbd/migration: prune snapshot extents in RawFormat::list_snaps()
list-snaps is exempt from clipping in ImageDispatcher::PreprocessVisitor because it's considered to be an internal API. Further, reads issued by ObjectCopyRequest based on list-snaps results may also be exempt because of READ_FLAG_DISABLE_CLIPPING. Since RawFormat allows specifying a set of snapshots (possibly of varying size!) to be imported, it needs to compensate for that in its list-snaps implementation. Otherwise, an out-of-bounds read will eventually be submitted to the stream. Fixes: https://tracker.ceph.com/issues/67845 Signed-off-by: Ilya Dryomov <[email protected]>
1 parent 5d64c9c commit d9192b5

File tree

3 files changed

+9
-3
lines changed

3 files changed

+9
-3
lines changed

qa/workunits/rbd/cli_migration.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ expect_false() {
2727
create_base_image() {
2828
local image=$1
2929

30-
rbd create --size 1G ${image}
30+
# size is not a multiple of object size to trigger an edge case in
31+
# list-snaps
32+
rbd create --size 1025M ${image}
33+
3134
rbd bench --io-type write --io-pattern rand --io-size=4K --io-total 256M ${image}
3235
rbd snap create ${image}@1
3336
rbd bench --io-type write --io-pattern rand --io-size=4K --io-total 64M ${image}

src/librbd/migration/RawFormat.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "librbd/Utils.h"
1010
#include "librbd/io/AioCompletion.h"
1111
#include "librbd/io/ReadResult.h"
12+
#include "librbd/io/Utils.h"
1213
#include "librbd/migration/SnapshotInterface.h"
1314
#include "librbd/migration/SourceSpecBuilder.h"
1415
#include "librbd/migration/Utils.h"
@@ -209,7 +210,9 @@ void RawFormat<I>::list_snaps(io::Extents&& image_extents,
209210
&previous_size, &sparse_extents);
210211

211212
// build set of data/zeroed extents for the current snapshot
212-
snapshot->list_snap(io::Extents{image_extents}, list_snaps_flags,
213+
auto snapshot_extents = image_extents;
214+
io::util::prune_extents(snapshot_extents, snap_info.size);
215+
snapshot->list_snap(std::move(snapshot_extents), list_snaps_flags,
213216
&sparse_extents, parent_trace, gather_ctx->new_sub());
214217
}
215218

src/test/librbd/migration/test_mock_RawFormat.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ TEST_F(TestMockMigrationRawFormat, ListSnapsMerge) {
466466
expect_snapshot_get_info(*mock_snapshot_interface_2, snap_info_2);
467467
io::SparseExtents sparse_extents_2;
468468
sparse_extents_2.insert(0, 32, {io::SPARSE_EXTENT_STATE_DATA, 32});
469-
expect_snapshot_list_snap(*mock_snapshot_interface_2, {{0, 123}},
469+
expect_snapshot_list_snap(*mock_snapshot_interface_2, {{0, 64}},
470470
sparse_extents_2, 0);
471471

472472
expect_snapshot_get_info(*mock_snapshot_interface_head, snap_info_head);

0 commit comments

Comments
 (0)