diff options
| author | Filipe Cabecinhas <me@filcab.net> | 2017-03-01 18:52:11 +0000 | 
|---|---|---|
| committer | Filipe Cabecinhas <me@filcab.net> | 2017-03-01 18:52:11 +0000 | 
| commit | 74ad311556099eac82005f4ce6c1d78bc65cfcb1 (patch) | |
| tree | dd340c174fbd0e31286ae38ccc1c0fcff9ca7d44 | |
| parent | 91d74813a6020e26301059d3e62490645eb400cd (diff) | |
| download | bcm5719-llvm-74ad311556099eac82005f4ce6c1d78bc65cfcb1.tar.gz bcm5719-llvm-74ad311556099eac82005f4ce6c1d78bc65cfcb1.zip  | |
Reapply r296419: [asan] Print a "PC is at a non-executable memory region" message if that's the case
Summary: Points the user to look at function pointer assignments.
Reviewers: kcc, eugenis, kubamracek
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D30432
llvm-svn: 296653
| -rw-r--r-- | compiler-rt/lib/asan/asan_errors.cc | 11 | ||||
| -rw-r--r-- | compiler-rt/test/asan/TestCases/non-executable-pc.cpp | 33 | 
2 files changed, 44 insertions, 0 deletions
diff --git a/compiler-rt/lib/asan/asan_errors.cc b/compiler-rt/lib/asan/asan_errors.cc index 7829dd1dcda..eb3ed001205 100644 --- a/compiler-rt/lib/asan/asan_errors.cc +++ b/compiler-rt/lib/asan/asan_errors.cc @@ -58,6 +58,16 @@ static void MaybeDumpRegisters(void *context) {    SignalContext::DumpAllRegisters(context);  } +static void MaybeReportNonExecRegion(uptr pc) { +  MemoryMappingLayout proc_maps(/*cache_enabled*/ true); +  uptr start, end, protection; +  while (proc_maps.Next(&start, &end, nullptr, nullptr, 0, &protection)) { +    if (pc >= start && pc < end && +        !(protection & MemoryMappingLayout::kProtectionExecute)) +      Report("Hint: PC is at a non-executable region. Maybe a wild jump?\n"); +  } +} +  void ErrorDeadlySignal::Print() {    Decorator d;    Printf("%s", d.Warning()); @@ -77,6 +87,7 @@ void ErrorDeadlySignal::Print() {      if (addr < GetPageSizeCached())        Report("Hint: address points to the zero page.\n");    } +  MaybeReportNonExecRegion(pc);    scariness.Print();    BufferedStackTrace stack;    GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, context, diff --git a/compiler-rt/test/asan/TestCases/non-executable-pc.cpp b/compiler-rt/test/asan/TestCases/non-executable-pc.cpp new file mode 100644 index 00000000000..f8adee613b0 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/non-executable-pc.cpp @@ -0,0 +1,33 @@ +// RUN: %clangxx_asan %s -o %t +// RUN: not %run %t 0 2>&1 | FileCheck %s +// RUN: not %run %t n 2>&1 | FileCheck %s -check-prefix=CHECK -check-prefix=NON_EXEC + +// Only Linux and FreeBSD list every memory region in MemoryMappingLayout, for now. +// REQUIRES: linux || freebsd + +#include <assert.h> + +typedef void void_f(); +int main(int argc, char **argv) { +  char *array = new char[42]; +  void_f *func; +  assert(argc > 1); +  if (argv[1][0] == '0') { +    func = (void_f *)0x04; +  } else { +    assert(argv[1][0] == 'n'); +    func = (void_f *)array; +  } + +  func(); +  // x86 reports the SEGV with both address=X and pc=X. +  // On PowerPC64 ELFv1, the pointer is taken to be a function-descriptor +  // pointer out of which three 64-bit quantities are read. This will SEGV, but +  // the compiler is free to choose the order. As a result, the address is +  // either X, X+0x8 or X+0x10. The pc is still in main() because it has not +  // actually made the call when the faulting access occurs. +  // CHECK: DEADLYSIGNAL +  // CHECK: {{AddressSanitizer: (SEGV|access-violation).*(address|pc) }} +  // NON_EXEC: PC is at a non-executable region. Maybe a wild jump? +  return 0; +}  | 

