2019-08-02 01:53:25 +08:00
|
|
|
//===-- slot_reuse.cpp ------------------------------------------*- C++ -*-===//
|
[GWP-ASan] Core Guarded Pool Allocator [4].
Summary:
See D60593 for further information.
This patch introduces the core of GWP-ASan, being the guarded pool allocator. This class contains the logic for creating and maintaining allocations in the guarded pool. Its public interface is to be utilised by supporting allocators in order to provide sampled guarded allocation behaviour.
This patch also contains basic functionality tests of the allocator as unittests. The error-catching behaviour will be tested in upcoming patches that use Scudo as an implementing allocator.
Reviewers: vlad.tsyrklevich, eugenis, jfb
Reviewed By: vlad.tsyrklevich
Subscribers: dexonsmith, kubamracek, mgorny, cryptoad, jfb, #sanitizers, llvm-commits, morehouse
Tags: #sanitizers, #llvm
Differential Revision: https://reviews.llvm.org/D62872
llvm-svn: 362636
2019-06-06 03:42:48 +08:00
|
|
|
//
|
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "gwp_asan/tests/harness.h"
|
|
|
|
|
2020-11-17 07:34:14 +08:00
|
|
|
#include <set>
|
|
|
|
|
[GWP-ASan] Core Guarded Pool Allocator [4].
Summary:
See D60593 for further information.
This patch introduces the core of GWP-ASan, being the guarded pool allocator. This class contains the logic for creating and maintaining allocations in the guarded pool. Its public interface is to be utilised by supporting allocators in order to provide sampled guarded allocation behaviour.
This patch also contains basic functionality tests of the allocator as unittests. The error-catching behaviour will be tested in upcoming patches that use Scudo as an implementing allocator.
Reviewers: vlad.tsyrklevich, eugenis, jfb
Reviewed By: vlad.tsyrklevich
Subscribers: dexonsmith, kubamracek, mgorny, cryptoad, jfb, #sanitizers, llvm-commits, morehouse
Tags: #sanitizers, #llvm
Differential Revision: https://reviews.llvm.org/D62872
llvm-svn: 362636
2019-06-06 03:42:48 +08:00
|
|
|
void singleByteGoodAllocDealloc(gwp_asan::GuardedPoolAllocator *GPA) {
|
|
|
|
void *Ptr = GPA->allocate(1);
|
|
|
|
EXPECT_NE(nullptr, Ptr);
|
|
|
|
EXPECT_TRUE(GPA->pointerIsMine(Ptr));
|
|
|
|
EXPECT_EQ(1u, GPA->getSize(Ptr));
|
|
|
|
GPA->deallocate(Ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CustomGuardedPoolAllocator, EnsureReuseOfQuarantine1) {
|
|
|
|
InitNumSlots(1);
|
|
|
|
for (unsigned i = 0; i < 128; ++i)
|
|
|
|
singleByteGoodAllocDealloc(&GPA);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CustomGuardedPoolAllocator, EnsureReuseOfQuarantine2) {
|
|
|
|
InitNumSlots(2);
|
|
|
|
for (unsigned i = 0; i < 128; ++i)
|
|
|
|
singleByteGoodAllocDealloc(&GPA);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CustomGuardedPoolAllocator, EnsureReuseOfQuarantine127) {
|
|
|
|
InitNumSlots(127);
|
|
|
|
for (unsigned i = 0; i < 128; ++i)
|
|
|
|
singleByteGoodAllocDealloc(&GPA);
|
|
|
|
}
|
|
|
|
|
|
|
|
// This test ensures that our slots are not reused ahead of time. We increase
|
|
|
|
// the use-after-free detection by not reusing slots until all of them have been
|
|
|
|
// allocated. This is done by always using the slots from left-to-right in the
|
|
|
|
// pool before we used each slot once, at which point random selection takes
|
|
|
|
// over.
|
|
|
|
void runNoReuseBeforeNecessary(gwp_asan::GuardedPoolAllocator *GPA,
|
|
|
|
unsigned PoolSize) {
|
|
|
|
std::set<void *> Ptrs;
|
|
|
|
for (unsigned i = 0; i < PoolSize; ++i) {
|
|
|
|
void *Ptr = GPA->allocate(1);
|
|
|
|
|
|
|
|
EXPECT_TRUE(GPA->pointerIsMine(Ptr));
|
|
|
|
EXPECT_EQ(0u, Ptrs.count(Ptr));
|
|
|
|
|
|
|
|
Ptrs.insert(Ptr);
|
|
|
|
GPA->deallocate(Ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CustomGuardedPoolAllocator, NoReuseBeforeNecessary2) {
|
|
|
|
constexpr unsigned kPoolSize = 2;
|
|
|
|
InitNumSlots(kPoolSize);
|
|
|
|
runNoReuseBeforeNecessary(&GPA, kPoolSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CustomGuardedPoolAllocator, NoReuseBeforeNecessary128) {
|
|
|
|
constexpr unsigned kPoolSize = 128;
|
|
|
|
InitNumSlots(kPoolSize);
|
|
|
|
runNoReuseBeforeNecessary(&GPA, kPoolSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(CustomGuardedPoolAllocator, NoReuseBeforeNecessary129) {
|
|
|
|
constexpr unsigned kPoolSize = 129;
|
|
|
|
InitNumSlots(kPoolSize);
|
|
|
|
runNoReuseBeforeNecessary(&GPA, kPoolSize);
|
|
|
|
}
|