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
15namespace gwp_asan {
16namespace 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'.
32typedef 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.
51typedef 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.
72typedef void (*PrintBacktrace_t)(uintptr_t *TraceBuffer, size_t TraceLength,
73                                 Printf_t Print);
74
75struct 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