llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-compiler-rt-sanitizer Author: Florian Mayer (fmayer) <details> <summary>Changes</summary> --- Full diff: https://github.com/llvm/llvm-project/pull/82683.diff 4 Files Affected: - (modified) compiler-rt/lib/scudo/standalone/combined.h (+34-10) - (modified) compiler-rt/lib/scudo/standalone/include/scudo/interface.h (+2) - (modified) compiler-rt/lib/scudo/standalone/tests/combined_test.cpp (+27) - (modified) compiler-rt/lib/scudo/standalone/wrappers_c_bionic.cpp (+4) ``````````diff diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h index 79b5891fd35869..479e49c328e3d7 100644 --- a/compiler-rt/lib/scudo/standalone/combined.h +++ b/compiler-rt/lib/scudo/standalone/combined.h @@ -174,9 +174,11 @@ class Allocator { static_cast<uptr>(getFlags()->quarantine_size_kb << 10), static_cast<uptr>(getFlags()->thread_local_quarantine_size_kb << 10)); - mapAndInitializeRingBuffer(); + mapAndInitializeRingBuffer(getFlags()->allocation_ring_buffer_size); } + bool resizeRingBuffer(int Size) { return mapAndInitializeRingBuffer(Size); } + // Initialize the embedded GWP-ASan instance. Requires the main allocator to // be functional, best called from PostInitCallback. void initGwpAsan() { @@ -1531,11 +1533,15 @@ class Allocator { RBEntryStart)[N]; } - void mapAndInitializeRingBuffer() { - if (getFlags()->allocation_ring_buffer_size <= 0) - return; - u32 AllocationRingBufferSize = - static_cast<u32>(getFlags()->allocation_ring_buffer_size); + bool mapAndInitializeRingBuffer(int RingBufferSize) { + if (RingBufferSize < 0 || + static_cast<unsigned int>(RingBufferSize) >= UINT32_MAX) + return false; + if (RingBufferSize == 0) { + swapOutRingBuffer(nullptr); + return true; + } + u32 AllocationRingBufferSize = static_cast<u32>(RingBufferSize); // We store alloc and free stacks for each entry. constexpr u32 kStacksPerRingBufferEntry = 2; @@ -1555,11 +1561,11 @@ class Allocator { UINTPTR_MAX); if (AllocationRingBufferSize > kMaxU32Pow2 / kStacksPerRingBufferEntry) - return; + return false; u32 TabSize = static_cast<u32>(roundUpPowerOfTwo(kStacksPerRingBufferEntry * AllocationRingBufferSize)); if (TabSize > UINT32_MAX / kFramesPerStack) - return; + return false; u32 RingSize = static_cast<u32>(TabSize * kFramesPerStack); DCHECK(isPowerOfTwo(RingSize)); @@ -1585,12 +1591,30 @@ class Allocator { RB->StackDepotSize = StackDepotSize; RB->RawStackDepotMap = DepotMap; - atomic_store(&RingBufferAddress, reinterpret_cast<uptr>(RB), - memory_order_release); + swapOutRingBuffer(RB); static_assert(sizeof(AllocationRingBuffer) % alignof(typename AllocationRingBuffer::Entry) == 0, "invalid alignment"); + return true; + } + + void swapOutRingBuffer(AllocationRingBuffer *NewRB) { + AllocationRingBuffer *PrevRB = reinterpret_cast<AllocationRingBuffer *>( + atomic_exchange(&RingBufferAddress, reinterpret_cast<uptr>(NewRB), + memory_order_acq_rel)); + if (PrevRB) { + auto RawStackDepotMap = PrevRB->RawStackDepotMap; + if (RawStackDepotMap.isAllocated()) { + RawStackDepotMap.releaseAndZeroPagesToOS( + RawStackDepotMap.getBase(), RawStackDepotMap.getCapacity()); + } + auto RawRingBufferMap = PrevRB->RawRingBufferMap; + if (RawRingBufferMap.isAllocated()) { + RawRingBufferMap.releaseAndZeroPagesToOS( + RawRingBufferMap.getBase(), RawRingBufferMap.getCapacity()); + } + } } void unmapRingBuffer() { diff --git a/compiler-rt/lib/scudo/standalone/include/scudo/interface.h b/compiler-rt/lib/scudo/standalone/include/scudo/interface.h index a2dedea910cc08..8aca56b7172d9f 100644 --- a/compiler-rt/lib/scudo/standalone/include/scudo/interface.h +++ b/compiler-rt/lib/scudo/standalone/include/scudo/interface.h @@ -123,6 +123,8 @@ size_t __scudo_get_region_info_size(void); const char *__scudo_get_ring_buffer_addr(void); size_t __scudo_get_ring_buffer_size(void); +bool __scudo_resize_ring_buffer(int); + #ifndef M_DECAY_TIME #define M_DECAY_TIME -100 #endif diff --git a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp index 13d627b116809b..7e7a0e59cfe6d0 100644 --- a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp @@ -915,6 +915,33 @@ SCUDO_TYPED_TEST(ScudoCombinedTest, StackDepot) { EXPECT_EQ(Depot->at(RingPosPtr + 2), 3u); } +SCUDO_TYPED_TEST(ScudoCombinedTest, ResizeRingBuffer) { + auto *Allocator = this->Allocator.get(); + auto Size = static_cast<int>(Allocator->getRingBufferSize()); + auto DepotSize = Allocator->getStackDepotSize(); + ASSERT_GT(Size, 0); + ASSERT_TRUE(Allocator->resizeRingBuffer(Size + 1024)); + EXPECT_GT(Allocator->getRingBufferSize(), Size); + EXPECT_GT(Allocator->getStackDepotSize(), DepotSize); +} + +SCUDO_TYPED_TEST(ScudoCombinedTest, ResizeRingBufferToZero) { + auto *Allocator = this->Allocator.get(); + const char *PrevRB = Allocator->getRingBufferAddress(); + auto PrevRBSize = Allocator->getRingBufferSize(); + ASSERT_TRUE(Allocator->resizeRingBuffer(0)); + EXPECT_EQ(Allocator->getRingBufferSize(), 0); + EXPECT_EQ(Allocator->getStackDepotSize(), 0); + EXPECT_EQ(Allocator->getStackDepotAddress(), nullptr); + EXPECT_EQ(Allocator->getRingBufferAddress(), nullptr); + // Make sure the old buffer is still accessible without a segfault. + // We DONTNEED the buffer, so we free the underlying pages, but we keep the + // VMA around to prevent races. + ASSERT_NE(PrevRB, nullptr); + ASSERT_GT(PrevRBSize, 0); + const_cast<volatile const char *>(PrevRB)[PrevRBSize - 1]; +} + #if SCUDO_CAN_USE_PRIMARY64 #if SCUDO_TRUSTY diff --git a/compiler-rt/lib/scudo/standalone/wrappers_c_bionic.cpp b/compiler-rt/lib/scudo/standalone/wrappers_c_bionic.cpp index e9d8c1e8d3db2f..004c9b9ef36cf6 100644 --- a/compiler-rt/lib/scudo/standalone/wrappers_c_bionic.cpp +++ b/compiler-rt/lib/scudo/standalone/wrappers_c_bionic.cpp @@ -72,4 +72,8 @@ INTERFACE size_t __scudo_get_ring_buffer_size() { return Allocator.getRingBufferSize(); } +INTERFACE bool __scudo_resize_ring_buffer(int new_size) { + return Allocator.resizeRingBuffer(new_size); +} + #endif // SCUDO_ANDROID && _BIONIC `````````` </details> https://github.com/llvm/llvm-project/pull/82683 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits