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; +} |