[compiler-rt] 67b950b - [hwasan] Fix allocator alignment.
Evgenii Stepanov via llvm-commits
llvm-commits at lists.llvm.org
Mon May 11 15:46:37 PDT 2020
Author: Evgenii Stepanov
Date: 2020-05-11T15:45:42-07:00
New Revision: 67b950be6d48eb4f8d9d4c450f590b64e769df5d
URL: https://github.com/llvm/llvm-project/commit/67b950be6d48eb4f8d9d4c450f590b64e769df5d
DIFF: https://github.com/llvm/llvm-project/commit/67b950be6d48eb4f8d9d4c450f590b64e769df5d.diff
LOG: [hwasan] Fix allocator alignment.
Summary:
Fix hwasan allocator not respecting the requested alignment when it is
higher than a page, but still within primary (i.e. [2048, 65536]).
Reviewers: pcc, hctim, cryptoad
Subscribers: #sanitizers, llvm-commits
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D79656
Added:
compiler-rt/test/hwasan/TestCases/malloc-align.c
Modified:
compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h
compiler-rt/lib/sanitizer_common/sanitizer_common.h
compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h
index 90603280e7c9..1d9a29c70f30 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary64.h
@@ -72,11 +72,15 @@ class SizeClassAllocator64 {
void Init(s32 release_to_os_interval_ms) {
uptr TotalSpaceSize = kSpaceSize + AdditionalSize();
if (kUsingConstantSpaceBeg) {
+ CHECK(IsAligned(kSpaceBeg, SizeClassMap::kMaxSize));
CHECK_EQ(kSpaceBeg, address_range.Init(TotalSpaceSize,
PrimaryAllocatorName, kSpaceBeg));
} else {
- NonConstSpaceBeg = address_range.Init(TotalSpaceSize,
- PrimaryAllocatorName);
+ // Combined allocator expects that an 2^N allocation is always aligned to
+ // 2^N. For this to work, the start of the space needs to be aligned as
+ // high as the largest size class (which also needs to be a power of 2).
+ NonConstSpaceBeg = address_range.InitAligned(
+ TotalSpaceSize, SizeClassMap::kMaxSize, PrimaryAllocatorName);
CHECK_NE(NonConstSpaceBeg, ~(uptr)0);
}
SetReleaseToOSIntervalMs(release_to_os_interval_ms);
@@ -220,7 +224,7 @@ class SizeClassAllocator64 {
// Test-only.
void TestOnlyUnmap() {
- UnmapWithCallbackOrDie(SpaceBeg(), kSpaceSize + AdditionalSize());
+ UnmapWithCallbackOrDie((uptr)address_range.base(), address_range.size());
}
static void FillMemoryProfile(uptr start, uptr rss, bool file, uptr *stats,
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
index 4ee8dde6c276..ac16e0e47efc 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
@@ -143,6 +143,7 @@ void RunFreeHooks(const void *ptr);
class ReservedAddressRange {
public:
uptr Init(uptr size, const char *name = nullptr, uptr fixed_addr = 0);
+ uptr InitAligned(uptr size, uptr align, const char *name = nullptr);
uptr Map(uptr fixed_addr, uptr size, const char *name = nullptr);
uptr MapOrDie(uptr fixed_addr, uptr size, const char *name = nullptr);
void Unmap(uptr addr, uptr size);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
index 37c5b10e809e..0c918ebb4a9d 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
@@ -129,6 +129,16 @@ void SetSandboxingCallback(void (*f)()) {
sandboxing_callback = f;
}
+uptr ReservedAddressRange::InitAligned(uptr size, uptr align,
+ const char *name) {
+ CHECK(IsPowerOfTwo(align));
+ if (align <= GetPageSizeCached())
+ return Init(size, name);
+ uptr start = Init(size + align, name);
+ start += align - (start & (align - 1));
+ return start;
+}
+
} // namespace __sanitizer
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_sandbox_on_notify,
diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp
index ff1f7f9f5d2b..baf9b37fb955 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_allocator_test.cpp
@@ -1009,7 +1009,7 @@ TEST(SanitizerCommon, LargeMmapAllocatorBlockBegin) {
// Don't test OOM conditions on Win64 because it causes other tests on the same
// machine to OOM.
#if SANITIZER_CAN_USE_ALLOCATOR64 && !SANITIZER_WINDOWS64 && !SANITIZER_ANDROID
-typedef __sanitizer::SizeClassMap<3, 4, 8, 63, 128, 16> SpecialSizeClassMap;
+typedef __sanitizer::SizeClassMap<3, 4, 8, 38, 128, 16> SpecialSizeClassMap;
template <typename AddressSpaceViewTy = LocalAddressSpaceView>
struct AP64_SpecialSizeClassMap {
static const uptr kSpaceBeg = kAllocatorSpace;
diff --git a/compiler-rt/test/hwasan/TestCases/malloc-align.c b/compiler-rt/test/hwasan/TestCases/malloc-align.c
new file mode 100644
index 000000000000..b318641342ff
--- /dev/null
+++ b/compiler-rt/test/hwasan/TestCases/malloc-align.c
@@ -0,0 +1,37 @@
+// Test malloc alignment.
+// RUN: %clang_hwasan -mllvm -hwasan-globals=0 %s -o %t
+// RUN: %run %t
+
+#include <assert.h>
+#include <sanitizer/allocator_interface.h>
+#include <sanitizer/hwasan_interface.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static const size_t sizes[] = {
+ 1, 3, 7, 8, 9, 16, 17, 31, 32, 33,
+ 63, 64, 65, 127, 128, 129, 511, 512, 513, 2047,
+ 2048, 2049, 65535, 65536, 65537, 1048575, 1048576, 1048577};
+static const size_t alignments[] = {8, 16, 64, 256, 1024, 4096, 65536, 131072};
+
+__attribute__((no_sanitize("hwaddress"))) int main() {
+ for (unsigned i = 0; i < sizeof(sizes) / sizeof(*sizes); ++i) {
+ for (unsigned j = 0; j < sizeof(alignments) / sizeof(*alignments); ++j) {
+ size_t size = sizes[i];
+ size_t alignment = alignments[j];
+ fprintf(stderr, "size %zu, alignment %zu (0x%zx)\n", size, alignment,
+ alignment);
+ const int cnt = 10;
+ void *ptrs[cnt];
+ for (int k = 0; k < cnt; ++k) {
+ int res = posix_memalign(&ptrs[k], alignment, size);
+ assert(res == 0);
+ fprintf(stderr, "... addr 0x%zx\n", (size_t)ptrs[k]);
+ assert(((size_t)ptrs[k] & (alignment - 1)) == 0);
+ }
+ for (int k = 0; k < cnt; ++k)
+ free(ptrs[k]);
+ }
+ }
+ return 0;
+}
More information about the llvm-commits
mailing list