[asan] Add __asan_set_shadow_*
authorVitaly Buka <vitalybuka@google.com>
Thu, 18 Aug 2016 00:56:11 +0000 (00:56 +0000)
committerVitaly Buka <vitalybuka@google.com>
Thu, 18 Aug 2016 00:56:11 +0000 (00:56 +0000)
Summary:
We are poisoning small allocas using store instruction from instrumented code.
For larger allocas we'd like to insert function calls instead of multiple stores.

PR27453

Reviewers: kcc, eugenis

Subscribers: llvm-commits, kubabrecka

Differential Revision: https://reviews.llvm.org/D23616

llvm-svn: 279019

compiler-rt/lib/asan/asan_interface_internal.h
compiler-rt/lib/asan/asan_poisoning.cc
compiler-rt/lib/asan/asan_rtl.cc
compiler-rt/lib/asan/asan_win_dll_thunk.cc
compiler-rt/lib/asan/tests/CMakeLists.txt
compiler-rt/lib/asan/tests/asan_internal_interface_test.cc [new file with mode: 0644]

index e6aede0..9462a8c 100644 (file)
@@ -79,6 +79,20 @@ extern "C" {
   SANITIZER_INTERFACE_ATTRIBUTE
   void __asan_after_dynamic_init();
 
+  // Sets bytes of the given range of the shadow memory into specific value.
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __asan_set_shadow_00(uptr addr, uptr size);
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __asan_set_shadow_f1(uptr addr, uptr size);
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __asan_set_shadow_f2(uptr addr, uptr size);
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __asan_set_shadow_f3(uptr addr, uptr size);
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __asan_set_shadow_f5(uptr addr, uptr size);
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __asan_set_shadow_f8(uptr addr, uptr size);
+
   // These two functions are used by instrumented code in the
   // use-after-scope mode. They mark memory for local variables as
   // unaddressable when they leave scope and addressable before the
index 65c4401..e1a3f2d 100644 (file)
@@ -314,6 +314,30 @@ static void PoisonAlignedStackMemory(uptr addr, uptr size, bool do_poison) {
   }
 }
 
+void __asan_set_shadow_00(uptr addr, uptr size) {
+  REAL(memset)((void *)addr, 0, size);
+}
+
+void __asan_set_shadow_f1(uptr addr, uptr size) {
+  REAL(memset)((void *)addr, 0xf1, size);
+}
+
+void __asan_set_shadow_f2(uptr addr, uptr size) {
+  REAL(memset)((void *)addr, 0xf2, size);
+}
+
+void __asan_set_shadow_f3(uptr addr, uptr size) {
+  REAL(memset)((void *)addr, 0xf3, size);
+}
+
+void __asan_set_shadow_f5(uptr addr, uptr size) {
+  REAL(memset)((void *)addr, 0xf5, size);
+}
+
+void __asan_set_shadow_f8(uptr addr, uptr size) {
+  REAL(memset)((void *)addr, 0xf8, size);
+}
+
 void __asan_poison_stack_memory(uptr addr, uptr size) {
   if (!__asan_option_detect_stack_use_after_scope) return;
   VReport(1, "poisoning: %p %zx\n", (void *)addr, size);
index b6297da..a4f82bf 100644 (file)
@@ -264,6 +264,7 @@ static NOINLINE void force_interface_symbols() {
   volatile int fake_condition = 0;  // prevent dead condition elimination.
   // __asan_report_* functions are noreturn, so we need a switch to prevent
   // the compiler from removing any of them.
+  // clang-format off
   switch (fake_condition) {
     case 1: __asan_report_load1(0); break;
     case 2: __asan_report_load2(0); break;
@@ -303,7 +304,14 @@ static NOINLINE void force_interface_symbols() {
     case 37: __asan_unpoison_stack_memory(0, 0); break;
     case 38: __asan_region_is_poisoned(0, 0); break;
     case 39: __asan_describe_address(0); break;
+    case 40: __asan_set_shadow_00(0, 0); break;
+    case 41: __asan_set_shadow_f1(0, 0); break;
+    case 42: __asan_set_shadow_f2(0, 0); break;
+    case 43: __asan_set_shadow_f3(0, 0); break;
+    case 44: __asan_set_shadow_f5(0, 0); break;
+    case 45: __asan_set_shadow_f8(0, 0); break;
   }
+  // clang-format on
 }
 
 static void asan_atexit() {
index 09c3b20..bceb033 100644 (file)
@@ -261,6 +261,13 @@ INTERFACE_FUNCTION(__asan_memcpy);
 INTERFACE_FUNCTION(__asan_memset);
 INTERFACE_FUNCTION(__asan_memmove);
 
+INTERFACE_FUNCTION(__asan_set_shadow_00);
+INTERFACE_FUNCTION(__asan_set_shadow_f1);
+INTERFACE_FUNCTION(__asan_set_shadow_f2);
+INTERFACE_FUNCTION(__asan_set_shadow_f3);
+INTERFACE_FUNCTION(__asan_set_shadow_f5);
+INTERFACE_FUNCTION(__asan_set_shadow_f8);
+
 INTERFACE_FUNCTION(__asan_alloca_poison);
 INTERFACE_FUNCTION(__asan_allocas_unpoison);
 
index e67d0fb..60f47bd 100644 (file)
@@ -193,6 +193,7 @@ set(ASAN_INST_TEST_SOURCES
   asan_asm_test.cc
   asan_globals_test.cc
   asan_interface_test.cc
+  asan_internal_interface_test.cc
   asan_test.cc
   asan_oob_test.cc
   asan_mem_test.cc
diff --git a/compiler-rt/lib/asan/tests/asan_internal_interface_test.cc b/compiler-rt/lib/asan/tests/asan_internal_interface_test.cc
new file mode 100644 (file)
index 0000000..af6ae48
--- /dev/null
@@ -0,0 +1,36 @@
+//===-- asan_internal_interface_test.cc -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+//===----------------------------------------------------------------------===//
+#include "asan_interface_internal.h"
+#include "asan_test_utils.h"
+
+TEST(AddressSanitizerInterface, SetShadow) {
+  std::vector<char> buffer(17, 0xff);
+
+  __asan_set_shadow_00((uptr)buffer.data(), buffer.size());
+  EXPECT_EQ(std::vector<char>(buffer.size(), 0x00), buffer);
+
+  __asan_set_shadow_f1((uptr)buffer.data(), buffer.size());
+  EXPECT_EQ(std::vector<char>(buffer.size(), 0xf1), buffer);
+
+  __asan_set_shadow_f2((uptr)buffer.data(), buffer.size());
+  EXPECT_EQ(std::vector<char>(buffer.size(), 0xf2), buffer);
+
+  __asan_set_shadow_f3((uptr)buffer.data(), buffer.size());
+  EXPECT_EQ(std::vector<char>(buffer.size(), 0xf3), buffer);
+
+  __asan_set_shadow_f5((uptr)buffer.data(), buffer.size());
+  EXPECT_EQ(std::vector<char>(buffer.size(), 0xf5), buffer);
+
+  __asan_set_shadow_f8((uptr)buffer.data(), buffer.size());
+  EXPECT_EQ(std::vector<char>(buffer.size(), 0xf8), buffer);
+}