From cb520f97094de02d06b81177043a1f2207ad78fe Mon Sep 17 00:00:00 2001 From: Igor Fedotov Date: Tue, 9 Jul 2019 21:02:08 +0300 Subject: [PATCH] os/bluestore: avoid length overflow in extents returned by Stupid Allocator. Fixes: http://tracker.ceph.com/issues/40703 Signed-off-by: Igor Fedotov (cherry picked from commit e1b4984a63e79ab2e2aec7aa17bd80a77e79ec8c) Conflicts: src/test/objectstore/Allocator_test.cc inconsistency with the old gtest version --- src/os/bluestore/StupidAllocator.cc | 11 +++++++---- src/test/objectstore/Allocator_test.cc | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/os/bluestore/StupidAllocator.cc b/src/os/bluestore/StupidAllocator.cc index c7224ea8c4e86..cbb0f35e8d82a 100644 --- a/src/os/bluestore/StupidAllocator.cc +++ b/src/os/bluestore/StupidAllocator.cc @@ -205,10 +205,13 @@ int64_t StupidAllocator::allocate( bool can_append = true; if (!extents->empty()) { bluestore_pextent_t &last_extent = extents->back(); - if ((last_extent.end() == offset) && - ((last_extent.length + length) <= max_alloc_size)) { - can_append = false; - last_extent.length += length; + if (last_extent.end() == offset) { + uint64_t l64 = last_extent.length; + l64 += length; + if (l64 < 0x100000000 && l64 <= max_alloc_size) { + can_append = false; + last_extent.length += length; + } } } if (can_append) { diff --git a/src/test/objectstore/Allocator_test.cc b/src/test/objectstore/Allocator_test.cc index 959932af9e598..ded6951f49cc6 100644 --- a/src/test/objectstore/Allocator_test.cc +++ b/src/test/objectstore/Allocator_test.cc @@ -316,6 +316,27 @@ TEST_P(AllocTest, test_alloc_bug_24598) EXPECT_EQ(tmp.size(), 1); } +//Verifies issue from +//http://tracker.ceph.com/issues/40703 +// +TEST_P(AllocTest, test_alloc_big2) +{ + int64_t block_size = 4096; + int64_t blocks = 1048576 * 2; + int64_t mas = 1024*1024; + init_alloc(blocks*block_size, block_size); + alloc->init_add_free(0, blocks * block_size); + + PExtentVector extents; + uint64_t need = block_size * blocks / 4; // 2GB + EXPECT_EQ(need, + alloc->allocate(need, mas, 0, &extents)); + need = block_size * blocks / 4; // 2GB + EXPECT_EQ(need, + alloc->allocate(need, mas, 0, &extents)); + EXPECT_TRUE(extents[0].length > 0); +} + INSTANTIATE_TEST_CASE_P( Allocator, AllocTest, -- 2.39.5