1 //===-- options.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_OPTIONS_H_
10 #define GWP_ASAN_OPTIONS_H_
11 
12 #include <stddef.h>
13 #include <stdint.h>
14 
15 namespace gwp_asan {
16 namespace options {
17 // ================================ Requirements ===============================
18 // This function is required to be implemented by the supporting allocator. The
19 // sanitizer::Printf() function can be simply used here.
20 // ================================ Description ================================
21 // This function shall produce output according to a strict subset of the C
22 // standard library's printf() family. This function must support printing the
23 // following formats:
24 //   1. integers: "%([0-9]*)?(z|ll)?{d,u,x,X}"
25 //   2. pointers: "%p"
26 //   3. strings:  "%[-]([0-9]*)?(\\.\\*)?s"
27 //   4. chars:    "%c"
28 // This function must be implemented in a signal-safe manner.
29 // =================================== Notes ===================================
30 // This function has a slightly different signature than the C standard
31 // library's printf(). Notably, it returns 'void' rather than 'int'.
32 typedef void (*Printf_t)(const char *Format, ...);
33 
34 // ================================ Requirements ===============================
35 // This function is required to be either implemented by the supporting
36 // allocator, or one of the two provided implementations may be used
37 // (RTGwpAsanBacktraceLibc or RTGwpAsanBacktraceSanitizerCommon).
38 // ================================ Description ================================
39 // This function shall collect the backtrace for the calling thread and place
40 // the result in `TraceBuffer`. This function should elide itself and all frames
41 // below itself from `TraceBuffer`, i.e. the caller's frame should be in
42 // TraceBuffer[0], and subsequent frames 1..n into TraceBuffer[1..n], where a
43 // maximum of `Size` frames are stored. Returns the number of frames stored into
44 // `TraceBuffer`, and zero on failure. If the return value of this function is
45 // equal to `Size`, it may indicate that the backtrace is truncated.
46 // =================================== Notes ===================================
47 // This function may directly or indirectly call malloc(), as the
48 // GuardedPoolAllocator contains a reentrancy barrier to prevent infinite
49 // recursion. Any allocation made inside this function will be served by the
50 // supporting allocator, and will not have GWP-ASan protections.
51 typedef size_t (*Backtrace_t)(uintptr_t *TraceBuffer, size_t Size);
52 
53 // ================================ Requirements ===============================
54 // This function is optional for the supporting allocator, but one of the two
55 // provided implementations may be used (RTGwpAsanBacktraceLibc or
56 // RTGwpAsanBacktraceSanitizerCommon). If not provided, a default implementation
57 // is used which prints the raw pointers only.
58 // ================================ Description ================================
59 // This function shall take the backtrace provided in `TraceBuffer`, and print
60 // it in a human-readable format using `Print`. Generally, this function shall
61 // resolve raw pointers to section offsets and print them with the following
62 // sanitizer-common format:
63 //      "  #{frame_number} {pointer} in {function name} ({binary name}+{offset}"
64 // e.g. "  #5 0x420459 in _start (/tmp/uaf+0x420459)"
65 // This format allows the backtrace to be symbolized offline successfully using
66 // llvm-symbolizer.
67 // =================================== Notes ===================================
68 // This function may directly or indirectly call malloc(), as the
69 // GuardedPoolAllocator contains a reentrancy barrier to prevent infinite
70 // recursion. Any allocation made inside this function will be served by the
71 // supporting allocator, and will not have GWP-ASan protections.
72 typedef void (*PrintBacktrace_t)(uintptr_t *TraceBuffer, size_t TraceLength,
73                                  Printf_t Print);
74 
75 struct Options {
76   Printf_t Printf = nullptr;
77   Backtrace_t Backtrace = nullptr;
78   PrintBacktrace_t PrintBacktrace = nullptr;
79 
80   // Read the options from the included definitions file.
81 #define GWP_ASAN_OPTION(Type, Name, DefaultValue, Description)                 \
82   Type Name = DefaultValue;
83 #include "gwp_asan/options.inc"
84 #undef GWP_ASAN_OPTION
85 
86   void setDefaults() {
87 #define GWP_ASAN_OPTION(Type, Name, DefaultValue, Description)                 \
88   Name = DefaultValue;
89 #include "gwp_asan/options.inc"
90 #undef GWP_ASAN_OPTION
91 
92     Printf = nullptr;
93     Backtrace = nullptr;
94     PrintBacktrace = nullptr;
95   }
96 };
97 } // namespace options
98 } // namespace gwp_asan
99 
100 #endif // GWP_ASAN_OPTIONS_H_
101