Enable build-tunable asan shadow scale size 85/210385/3
authorMikhail Kashkarov <m.kashkarov@partner.samsung.com>
Fri, 28 Jun 2019 18:31:32 +0000 (21:31 +0300)
committerDongkyun Son <dongkyun.s@samsung.com>
Mon, 22 Jul 2019 12:16:35 +0000 (12:16 +0000)
Use the following for the project config (3 is default):

  %define asan_shadow_scale 3
  Macros:
  asan_shadow_scale 3
  :Macros

+ backport https://reviews.llvm.org/D39471 for x86_64 shadow offset
+ backport https://reviews.llvm.org/D39472 for minimum redzone size
+ backport https://reviews.llvm.org/D39473 for internal alloc min alignment
+ backport https://reviews.llvm.org/D39474 to avoid assert failure for non-default shadow scale

Change-Id: I23b231f03d6ab47c6b4264f8c7837eb1197f4cc4

13 files changed:
gcc/asan.h
gcc/config/i386/i386.c
libsanitizer/asan/asan_activation.cc
libsanitizer/asan/asan_fake_stack.cc
libsanitizer/asan/asan_flags.cc
libsanitizer/asan/asan_mapping.h
libsanitizer/asan/asan_rtl.cc
libsanitizer/sanitizer_common/sanitizer_allocator.cc
libsanitizer/sanitizer_common/sanitizer_common.h
packaging/gcc-aarch64.spec
packaging/gcc-armv7hl.spec
packaging/gcc-armv7l.spec
packaging/linaro-gcc.spec

index 511da9a..66f7e90 100644 (file)
@@ -43,7 +43,11 @@ extern hash_set <tree> *asan_used_labels;
 
 /* Shadow memory is found at
    (address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
+#if defined(ASAN_SHADOW_SCALE)
+#define ASAN_SHADOW_SHIFT      ASAN_SHADOW_SCALE
+#else
 #define ASAN_SHADOW_SHIFT      3
+#endif
 #define ASAN_SHADOW_GRANULARITY (1UL << ASAN_SHADOW_SHIFT)
 
 /* Red zone size, stack and global variables are padded by ASAN_RED_ZONE_SIZE
index 898c247..bd043c4 100644 (file)
@@ -79,6 +79,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dojump.h"
 #include "fold-const-call.h"
 #include "tree-ssanames.h"
+#include "asan.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -7374,12 +7375,20 @@ ix86_legitimate_combined_insn (rtx_insn *insn)
 \f
 /* Implement the TARGET_ASAN_SHADOW_OFFSET hook.  */
 
+#if !defined(TARGET_MACHO) && !defined(ASAN_SHADOW_SHIFT)
+#  error ASAN_SHADOW_SHIFT is not defined
+#endif
+
+static const unsigned HOST_WIDE_INT asan_short_64bit_shadow_offset =
+  0x7FFFFFFF & (~0xFFFULL << ASAN_SHADOW_SHIFT);
+
 static unsigned HOST_WIDE_INT
 ix86_asan_shadow_offset (void)
 {
-  return TARGET_LP64 ? (TARGET_MACHO ? (HOST_WIDE_INT_1 << 44)
-                                    : HOST_WIDE_INT_C (0x7fff8000))
-                    : (HOST_WIDE_INT_1 << 29);
+  return TARGET_LP64
+             ? (TARGET_MACHO ? (HOST_WIDE_INT_1 << 44)
+                             :  asan_short_64bit_shadow_offset)
+             : (HOST_WIDE_INT_1 << 29);
 }
 \f
 /* Argument support functions.  */
index 26798e7..0c0ae09 100644 (file)
 #include "asan_allocator.h"
 #include "asan_flags.h"
 #include "asan_internal.h"
+#include "asan_mapping.h"
 #include "asan_poisoning.h"
 #include "asan_stack.h"
+#include "sanitizer_common/sanitizer_common.h"
 #include "sanitizer_common/sanitizer_flags.h"
 
 namespace __asan {
@@ -107,8 +109,9 @@ void AsanDeactivate() {
 
   AllocatorOptions disabled = asan_deactivated_flags.allocator_options;
   disabled.quarantine_size_mb = 0;
-  disabled.min_redzone = 16;  // Redzone must be at least 16 bytes long.
-  disabled.max_redzone = 16;
+  // Redzone must be at least Max(16, granularity) bytes long.
+  disabled.min_redzone = Max(16, (int)SHADOW_GRANULARITY);
+  disabled.max_redzone = disabled.min_redzone;
   disabled.alloc_dealloc_mismatch = false;
   disabled.may_return_null = true;
   ReInitializeAllocator(disabled);
index bf7566a..a2e3f4e 100644 (file)
@@ -26,9 +26,9 @@ static const u64 kAllocaRedzoneMask = 31UL;
 
 // For small size classes inline PoisonShadow for better performance.
 ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) {
-  CHECK_EQ(SHADOW_SCALE, 3);  // This code expects SHADOW_SCALE=3.
   u64 *shadow = reinterpret_cast<u64*>(MemToShadow(ptr));
-  if (class_id <= 6) {
+  if (SHADOW_SCALE == 3 && class_id <= 6) {
+    // This code expects SHADOW_SCALE=3.
     for (uptr i = 0; i < (((uptr)1) << class_id); i++) {
       shadow[i] = magic;
       // Make sure this does not become memset.
index 39473bb..6639841 100644 (file)
@@ -13,6 +13,7 @@
 #include "asan_activation.h"
 #include "asan_flags.h"
 #include "asan_interface_internal.h"
+#include "asan_mapping.h"
 #include "asan_stack.h"
 #include "lsan/lsan_common.h"
 #include "sanitizer_common/sanitizer_common.h"
@@ -133,6 +134,9 @@ void InitializeFlags() {
            SanitizerToolName);
     Die();
   }
+  // Ensure that redzone is at least SHADOW_GRANULARITY.
+  if (f->redzone < (int)SHADOW_GRANULARITY)
+    f->redzone = SHADOW_GRANULARITY;
   // Make "strict_init_order" imply "check_initialization_order".
   // TODO(samsonov): Use a single runtime flag for an init-order checker.
   if (f->strict_init_order) {
index b9fa5f7..040cde6 100644 (file)
 // || `[0x30000000, 0x35ffffff]` || LowShadow  ||
 // || `[0x00000000, 0x2fffffff]` || LowMem     ||
 
+#if defined(ASAN_SHADOW_SCALE)
+static const u64 kDefaultShadowScale = ASAN_SHADOW_SCALE;
+#else
 static const u64 kDefaultShadowScale = 3;
+#endif
 static const u64 kDefaultShadowSentinel = ~(uptr)0;
 static const u64 kDefaultShadowOffset32 = 1ULL << 29;  // 0x20000000
 static const u64 kDefaultShadowOffset64 = 1ULL << 44;
-static const u64 kDefaultShort64bitShadowOffset = 0x7FFF8000;  // < 2G.
+static const u64 kDefaultShort64bitShadowOffset =
+    0x7FFFFFFF & (~0xFFFULL << kDefaultShadowScale);  // < 2G.
 static const u64 kIosShadowOffset32 = 1ULL << 30;  // 0x40000000
 static const u64 kIosShadowOffset64 = 0x120200000;
 static const u64 kIosSimShadowOffset32 = 1ULL << 30;
index 5bafb9a..9ff2900 100644 (file)
@@ -469,6 +469,7 @@ static void AsanInitInternal() {
   MaybeReexec();
 
   // Setup internal allocator callback.
+  SetLowLevelAllocateMinAlignment(SHADOW_GRANULARITY);
   SetLowLevelAllocateCallback(OnLowLevelAllocate);
 
   InitializeAsanInterceptors();
index 5af4fba..d68c207 100644 (file)
@@ -175,11 +175,13 @@ void InternalFree(void *addr, InternalAllocatorCache *cache) {
 }
 
 // LowLevelAllocator
+constexpr uptr kLowLevelAllocatorDefaultAlignment = 8;
+static uptr low_level_alloc_min_alignment = kLowLevelAllocatorDefaultAlignment;
 static LowLevelAllocateCallback low_level_alloc_callback;
 
 void *LowLevelAllocator::Allocate(uptr size) {
   // Align allocation size.
-  size = RoundUpTo(size, 8);
+  size = RoundUpTo(size, low_level_alloc_min_alignment);
   if (allocated_end_ - allocated_current_ < (sptr)size) {
     uptr size_to_allocate = Max(size, GetPageSizeCached());
     allocated_current_ =
@@ -196,6 +198,11 @@ void *LowLevelAllocator::Allocate(uptr size) {
   return res;
 }
 
+void SetLowLevelAllocateMinAlignment(uptr alignment) {
+  CHECK(IsPowerOfTwo(alignment));
+  low_level_alloc_min_alignment = Max(alignment, low_level_alloc_min_alignment);
+}
+
 void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback) {
   low_level_alloc_callback = callback;
 }
index fb06aa4..79017ca 100644 (file)
@@ -174,6 +174,8 @@ class LowLevelAllocator {
   char *allocated_end_;
   char *allocated_current_;
 };
+// Set the min alignment of LowLevelAllocator to at least alignment.
+void SetLowLevelAllocateMinAlignment(uptr alignment);
 typedef void (*LowLevelAllocateCallback)(uptr ptr, uptr size);
 // Allows to register tool-specific callbacks for LowLevelAllocator.
 // Passing NULL removes the callback.
index 52a7c9d..25eaa94 100644 (file)
@@ -727,6 +727,7 @@ if [ ! -z "$(echo $RPM_OPT_FLAGS | grep -o "\B\-Wformat\-")" ]; then
 fi
 
 %{?asan: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -DASAN_INIT_FIRST) }
+%{?asan_shadow_scale: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -Wp,-DASAN_SHADOW_SCALE=%{asan_shadow_scale})}
 
 %ifarch armv7l armv7hl aarch64
 %undefine gcc_profiledbootstrap
index 3540bfe..b5a36ff 100644 (file)
@@ -727,6 +727,7 @@ if [ ! -z "$(echo $RPM_OPT_FLAGS | grep -o "\B\-Wformat\-")" ]; then
 fi
 
 %{?asan: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -DASAN_INIT_FIRST) }
+%{?asan_shadow_scale: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -Wp,-DASAN_SHADOW_SCALE=%{asan_shadow_scale})}
 
 %ifarch armv7l armv7hl aarch64
 %undefine gcc_profiledbootstrap
index f9a6241..fda85b8 100644 (file)
@@ -727,6 +727,7 @@ if [ ! -z "$(echo $RPM_OPT_FLAGS | grep -o "\B\-Wformat\-")" ]; then
 fi
 
 %{?asan: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -DASAN_INIT_FIRST) }
+%{?asan_shadow_scale: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -Wp,-DASAN_SHADOW_SCALE=%{asan_shadow_scale})}
 
 %ifarch armv7l armv7hl aarch64
 %undefine gcc_profiledbootstrap
index 52a1b5f..fde4e38 100644 (file)
@@ -724,6 +724,7 @@ if [ ! -z "$(echo $RPM_OPT_FLAGS | grep -o "\B\-Wformat\-")" ]; then
 fi
 
 %{?asan: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -DASAN_INIT_FIRST) }
+%{?asan_shadow_scale: RPM_OPT_FLAGS=$(echo $RPM_OPT_FLAGS -Wp,-DASAN_SHADOW_SCALE=%{asan_shadow_scale})}
 
 %ifarch armv7l armv7hl aarch64
 %undefine gcc_profiledbootstrap