[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
This commit is contained in:
Kostya Kortchinsky 2019-11-21 10:57:49 -08:00
parent bec37c3fc7
commit 15664fe2c4
2 changed files with 19 additions and 1 deletions

View File

@ -402,7 +402,10 @@ public:
Str.output(); Str.output();
} }
void releaseToOS() { Primary.releaseToOS(); } void releaseToOS() {
initThreadMaybe();
Primary.releaseToOS();
}
// Iterate over all chunks and call a callback for all busy chunks located // 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 // within the provided memory range. Said callback must not use this allocator

View File

@ -279,3 +279,18 @@ TEST(ScudoCombinedTest, DeathCombined) {
EXPECT_DEATH(Allocator->reallocate(P, Size * 2U), ""); EXPECT_DEATH(Allocator->reallocate(P, Size * 2U), "");
EXPECT_DEATH(Allocator->getUsableSize(P), ""); 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<DeathConfig>;
auto Deleter = [](AllocatorT *A) {
A->unmapTestOnly();
delete A;
};
std::unique_ptr<AllocatorT, decltype(Deleter)> Allocator(new AllocatorT,
Deleter);
Allocator->reset();
Allocator->releaseToOS();
}