From 15664fe2c48be242b4b38422466246e9592b6670 Mon Sep 17 00:00:00 2001 From: Kostya Kortchinsky Date: Thu, 21 Nov 2019 10:57:49 -0800 Subject: [PATCH] [scudo][standalone] Fix for releaseToOS prior to init Summary: cferris@ found an issue where calling `releaseToOS` prior to any other heap operation would lead to a crash, due to the allocator not being properly initialized (it was discovered via `mallopt`). The fix is to call `initThreadMaybe` prior to calling `releaseToOS` for the Primary. Add a test that crashes prior to fix. Reviewers: hctim, cferris, pcc, eugenis Subscribers: #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D70552 --- compiler-rt/lib/scudo/standalone/combined.h | 5 ++++- .../lib/scudo/standalone/tests/combined_test.cpp | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/compiler-rt/lib/scudo/standalone/combined.h b/compiler-rt/lib/scudo/standalone/combined.h index 0a05857a20d6..8560c2d3599f 100644 --- a/compiler-rt/lib/scudo/standalone/combined.h +++ b/compiler-rt/lib/scudo/standalone/combined.h @@ -402,7 +402,10 @@ public: Str.output(); } - void releaseToOS() { Primary.releaseToOS(); } + void releaseToOS() { + initThreadMaybe(); + Primary.releaseToOS(); + } // Iterate over all chunks and call a callback for all busy chunks located // within the provided memory range. Said callback must not use this allocator diff --git a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp index d32ea89e0ea3..9205467998ed 100644 --- a/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/combined_test.cpp @@ -279,3 +279,18 @@ TEST(ScudoCombinedTest, DeathCombined) { EXPECT_DEATH(Allocator->reallocate(P, Size * 2U), ""); EXPECT_DEATH(Allocator->getUsableSize(P), ""); } + +// Ensure that releaseToOS can be called prior to any other allocator +// operation without issue. +TEST(ScudoCombinedTest, ReleaseToOS) { + using AllocatorT = scudo::Allocator; + auto Deleter = [](AllocatorT *A) { + A->unmapTestOnly(); + delete A; + }; + std::unique_ptr Allocator(new AllocatorT, + Deleter); + Allocator->reset(); + + Allocator->releaseToOS(); +}