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