From d2224e17c3ec684a51024c7af2807ccab400a7dd Mon Sep 17 00:00:00 2001 From: Dmitry Mikulin Date: Wed, 27 Sep 2017 23:32:01 +0000 Subject: [PATCH] ASan allocates a global data initialization array at the tail end of each compunit's .data section. This vector is not poisoned. Because of this the first symbol of the following section has no left red zone. As a result, ASan cannot detect underflow for such symbols. Poison ASan allocated metadata, it should not be accessible to user code. This fix does not eliminate the problem with missing left red zones but it reduces the set of vulnerable symbols from first symbols in each input data section to first symbols in the output section of the binary. Differential Revision: https://reviews.llvm.org/D38056 llvm-svn: 314365 --- compiler-rt/lib/asan/asan_globals.cc | 4 ++++ .../test/asan/TestCases/Helpers/underflow.cc | 1 + .../test/asan/TestCases/global-underflow.cc | 17 +++++++++++++++++ 3 files changed, 22 insertions(+) create mode 100644 compiler-rt/test/asan/TestCases/Helpers/underflow.cc create mode 100644 compiler-rt/test/asan/TestCases/global-underflow.cc diff --git a/compiler-rt/lib/asan/asan_globals.cc b/compiler-rt/lib/asan/asan_globals.cc index eebada804f07c..ed1e4c614a26b 100644 --- a/compiler-rt/lib/asan/asan_globals.cc +++ b/compiler-rt/lib/asan/asan_globals.cc @@ -384,6 +384,10 @@ void __asan_register_globals(__asan_global *globals, uptr n) { } RegisterGlobal(&globals[i]); } + + // Poison the metadata. It should not be accessible to user code. + PoisonShadow(reinterpret_cast(globals), n * sizeof(__asan_global), + kAsanGlobalRedzoneMagic); } // Unregister an array of globals. diff --git a/compiler-rt/test/asan/TestCases/Helpers/underflow.cc b/compiler-rt/test/asan/TestCases/Helpers/underflow.cc new file mode 100644 index 0000000000000..26979482fab18 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/Helpers/underflow.cc @@ -0,0 +1 @@ +int YYY[3]={1,2,3}; diff --git a/compiler-rt/test/asan/TestCases/global-underflow.cc b/compiler-rt/test/asan/TestCases/global-underflow.cc new file mode 100644 index 0000000000000..4a03513567cd2 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/global-underflow.cc @@ -0,0 +1,17 @@ +// RUN: %clangxx_asan -O0 %s %p/Helpers/underflow.cc -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s %p/Helpers/underflow.cc -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s %p/Helpers/underflow.cc -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s %p/Helpers/underflow.cc -o %t && not %run %t 2>&1 | FileCheck %s + +int XXX[2] = {2, 3}; +extern int YYY[]; +#include +int main(int argc, char **argv) { + memset(XXX, 0, 2*sizeof(int)); + // CHECK: {{READ of size 4 at 0x.* thread T0}} + // CHECK: {{ #0 0x.* in main .*global-underflow.cc:}}[[@LINE+3]] + // CHECK: {{0x.* is located 4 bytes to the left of global variable}} + // CHECK: {{.*YYY.* of size 12}} + int res = YYY[-1]; + return res; +}