1 //===-- segv_handler.h ------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef GWP_ASAN_OPTIONAL_SEGV_HANDLER_H_ 10 #define GWP_ASAN_OPTIONAL_SEGV_HANDLER_H_ 11 12 #include "gwp_asan/guarded_pool_allocator.h" 13 #include "gwp_asan/options.h" 14 15 namespace gwp_asan { 16 namespace crash_handler { 17 // ================================ Requirements =============================== 18 // This function must be provided by the supporting allocator only when this 19 // provided crash handler is used to dump the generic report. 20 // sanitizer::Printf() function can be simply used here. 21 // ================================ Description ================================ 22 // This function shall produce output according to a strict subset of the C 23 // standard library's printf() family. This function must support printing the 24 // following formats: 25 // 1. integers: "%([0-9]*)?(z|ll)?{d,u,x,X}" 26 // 2. pointers: "%p" 27 // 3. strings: "%[-]([0-9]*)?(\\.\\*)?s" 28 // 4. chars: "%c" 29 // This function must be implemented in a signal-safe manner, and thus must not 30 // malloc(). 31 // =================================== Notes =================================== 32 // This function has a slightly different signature than the C standard 33 // library's printf(). Notably, it returns 'void' rather than 'int'. 34 typedef void (*Printf_t)(const char *Format, ...); 35 36 // ================================ Requirements =============================== 37 // This function is required for the supporting allocator, but one of the three 38 // provided implementations may be used (RTGwpAsanBacktraceLibc, 39 // RTGwpAsanBacktraceSanitizerCommon, or BasicPrintBacktraceFunction). 40 // ================================ Description ================================ 41 // This function shall take the backtrace provided in `TraceBuffer`, and print 42 // it in a human-readable format using `Print`. Generally, this function shall 43 // resolve raw pointers to section offsets and print them with the following 44 // sanitizer-common format: 45 // " #{frame_number} {pointer} in {function name} ({binary name}+{offset}" 46 // e.g. " #5 0x420459 in _start (/tmp/uaf+0x420459)" 47 // This format allows the backtrace to be symbolized offline successfully using 48 // llvm-symbolizer. 49 // =================================== Notes =================================== 50 // This function may directly or indirectly call malloc(), as the 51 // GuardedPoolAllocator contains a reentrancy barrier to prevent infinite 52 // recursion. Any allocation made inside this function will be served by the 53 // supporting allocator, and will not have GWP-ASan protections. 54 typedef void (*PrintBacktrace_t)(uintptr_t *TraceBuffer, size_t TraceLength, 55 Printf_t Print); 56 57 // Returns a function pointer to a basic PrintBacktrace implementation. This 58 // implementation simply prints the stack trace in a human readable fashion 59 // without any symbolization. 60 PrintBacktrace_t getBasicPrintBacktraceFunction(); 61 62 // Returns a function pointer to a backtrace function that's suitable for 63 // unwinding through a signal handler. This is important primarily for frame- 64 // pointer based unwinders, DWARF or other unwinders can simply provide the 65 // normal backtrace function as the implementation here. On POSIX, SignalContext 66 // should be the `ucontext_t` from the signal handler. 67 typedef size_t (*SegvBacktrace_t)(uintptr_t *TraceBuffer, size_t Size, 68 void *SignalContext); 69 SegvBacktrace_t getSegvBacktraceFunction(); 70 71 // Install the SIGSEGV crash handler for printing use-after-free and heap- 72 // buffer-{under|over}flow exceptions if the user asked for it. This is platform 73 // specific as even though POSIX and Windows both support registering handlers 74 // through signal(), we have to use platform-specific signal handlers to obtain 75 // the address that caused the SIGSEGV exception. GPA->init() must be called 76 // before this function. 77 void installSignalHandlers(gwp_asan::GuardedPoolAllocator *GPA, Printf_t Printf, 78 PrintBacktrace_t PrintBacktrace, 79 SegvBacktrace_t SegvBacktrace); 80 81 void uninstallSignalHandlers(); 82 83 void dumpReport(uintptr_t ErrorPtr, const gwp_asan::AllocatorState *State, 84 const gwp_asan::AllocationMetadata *Metadata, 85 SegvBacktrace_t SegvBacktrace, Printf_t Printf, 86 PrintBacktrace_t PrintBacktrace, void *Context); 87 } // namespace crash_handler 88 } // namespace gwp_asan 89 90 #endif // GWP_ASAN_OPTIONAL_SEGV_HANDLER_H_ 91