[compiler-rt] r315533 - Reland "[sanitizer] Introduce ReservedAddressRange to sanitizer_common"
Evgenii Stepanov via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 11 18:23:50 PDT 2017
10-11 18:22:12.665 11799 11799 F DEBUG : pid: 11796, tid: 11796,
name: SanitizerTest >>> /data/local/tmp/Output/SanitizerTest <<<
10-11 18:22:12.665 11799 11799 F DEBUG : signal 11 (SIGSEGV), code 1
(SEGV_MAPERR), fault addr 0x7fcae88000
10-11 18:22:12.665 11799 11799 F DEBUG : x0 0000007fcae76c90
x1 0000007fcae87fd0 x2 000000000000ec6f x3 0000007fcae77f90
10-11 18:22:12.665 11799 11799 F DEBUG : x4 0000007fcae96c8f
x5 0000007fcae86c8f x6 757074754f2f706d x7 6974696e61532f74
10-11 18:22:12.665 11799 11799 F DEBUG : x8 007473655472657a
x9 0000000000000000 x10 732d696669772f6b x11 6a2e656369767265
10-11 18:22:12.665 11799 11799 F DEBUG : x12 617461642f007261
x13 742f6c61636f6c2f x14 0000000000000000 x15 000000799fe00000
10-11 18:22:12.665 11799 11799 F DEBUG : x16 0000005bb2f01008
x17 00000079a035d430 x18 0000000000000000 x19 00000079a06f8000
10-11 18:22:12.666 11799 11799 F DEBUG : x20 000000799fe33000
x21 0000007fcae86c90 x22 000000799fe33000 x23 0000000059dec3c4
10-11 18:22:12.666 11799 11799 F DEBUG : x24 000000000009823b
x25 0000005bb399b4c0 x26 0000000000000000 x27 0000000000000000
10-11 18:22:12.666 11799 11799 F DEBUG : x28 0000000000000000
x29 0000000059dec3c4 x30 0000005bb2e4d354
10-11 18:22:12.666 11799 11799 F DEBUG : sp 0000007fcae76c30
pc 00000079a035d554 pstate 0000000020000000
10-11 18:22:12.668 11799 11799 F DEBUG :
10-11 18:22:12.668 11799 11799 F DEBUG : backtrace:
#00 pc 000000000001c554 /system/lib64/libc.so (memcpy+292)
000000000008a350
TestBody
/code/llvm-project/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cc:350
00000000000df0c8
Run
/code/llvm-project/llvm/utils/unittest/googletest/src/gtest.cc
On Wed, Oct 11, 2017 at 6:18 PM, Evgenii Stepanov
<eugeni.stepanov at gmail.com> wrote:
> Hi,
>
> these new tests are crashing on Android, arm & aarch64 but not x86:
>
> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-android/builds/3724/steps/run%20sanitizer_common%20tests%20%5Barm%2Faosp_marlin-userdebug%2FNMF27E%5D/logs/stdio
>
> On Wed, Oct 11, 2017 at 4:41 PM, Petr Hosek via llvm-commits
> <llvm-commits at lists.llvm.org> wrote:
>> Author: phosek
>> Date: Wed Oct 11 16:41:32 2017
>> New Revision: 315533
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=315533&view=rev
>> Log:
>> Reland "[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/D38437
>>
>> Modified:
>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_fuchsia.cc
>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc
>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
>> compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_common_test.cc
>>
>> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
>> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=315533&r1=315532&r2=315533&view=diff
>> ==============================================================================
>> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
>> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Wed Oct 11 16:41:32 2017
>> @@ -128,6 +128,20 @@ void CheckVMASize();
>> void RunMallocHooks(const void *ptr, uptr size);
>> void RunFreeHooks(const void *ptr);
>>
>> +class ReservedAddressRange {
>> + public:
>> + uptr Init(uptr size, const char *name = nullptr, uptr fixed_addr = 0);
>> + uptr Map(uptr fixed_addr, uptr size, bool tolerate_enomem = false);
>> + void Unmap(uptr addr, uptr size);
>> + void *base() const { return base_; }
>> + uptr size() const { return size_; }
>> +
>> + private:
>> + void* base_;
>> + uptr size_;
>> + const char* name_;
>> +};
>> +
>> typedef void (*fill_profile_f)(uptr start, uptr rss, bool file,
>> /*out*/uptr *stats, uptr stats_size);
>>
>>
>> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_fuchsia.cc
>> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_fuchsia.cc?rev=315533&r1=315532&r2=315533&view=diff
>> ==============================================================================
>> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_fuchsia.cc (original)
>> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_fuchsia.cc Wed Oct 11 16:41:32 2017
>> @@ -236,6 +236,37 @@ void *MmapOrDieOnFatalError(uptr size, c
>> return DoAnonymousMmapOrDie(size, mem_type, false, false);
>> }
>>
>> +uptr ReservedAddressRange::Init(uptr init_size, const char* name = nullptr,
>> + uptr fixed_addr = uptr(0)) {
>> + base_ = MmapNoAccess(init_size);
>> + size_ = size;
>> + name_ = name;
>> + return reinterpret_cast<uptr>(base_);
>> +}
>> +
>> +// Uses fixed_addr for now.
>> +// Will use offset instead once we've implemented this function for real.
>> +uptr ReservedAddressRange::Map(uptr fixed_addr, uptr map_size,
>> + bool tolerate_enomem = true) {
>> + return reinterpret_cast<uptr>(MmapFixedOrDie(fixed_addr, size,
>> + tolerate_enomem));
>> +}
>> +
>> +void ReservedAddressRange::Unmap(uptr addr, uptr size) {
>> + void* addr_as_void = reinterpret_cast<void*>(addr);
>> + uptr base_as_uptr = reinterpret_cast<uptr>(base_);
>> + // Only unmap at the beginning or end of the range.
>> + CHECK_EQ((addr_as_void == base_) || (addr + size == base_as_uptr + size_),
>> + true);
>> + // Detect overflows.
>> + CHECK_LE(size, (base_as_uptr + size_) - addr);
>> + UnmapOrDie(reinterpret_cast<void*>(addr), size);
>> + if (addr_as_void == base_) {
>> + base_ = reinterpret_cast<void*>(addr + size);
>> + }
>> + size_ = size_ - size;
>> +}
>> +
>> // MmapNoAccess and MmapFixedOrDie are used only by sanitizer_allocator.
>> // Instead of doing exactly what they say, we make MmapNoAccess actually
>> // just allocate a VMAR to reserve the address space. Then MmapFixedOrDie
>>
>> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc
>> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc?rev=315533&r1=315532&r2=315533&view=diff
>> ==============================================================================
>> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc (original)
>> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc Wed Oct 11 16:41:32 2017
>> @@ -337,6 +337,42 @@ void *MmapFixedNoReserve(uptr fixed_addr
>> return (void *)p;
>> }
>>
>> +uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) {
>> + if (fixed_addr) {
>> + base_ = MmapFixedNoAccess(fixed_addr, size, name);
>> + } else {
>> + base_ = MmapNoAccess(size);
>> + }
>> + size_ = size;
>> + name_ = name;
>> + return reinterpret_cast<uptr>(base_);
>> +}
>> +
>> +// Uses fixed_addr for now.
>> +// Will use offset instead once we've implemented this function for real.
>> +uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size,
>> + bool tolerate_enomem) {
>> + if (tolerate_enomem) {
>> + return reinterpret_cast<uptr>(MmapFixedOrDieOnFatalError(fixed_addr, size));
>> + }
>> + return reinterpret_cast<uptr>(MmapFixedOrDie(fixed_addr, size));
>> +}
>> +
>> +void ReservedAddressRange::Unmap(uptr addr, uptr size) {
>> + void* addr_as_void = reinterpret_cast<void*>(addr);
>> + uptr base_as_uptr = reinterpret_cast<uptr>(base_);
>> + // Only unmap at the beginning or end of the range.
>> + CHECK_EQ((addr_as_void == base_) || (addr + size == base_as_uptr + size_),
>> + true);
>> + // Detect overflows.
>> + CHECK_LE(size, (base_as_uptr + size_) - addr);
>> + UnmapOrDie(reinterpret_cast<void*>(addr), size);
>> + if (addr_as_void == base_) {
>> + base_ = reinterpret_cast<void*>(addr + size);
>> + }
>> + size_ = size_ - size;
>> +}
>> +
>> void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name) {
>> int fd = name ? GetNamedMappingFd(name, size) : -1;
>> unsigned flags = MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE;
>>
>> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
>> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc?rev=315533&r1=315532&r2=315533&view=diff
>> ==============================================================================
>> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc (original)
>> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc Wed Oct 11 16:41:32 2017
>> @@ -235,6 +235,31 @@ void *MmapFixedOrDie(uptr fixed_addr, up
>> return p;
>> }
>>
>> +// Uses fixed_addr for now.
>> +// Will use offset instead once we've implemented this function for real.
>> +uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size,
>> + bool tolerate_enomem) {
>> + if (tolerate_enomem) {
>> + return reinterpret_cast<uptr>(MmapFixedOrDieOnFatalError(fixed_addr, size));
>> + }
>> + return reinterpret_cast<uptr>(MmapFixedOrDie(fixed_addr, size));
>> +}
>> +
>> +void ReservedAddressRange::Unmap(uptr addr, uptr size) {
>> + void* addr_as_void = reinterpret_cast<void*>(addr);
>> + uptr base_as_uptr = reinterpret_cast<uptr>(base_);
>> + // Only unmap at the beginning or end of the range.
>> + CHECK_EQ((addr_as_void == base_) || (addr + size == base_as_uptr + size_),
>> + true);
>> + // Detect overflows.
>> + CHECK_LE(size, (base_as_uptr + size_) - addr);
>> + UnmapOrDie(reinterpret_cast<void*>(addr), size);
>> + if (addr_as_void == base_) {
>> + base_ = reinterpret_cast<void*>(addr + size);
>> + }
>> + size_ = size_ - size;
>> +}
>> +
>> void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size) {
>> void *p = VirtualAlloc((LPVOID)fixed_addr, size,
>> MEM_COMMIT, PAGE_READWRITE);
>> @@ -252,6 +277,18 @@ void *MmapNoReserveOrDie(uptr size, cons
>> return MmapOrDie(size, mem_type);
>> }
>>
>> +uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) {
>> + if (fixed_addr) {
>> + base_ = MmapFixedNoAccess(fixed_addr, size, name);
>> + } else {
>> + base_ = MmapNoAccess(size);
>> + }
>> + size_ = size;
>> + name_ = name;
>> + return reinterpret_cast<uptr>(base_);
>> +}
>> +
>> +
>> void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name) {
>> (void)name; // unsupported
>> void *res = VirtualAlloc((LPVOID)fixed_addr, size,
>>
>> Modified: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_common_test.cc
>> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_common_test.cc?rev=315533&r1=315532&r2=315533&view=diff
>> ==============================================================================
>> --- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_common_test.cc (original)
>> +++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_common_test.cc Wed Oct 11 16:41:32 2017
>> @@ -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
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list