[compiler-rt] r212807 - [ASan/Win] Catch NULL derefs and page faults

Alexey Samsonov vonosmas at gmail.com
Fri Jul 11 11:15:45 PDT 2014


On Fri, Jul 11, 2014 at 4:57 AM, Timur Iskhodzhanov <timurrrr at google.com>
wrote:

> Author: timurrrr
> Date: Fri Jul 11 06:57:41 2014
> New Revision: 212807
>
> URL: http://llvm.org/viewvc/llvm-project?rev=212807&view=rev
> Log:
> [ASan/Win] Catch NULL derefs and page faults
>
> Reviewed at http://reviews.llvm.org/D4471
>
> Added:
>     compiler-rt/trunk/test/asan/TestCases/Windows/null_deref.cc
> Modified:
>     compiler-rt/trunk/lib/asan/asan_posix.cc
>     compiler-rt/trunk/lib/asan/asan_report.cc
>     compiler-rt/trunk/lib/asan/asan_report.h
>     compiler-rt/trunk/lib/asan/asan_win.cc
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
>
> Modified: compiler-rt/trunk/lib/asan/asan_posix.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_posix.cc?rev=212807&r1=212806&r2=212807&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/asan/asan_posix.cc (original)
> +++ compiler-rt/trunk/lib/asan/asan_posix.cc Fri Jul 11 06:57:41 2014
> @@ -50,7 +50,7 @@ void AsanOnSIGSEGV(int, void *siginfo, v
>        (code == si_SEGV_MAPERR || code == si_SEGV_ACCERR))
>      ReportStackOverflow(pc, sp, bp, context, addr);
>    else
> -    ReportSIGSEGV(pc, sp, bp, context, addr);
> +    ReportSIGSEGV("SEGV", pc, sp, bp, context, addr);
>  }
>
>  // ---------------------- TSD ---------------- {{{1
>
> Modified: compiler-rt/trunk/lib/asan/asan_report.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.cc?rev=212807&r1=212806&r2=212807&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/asan/asan_report.cc (original)
> +++ compiler-rt/trunk/lib/asan/asan_report.cc Fri Jul 11 06:57:41 2014
> @@ -611,14 +611,15 @@ void ReportStackOverflow(uptr pc, uptr s
>    ReportErrorSummary("stack-overflow", &stack);
>  }
>
> -void ReportSIGSEGV(uptr pc, uptr sp, uptr bp, void *context, uptr addr) {
> +void ReportSIGSEGV(const char *description, uptr pc, uptr sp, uptr bp,
> +                   void *context, uptr addr) {
>    ScopedInErrorReport in_report;
>    Decorator d;
>    Printf("%s", d.Warning());
>    Report(
> -      "ERROR: AddressSanitizer: SEGV on unknown address %p"
> +      "ERROR: AddressSanitizer: %s on unknown address %p"
>        " (pc %p sp %p bp %p T%d)\n",
> -      (void *)addr, (void *)pc, (void *)sp, (void *)bp,
> +      description, (void *)addr, (void *)pc, (void *)sp, (void *)bp,
>        GetCurrentTidOrInvalid());
>    Printf("%s", d.EndWarning());
>    GET_STACK_TRACE_SIGNAL(pc, bp, context);
>
> Modified: compiler-rt/trunk/lib/asan/asan_report.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.h?rev=212807&r1=212806&r2=212807&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/asan/asan_report.h (original)
> +++ compiler-rt/trunk/lib/asan/asan_report.h Fri Jul 11 06:57:41 2014
> @@ -34,8 +34,8 @@ void DescribeThread(AsanThreadContext *c
>  // Different kinds of error reports.
>  void NORETURN
>      ReportStackOverflow(uptr pc, uptr sp, uptr bp, void *context, uptr
> addr);
> -void NORETURN
> -    ReportSIGSEGV(uptr pc, uptr sp, uptr bp, void *context, uptr addr);
> +void NORETURN ReportSIGSEGV(const char *description, uptr pc, uptr sp,
> uptr bp,
> +                            void *context, uptr addr);
>  void NORETURN ReportDoubleFree(uptr addr, StackTrace *free_stack);
>  void NORETURN ReportFreeNotMalloced(uptr addr, StackTrace *free_stack);
>  void NORETURN ReportAllocTypeMismatch(uptr addr, StackTrace *free_stack,
>
> Modified: compiler-rt/trunk/lib/asan/asan_win.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win.cc?rev=212807&r1=212806&r2=212807&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/asan/asan_win.cc (original)
> +++ compiler-rt/trunk/lib/asan/asan_win.cc Fri Jul 11 06:57:41 2014
> @@ -21,6 +21,7 @@
>
>  #include "asan_interceptors.h"
>  #include "asan_internal.h"
> +#include "asan_report.h"
>  #include "asan_thread.h"
>  #include "sanitizer_common/sanitizer_libc.h"
>  #include "sanitizer_common/sanitizer_mutex.h"
> @@ -86,6 +87,44 @@ void AsanOnSIGSEGV(int, void *siginfo, v
>    UNIMPLEMENTED();
>  }
>
> +static LPTOP_LEVEL_EXCEPTION_FILTER default_seh_handler;
> +
> +long WINAPI SEHHandler(EXCEPTION_POINTERS *info) {
> +  EXCEPTION_RECORD *exception_record = info->ExceptionRecord;
> +  CONTEXT *context = info->ContextRecord;
> +  uptr pc = (uptr)exception_record->ExceptionAddress;
> +#ifdef _WIN64
> +  uptr bp = (uptr)context->Rbp, sp = (uptr)context->Rsp;
> +#else
> +  uptr bp = (uptr)context->Ebp, sp = (uptr)context->Esp;
> +#endif
> +
> +  if (exception_record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ||
> +      exception_record->ExceptionCode == EXCEPTION_IN_PAGE_ERROR) {
> +    const char *description =
> +        (exception_record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
> +            ? "access-violation"
> +            : "in-page-error";
> +    uptr access_addr = exception_record->ExceptionInformation[1];
> +    ReportSIGSEGV(description, pc, sp, bp, context, access_addr);
> +  }
> +
> +  // FIXME: Handle EXCEPTION_STACK_OVERFLOW here.
> +
> +  return default_seh_handler(info);
> +}
> +
> +int SetSEHFilter() {
> +  default_seh_handler = SetUnhandledExceptionFilter(SEHHandler);
> +  return 0;
> +}
> +
> +// Put a pointer to SetSEHFilter at the end of the global list
> +// of C initializers, after the default handler is set by the CRT.
> +// See crt0dat.c in the CRT sources for the details.
> +#pragma section(".CRT$XIZ", long, read)  // NOLINT
> +__declspec(allocate(".CRT$XIZ")) int (*__intercept_seh)() = SetSEHFilter;
> +
>  }  // namespace __asan
>
>  #endif  // _WIN32
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc?rev=212807&r1=212806&r2=212807&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc Fri Jul 11
> 06:57:41 2014
> @@ -17,9 +17,10 @@
>
>  #define WIN32_LEAN_AND_MEAN
>  #define NOGDI
> -#include <stdlib.h>
> -#include <io.h>
>  #include <windows.h>
> +#include <dbghelp.h>
> +#include <io.h>
> +#include <stdlib.h>
>
>  #include "sanitizer_common.h"
>  #include "sanitizer_libc.h"
> @@ -449,7 +450,30 @@ void StackTrace::SlowUnwindStack(uptr pc
>
>  void StackTrace::SlowUnwindStackWithContext(uptr pc, void *context,
>                                              uptr max_depth) {
> -  UNREACHABLE("no signal context on windows");
> +  CONTEXT ctx = *(CONTEXT *)context;
> +  STACKFRAME64 stack_frame;
> +  memset(&stack_frame, 0, sizeof(stack_frame));
> +  size = 0;
> +#if defined(_WIN64)
> +  int machine_type = IMAGE_FILE_MACHINE_AMD64;
> +  stack_frame.AddrPC.Offset = ctx.Rip;
> +  stack_frame.AddrFrame.Offset = ctx.Rbp;
> +  stack_frame.AddrStack.Offset = ctx.Rsp;
> +#else
> +  int machine_type = IMAGE_FILE_MACHINE_I386;
> +  stack_frame.AddrPC.Offset = ctx.Eip;
> +  stack_frame.AddrFrame.Offset = ctx.Ebp;
> +  stack_frame.AddrStack.Offset = ctx.Esp;
> +#endif
> +  stack_frame.AddrPC.Mode = AddrModeFlat;
> +  stack_frame.AddrFrame.Mode = AddrModeFlat;
> +  stack_frame.AddrStack.Mode = AddrModeFlat;
> +  while (StackWalk64(machine_type, GetCurrentProcess(),
> GetCurrentThread(),
> +                     &stack_frame, &ctx, NULL, &SymFunctionTableAccess64,
> +                     &SymGetModuleBase64, NULL) &&
> +         size < Min(max_depth, kStackTraceMax)) {
> +    trace[size++] = (uptr)stack_frame.AddrPC.Offset;
> +  }
>  }
>
>  void MaybeOpenReportFile() {
>
> Added: compiler-rt/trunk/test/asan/TestCases/Windows/null_deref.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Windows/null_deref.cc?rev=212807&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/test/asan/TestCases/Windows/null_deref.cc (added)
> +++ compiler-rt/trunk/test/asan/TestCases/Windows/null_deref.cc Fri Jul 11
> 06:57:41 2014
> @@ -0,0 +1,15 @@
> +// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
> --check-prefix=CHECK-%os --check-prefix=CHECK
>

stray CHECK-%os?


> +// FIXME: merge this with the common null_deref test when we can run
> common
> +// tests on Windows.
> +
> +__attribute__((noinline))
> +static void NullDeref(int *ptr) {
> +  // CHECK: ERROR: AddressSanitizer: access-violation on unknown address
> +  // CHECK:   {{0x0*000.. .*pc 0x.*}}
> +  ptr[10]++;  // BOOM
> +}
> +int main() {
> +  NullDeref((int*)0);
> +  // CHECK: {{    #1 0x.* in main.*null_deref.cc:}}[[@LINE-1]]
> +  // CHECK: {{AddressSanitizer can not provide additional info.}}
>

I don't think you need {{}} here - it's not a regexp.


> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>



-- 
Alexey Samsonov
vonosmas at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140711/d9f5fbac/attachment.html>


More information about the llvm-commits mailing list