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

Timur Iskhodzhanov timurrrr at google.com
Mon Jul 14 07:35:18 PDT 2014


r212943, thanks for catching!

2014-07-12 0:16 GMT+04:00 Timur Iskhodzhanov <timurrrr at google.com>:
> Ah sorry, now I see what you were talking about :)
> Will fix on Monday.
>
> The regexp should be fixed in the "common" test too, indeed.
>
> 2014-07-12 0:01 GMT+04:00 Alexey Samsonov <vonosmas at gmail.com>:
>> I'm fine with committing a Windows-specific test case, and don't see how it
>> relates to my comment. If you're copying a test case and modifying some bits
>> of it, RUN-line should be modified accordingly.
>>
>> On Fri, Jul 11, 2014 at 12:44 PM, Timur Iskhodzhanov <timurrrr at google.com>
>> wrote:
>>>
>>> The problem is that we don't currently run the tests from
>>> test/asan/TestCases on Windows.  This is subject to fix soon; I just wanted
>>> to get this feature covered sooner.
>>>
>>> 11 июля 2014 г. 22:15 пользователь "Alexey Samsonov" <vonosmas at gmail.com>
>>> написал:
>>>
>>>>
>>>> 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
>>
>>
>>
>>
>> --
>> Alexey Samsonov
>> vonosmas at gmail.com




More information about the llvm-commits mailing list