[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