diff options
author | Petr Hosek <phosek@chromium.org> | 2017-10-11 19:17:35 +0000 |
---|---|---|
committer | Petr Hosek <phosek@chromium.org> | 2017-10-11 19:17:35 +0000 |
commit | c37be534a252a7cb8e2ab04b15256232394dd7a9 (patch) | |
tree | 145e8b2d2e1d28c3e0125e6f33eb77fd7bbabb71 /lib/sanitizer_common/tests | |
parent | f5ee4a4c0f97f94f71d007a18480ca4b6c023075 (diff) |
[sanitizer] Introduce ReservedAddressRange to sanitizer_common
In Fuchsia, MmapNoAccess/MmapFixedOrDie are implemented using a global
VMAR, which means that MmapNoAccess can only be called once. This works
for the sanitizer allocator but *not* for the Scudo allocator.
Hence, this changeset introduces a new ReservedAddressRange object to
serve as the new API for these calls. In this changeset, the object
still calls into the old Mmap implementations.
The next changeset two changesets will convert the sanitizer and scudo
allocators to use the new APIs, respectively. (ReservedAddressRange will
replace the SecondaryHeader in Scudo.)
Finally, a last changeset will update the Fuchsia implementation.
Patch by Julia Hansbrough
Differential Revision: https://reviews.llvm.org/D38759
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@315493 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/tests')
-rw-r--r-- | lib/sanitizer_common/tests/sanitizer_common_test.cc | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/sanitizer_common/tests/sanitizer_common_test.cc b/lib/sanitizer_common/tests/sanitizer_common_test.cc index 9c62b4593..5efce86ce 100644 --- a/lib/sanitizer_common/tests/sanitizer_common_test.cc +++ b/lib/sanitizer_common/tests/sanitizer_common_test.cc @@ -320,4 +320,66 @@ TEST(SanitizerCommon, GetRandom) { } #endif +TEST(SanitizerCommon, ReservedAddressRangeInit) { + uptr init_size = 0xffff; + ReservedAddressRange address_range; + uptr res = address_range.Init(init_size); + CHECK_NE(res, (void*)-1); + UnmapOrDie((void*)res, init_size); + // Should be able to map into the same space now. + ReservedAddressRange address_range2; + uptr res2 = address_range2.Init(init_size, nullptr, res); + CHECK_EQ(res, res2); + + // TODO(flowerhack): Once this is switched to the "real" implementation + // (rather than passing through to MmapNoAccess*), enforce and test "no + // double initializations allowed" +} + +TEST(SanitizerCommon, ReservedAddressRangeMap) { + constexpr uptr init_size = 0xffff; + ReservedAddressRange address_range; + uptr res = address_range.Init(init_size); + CHECK_NE(res, (void*) -1); + + // Valid mappings should succeed. + CHECK_EQ(res, address_range.Map(res, init_size)); + + // Valid mappings should be readable. + unsigned char buffer[init_size]; + memcpy(buffer, &res, sizeof(buffer)); + + // Invalid mappings should fail. + EXPECT_DEATH(address_range.Map(res, 0), ".*"); + + // TODO(flowerhack): Once this is switched to the "real" implementation, make + // sure you can only mmap into offsets in the Init range. +} + +TEST(SanitizerCommon, ReservedAddressRangeUnmap) { + uptr PageSize = GetPageSizeCached(); + uptr init_size = PageSize * 4; + ReservedAddressRange address_range; + uptr base_addr = address_range.Init(init_size); + CHECK_NE(base_addr, (void*)-1); + CHECK_EQ(base_addr, address_range.Map(base_addr, init_size)); + + // Unmapping at the beginning should succeed. + address_range.Unmap(base_addr, PageSize); + CHECK_EQ(base_addr + PageSize, address_range.base()); + CHECK_EQ(init_size - PageSize, address_range.size()); + + // Unmapping at the end should succeed. + uptr old_size = address_range.size(); + void* old_base = address_range.base(); + uptr new_start = reinterpret_cast<uptr>(address_range.base()) + + address_range.size() - PageSize; + address_range.Unmap(new_start, PageSize); + CHECK_EQ(old_size - PageSize, address_range.size()); + CHECK_EQ(old_base, address_range.base()); + + // Unmapping in the middle of the ReservedAddressRange should fail. + EXPECT_DEATH(address_range.Unmap(base_addr + 0xf, 0xff), ".*"); +} + } // namespace __sanitizer |