From d389ecb072df8e9576bc3614fb947319b0268d64 Mon Sep 17 00:00:00 2001 From: Igor Fedotov Date: Fri, 19 Apr 2019 15:43:07 +0300 Subject: [PATCH] os/bluestore: fix out-of-bound access in bmap allocator. Fixes: https://tracker.ceph.com/issues/39334 Signed-off-by: Igor Fedotov (cherry picked from commit b0d2411c9c48b49fff827841c5ec6b66533d9c58) Conflicts: src/os/bluestore/fastbmap_allocator_impl.cc src/os/bluestore/fastbmap_allocator_impl.h --- src/os/bluestore/fastbmap_allocator_impl.cc | 16 +++++++++------- src/os/bluestore/fastbmap_allocator_impl.h | 16 ++++++++-------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/os/bluestore/fastbmap_allocator_impl.cc b/src/os/bluestore/fastbmap_allocator_impl.cc index 1eff326d4f4a2..3ef73a439eb59 100755 --- a/src/os/bluestore/fastbmap_allocator_impl.cc +++ b/src/os/bluestore/fastbmap_allocator_impl.cc @@ -286,20 +286,22 @@ void AllocatorLevel01Loose::_mark_alloc_l0(int64_t l0_pos_start, int64_t pos = l0_pos_start; slot_t bits = (slot_t)1 << (l0_pos_start % d0); - - while (pos < std::min(l0_pos_end, (int64_t)P2ROUNDUP(l0_pos_start, d0))) { - l0[pos / d0] &= ~bits; + slot_t* val_s = &l0[pos / d0]; + int64_t pos_e = std::min(l0_pos_end, P2ROUNDUP(l0_pos_start + 1, d0)); + while (pos < pos_e) { + (*val_s) &= ~bits; bits <<= 1; pos++; } - - while (pos < std::min(l0_pos_end, (int64_t)P2ALIGN(l0_pos_end, d0))) { - l0[pos / d0] = all_slot_clear; + pos_e = std::min(l0_pos_end, P2ALIGN(l0_pos_end, d0)); + while (pos < pos_e) { + *(++val_s) = all_slot_clear; pos += d0; } bits = 1; + ++val_s; while (pos < l0_pos_end) { - l0[pos / d0] &= ~bits; + (*val_s) &= ~bits; bits <<= 1; pos++; } diff --git a/src/os/bluestore/fastbmap_allocator_impl.h b/src/os/bluestore/fastbmap_allocator_impl.h index c4f2ca00b29f7..691a2273e487c 100755 --- a/src/os/bluestore/fastbmap_allocator_impl.h +++ b/src/os/bluestore/fastbmap_allocator_impl.h @@ -337,23 +337,23 @@ protected: auto pos = l0_pos_start; slot_t bits = (slot_t)1 << (l0_pos_start % d0); - slot_t& val_s = l0[pos / d0]; - int64_t pos_e = std::min(l0_pos_end, (int64_t)P2ROUNDUP(l0_pos_start + 1, d0)); + slot_t* val_s = &l0[pos / d0]; + int64_t pos_e = std::min(l0_pos_end, + P2ROUNDUP(l0_pos_start + 1, d0)); while (pos < pos_e) { - val_s |= bits; + *val_s |= bits; bits <<= 1; pos++; } - pos_e = std::min(l0_pos_end, (int64_t)P2ALIGN(l0_pos_end, d0)); - auto idx = pos / d0; + pos_e = std::min(l0_pos_end, P2ALIGN(l0_pos_end, d0)); while (pos < pos_e) { - l0[idx++] = all_slot_set; + *(++val_s) = all_slot_set; pos += d0; } bits = 1; - uint64_t& val_e = l0[pos / d0]; + ++val_s; while (pos < l0_pos_end) { - val_e |= bits; + *val_s |= bits; bits <<= 1; pos++; } -- 2.39.5