1 : // Copyright 2014 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // Declares the data structure that will be injected into Asan instrumented
16 : // images and which contains instrumentation-time specified parameters to
17 : // control the runtime. This allows for the specification of default parameters
18 : // that aren't hard coded into the toolchain itself. Overrides may still be
19 : // specified using the existing environment variable system.
20 :
21 : #ifndef SYZYGY_COMMON_ASAN_PARAMETERS_H_
22 : #define SYZYGY_COMMON_ASAN_PARAMETERS_H_
23 :
24 : #include <set>
25 : #include <string>
26 : #include <vector>
27 :
28 : #include "base/basictypes.h"
29 : #include "base/strings/string_piece.h"
30 : #include "syzygy/common/assertions.h"
31 :
32 : namespace common {
33 :
34 : #pragma pack(push, 1)
35 :
36 : // The type used by stack IDs. This must be compatible with that used by
37 : // the StackCaptureCache.
38 : typedef uint32 AsanStackId;
39 :
40 : static const size_t kAsanParametersReserved1Bits = 22;
41 :
42 : // This data structure is injected into an instrumented image in a read-only
43 : // section. It is initialized by the instrumenter, and will be looked up at
44 : // runtime by the SyzyAsan RTL. Values in this structure (if present) will
45 : // override hard-coded default values. Values in this structure may be
46 : // superceded by environment variable parameter settings.
47 : struct AsanParameters {
48 : // The first two members of this structure are fixed, and must always be
49 : // present. This allows for the detection of version shear between RTLs and
50 : // instrumented code.
51 :
52 : // The overall size of the structure. This should include the total size of
53 : // any variable sized data included at the end of this structure as laid out
54 : // in an image.
55 : uint32 size;
56 : // The version number of this structure.
57 : uint32 version;
58 :
59 : // The parameters should not change in size or offset. This structure should
60 : // be strictly added to, keeping it backwards compatible.
61 :
62 : // HeapProxy: The maximum size the quarantine may grow to, in bytes.
63 : uint32 quarantine_size;
64 : // StackCaptureCache: The number of allocations between reports of the stack
65 : // trace cache compression ratio. A value of zero means no reports are
66 : // generated.
67 : uint32 reporting_period;
68 : // StackCaptureCache: The number of bottom frames to skip on a stack trace.
69 : uint32 bottom_frames_to_skip;
70 : // StackCapture: The max number of frames for a stack trace.
71 : uint32 max_num_frames;
72 : // HeapProxy: The size of the padding added to every memory block trailer.
73 : uint32 trailer_padding_size;
74 : // AsanRuntime: The stack ids we ignore, as a null terminated list. Set
75 : // this to NULL if there are no stack ids specified.
76 : AsanStackId* ignored_stack_ids;
77 : // HeapProxy: The maximum size of any single block that may be admitted to
78 : // the quarantine.
79 : uint32 quarantine_block_size;
80 :
81 : // Bitfield of boolean values. When this bitfield is full add an entirely new
82 : // one at the end of the structure.
83 : union {
84 : uint32 bitfield1;
85 : struct {
86 : // AsanLogger: If true, we should generate a minidump whenever an error is
87 : // detected.
88 : unsigned minidump_on_failure : 1;
89 : // AsanRuntime: If we should stop the logger (and the running program)
90 : // after reporting an error.
91 : unsigned exit_on_failure : 1;
92 : // AsanLogger: If true, we should generate a textual log describing any
93 : // errors.
94 : unsigned log_as_text : 1;
95 : // AsanRuntime: If true, we should check if the heap is corrupt on
96 : // failure.
97 : unsigned check_heap_on_failure : 1;
98 : // AsanRuntime: If true, we won't try to report the crashes via breakpad
99 : // on failure.
100 : unsigned disable_breakpad_reporting : 1;
101 : // BlockHeapManager: Indicates if CtMalloc should be used to serve the
102 : // user's allocations.
103 : unsigned enable_ctmalloc : 1;
104 : // ZebraBlockHeap: If true the ZebraBlockHeap will be used by the heap
105 : // manager.
106 : unsigned enable_zebra_block_heap : 1;
107 : // LargeBlockHeap: If true then the LargeBlockHeap will be used by the
108 : // heap manager.
109 : unsigned enable_large_block_heap : 1;
110 : // BlockHeapManager: Indicates if the allocation filtering is enabled. If
111 : // so, only blocks from filtered sites can make it into the zebra heap.
112 : unsigned enable_allocation_filter : 1;
113 : // BlockHeapManager: Indicates if we want to use the rate targeted heaps
114 : // to reduce the aliasing of the low frequency allocation sites.
115 : unsigned enable_rate_targeted_heaps : 1;
116 :
117 : // Add new flags here!
118 :
119 : unsigned reserved1 : kAsanParametersReserved1Bits;
120 : };
121 : };
122 :
123 : // HeapProxy: The rate at which allocations are instrumented with header and
124 : // footer guards. This happens for each allocation via a runtime cointoss.
125 : // A value in the range 0.0 to 1.0, inclusive.
126 : float allocation_guard_rate;
127 :
128 : // ZebraBlockHeap: The size of the ZebraBlockHeap.
129 : uint32 zebra_block_heap_size;
130 :
131 : // ZebraBlockHeap: The ratio of the memory used for the quarantine.
132 : float zebra_block_heap_quarantine_ratio;
133 :
134 : // LargeBlockHeap: The minimum size of allocations that will be passed to
135 : // the large block heap.
136 : uint32 large_allocation_threshold;
137 :
138 : // Add new parameters here!
139 :
140 : // When laid out in memory the ignored_stack_ids are present here as a NULL
141 : // terminated vector.
142 : };
143 : COMPILE_ASSERT_IS_POD_OF_SIZE(AsanParameters, 56);
144 :
145 : // The current version of the Asan parameters structure. This must be updated
146 : // if any changes are made to the above structure! This is defined in the header
147 : // file to allow compile time assertions against this version number.
148 : const uint32 kAsanParametersVersion = 8u;
149 :
150 : // If the number of free bits in the parameters struct changes, then the
151 : // version has to change as well. This is simply here to make sure that
152 : // everything changes in lockstep.
153 : COMPILE_ASSERT(kAsanParametersReserved1Bits == 22 &&
154 : kAsanParametersVersion == 8,
155 : version_must_change_if_reserved_bits_changes);
156 :
157 : // The name of the section that will be injected into an instrumented image,
158 : // and contain the AsanParameters structure. Asan can't use your typical entry
159 : // hook because the entry hook is called after the RTL has initialized itself.
160 : // Instead the RTL scans through libraries in its memory and looks for a
161 : // telltale section containing parameters. The first set of parameters it
162 : // encounters are used. After that it may override some of them with environment
163 : // variable configuration.
164 : extern const char kAsanParametersSectionName[];
165 : extern const uint32 kAsanParametersSectionCharacteristics;
166 :
167 : #pragma pack(pop)
168 :
169 : // An inflated version of AsanParameters for dynamically parsing into. This can
170 : // then be flattened into a FlatAsanParameters object. In this representation
171 : // variable sized fields of the flat representation are backed by STL
172 : // containers.
173 : struct InflatedAsanParameters : public AsanParameters {
174 : InflatedAsanParameters();
175 :
176 : std::set<AsanStackId> ignored_stack_ids_set;
177 :
178 : protected:
179 : // Deprecate use of this field in favour of the STL set version.
180 : using AsanParameters::ignored_stack_ids;
181 : };
182 :
183 : // A flat version of AsanParameters, backed by a vector for housing the variable
184 : // sized data. This is a read-only structure.
185 : class FlatAsanParameters {
186 : public:
187 : // Constructs a flat parameter representation from the given set of parsed
188 : // parameters.
189 : explicit FlatAsanParameters(const InflatedAsanParameters& asan_parameters);
190 :
191 : // @name Accessors.
192 : // @{
193 E : const std::vector<uint8>& data() const { return data_; }
194 E : const AsanParameters& params() const {
195 E : return *reinterpret_cast<const AsanParameters*>(data_.data());
196 E : }
197 E : const AsanParameters* operator->() const {
198 E : return reinterpret_cast<const AsanParameters*>(data_.data());
199 E : }
200 : // @}
201 :
202 : protected:
203 : // The data backing the Asan parameters.
204 : std::vector<uint8> data_;
205 :
206 : private:
207 : DISALLOW_COPY_AND_ASSIGN(FlatAsanParameters);
208 : };
209 :
210 : // Default values of HeapProxy parameters
211 : extern const uint32 kDefaultQuarantineSize;
212 : extern const uint32 kDefaultQuarantineBlockSize;
213 : extern const uint32 kDefaultTrailerPaddingSize;
214 : extern const float kDefaultAllocationGuardRate;
215 : // Default values of StackCaptureCache parameters.
216 : extern const uint32 kDefaultReportingPeriod;
217 : extern const uint32 kDefaultMaxNumFrames;
218 : // Default values of StackCapture parameters.
219 : extern const uint32 kDefaultBottomFramesToSkip;
220 : // Default values of AsanRuntime parameters.
221 : extern const bool kDefaultExitOnFailure;
222 : extern const bool kDefaultCheckHeapOnFailure;
223 : extern const bool kDefaultDisableBreakpadReporting;
224 : // Default values of AsanLogger parameters.
225 : extern const bool kDefaultMiniDumpOnFailure;
226 : extern const bool kDefaultLogAsText;
227 : // Default values of ZebraBlockHeap parameters.
228 : extern const uint32 kDefaultZebraBlockHeapSize;
229 : extern const float kDefaultZebraBlockHeapQuarantineRatio;
230 : // Default values of the BlockHeapManager parameters.
231 : extern const bool kDefaultEnableCtMalloc;
232 : extern const bool kDefaultEnableZebraBlockHeap;
233 : extern const bool kDefaultEnableAllocationFilter;
234 : // Default values of LargeBlockHeap parameters.
235 : extern const bool kDefaultEnableLargeBlockHeap;
236 : extern const size_t kDefaultLargeAllocationThreshold;
237 : extern const bool kDefaultEnableRateTargetedHeaps;
238 :
239 : // The name of the environment variable containing the SyzyAsan command-line.
240 : extern const char kSyzyAsanOptionsEnvVar[];
241 :
242 : // String names of HeapProxy parameters.
243 : extern const char kParamQuarantineSize[];
244 : extern const char kParamQuarantineBlockSize[];
245 : extern const char kParamTrailerPaddingSize[];
246 : extern const char kParamAllocationGuardRate[];
247 : // String names of StackCaptureCache parameters.
248 : extern const char kParamReportingPeriod[];
249 : extern const char kParamBottomFramesToSkip[];
250 : // String names of StackCapture parameters.
251 : extern const char kParamMaxNumFrames[];
252 : // String names of AsanRuntime parameters.
253 : extern const char kParamIgnoredStackIds[];
254 : extern const char kParamExitOnFailure[];
255 : extern const char kParamDisableBreakpadReporting[];
256 : // String names of AsanLogger parameters.
257 : extern const char kParamMiniDumpOnFailure[];
258 : extern const char kParamLogAsText[];
259 : // String names of ZebraBlockHeap parameters.
260 : extern const char kParamZebraBlockHeapSize[];
261 : extern const char kParamZebraBlockHeapQuarantineRatio[];
262 : // String names of BlockHeapManager parameters.
263 : extern const char kParamDisableCtMalloc[];
264 : extern const char kParamDisableSizeTargetedHeaps[];
265 : extern const char kParamEnableZebraBlockHeap[];
266 : extern const char kParamEnableAllocationFilter[];
267 : // String names of LargeBlockHeap parameters.
268 : extern const char kParamDisableLargeBlockHeap[];
269 : extern const char kParamLargeAllocationThreshold[];
270 :
271 : // Initializes an AsanParameters struct with default values.
272 : // @param asan_parameters The AsanParameters struct to be initialized.
273 : void SetDefaultAsanParameters(AsanParameters* asan_parameters);
274 :
275 : // Initializes an InflatedAsanParameters from a FlatAsanParameters.
276 : // @param params The POD asan parameters to copy.
277 : // @param inflated_params The inflated parameters to be populated.
278 : bool InflateAsanParameters(const AsanParameters* pod_params,
279 : InflatedAsanParameters* inflated_params);
280 :
281 : // Parses parameters from a string, and updates the provided structure.
282 : // @param param_string the string of parameters to be parsed.
283 : // @param asan_parameters The AsanParameters struct to be updated.
284 : // @returns true on success, false otherwise. Logs verbosely on failure.
285 : bool ParseAsanParameters(const base::StringPiece16& param_string,
286 : InflatedAsanParameters* asan_parameters);
287 :
288 : } // namespace common
289 :
290 : #endif // SYZYGY_COMMON_ASAN_PARAMETERS_H_
|