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 = 20;
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 : // Runtime: 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 : // Runtime: If true, we should check if the heap is corrupt on
96 : // failure.
97 : unsigned check_heap_on_failure : 1;
98 : // Runtime: If true, we won't try to report the crashes via breakpad
99 : // on failure.
100 : unsigned disable_breakpad_reporting : 1;
101 : // DEPRECATED: BlockHeapManager: Indicates if CtMalloc should be used to
102 : // serve the user's allocations.
103 : unsigned deprecated_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 : // Runtime: Indicates if the feature randomization is enabled.
114 : unsigned feature_randomization : 1;
115 : // BlockHeapManager: Indicates if we shouldn't report a crash for the same
116 : // corrupt block twice.
117 : unsigned prevent_duplicate_corruption_crashes : 1;
118 : // Runtime: Indicates if the invalid accesses should be reported.
119 : unsigned report_invalid_accesses : 1;
120 :
121 : // Add new flags here!
122 :
123 : unsigned reserved1 : kAsanParametersReserved1Bits;
124 : };
125 : };
126 :
127 : // HeapProxy: The rate at which allocations are instrumented with header and
128 : // footer guards. This happens for each allocation via a runtime cointoss.
129 : // A value in the range 0.0 to 1.0, inclusive.
130 : float allocation_guard_rate;
131 :
132 : // ZebraBlockHeap: The size of the ZebraBlockHeap.
133 : uint32 zebra_block_heap_size;
134 :
135 : // ZebraBlockHeap: The ratio of the memory used for the quarantine.
136 : float zebra_block_heap_quarantine_ratio;
137 :
138 : // LargeBlockHeap: The minimum size of allocations that will be passed to
139 : // the large block heap.
140 : uint32 large_allocation_threshold;
141 :
142 : // The rate at which blocks will have their contents flood-filled upon entry
143 : // to the quarantine. When this occurs it encourages non-instrumented read-
144 : // after-frees to fail, and it also makes non-instrumented write-after-frees
145 : // plainly visible. A value in the range 0.0 to 1.0, inclusive. A value of
146 : // 0.0 corresponds to this being disabled entirely.
147 : float quarantine_flood_fill_rate;
148 :
149 : // Add new parameters here!
150 :
151 : // When laid out in memory the ignored_stack_ids are present here as a NULL
152 : // terminated vector.
153 : };
154 : COMPILE_ASSERT_IS_POD_OF_SIZE(AsanParameters, 60);
155 :
156 : // The current version of the Asan parameters structure. This must be updated
157 : // if any changes are made to the above structure! This is defined in the header
158 : // file to allow compile time assertions against this version number.
159 : const uint32 kAsanParametersVersion = 14;
160 :
161 : // If the number of free bits in the parameters struct changes, then the
162 : // version has to change as well. This is simply here to make sure that
163 : // everything changes in lockstep.
164 : static_assert(kAsanParametersReserved1Bits == 20 &&
165 : kAsanParametersVersion == 14,
166 : "Version must change if reserved bits changes.");
167 :
168 : // The name of the section that will be injected into an instrumented image,
169 : // and contain the AsanParameters structure. Asan can't use your typical entry
170 : // hook because the entry hook is called after the RTL has initialized itself.
171 : // Instead the RTL scans through libraries in its memory and looks for a
172 : // telltale section containing parameters. The first set of parameters it
173 : // encounters are used. After that it may override some of them with environment
174 : // variable configuration.
175 : extern const char kAsanParametersSectionName[];
176 : extern const uint32 kAsanParametersSectionCharacteristics;
177 :
178 : #pragma pack(pop)
179 :
180 : // An inflated version of AsanParameters for dynamically parsing into. This can
181 : // then be flattened into a FlatAsanParameters object. In this representation
182 : // variable sized fields of the flat representation are backed by STL
183 : // containers.
184 : struct InflatedAsanParameters : public AsanParameters {
185 : InflatedAsanParameters();
186 :
187 : std::set<AsanStackId> ignored_stack_ids_set;
188 :
189 : protected:
190 : // Deprecate use of this field in favour of the STL set version.
191 : using AsanParameters::ignored_stack_ids;
192 : };
193 :
194 : // A flat version of AsanParameters, backed by a vector for housing the variable
195 : // sized data. This is a read-only structure.
196 : class FlatAsanParameters {
197 : public:
198 : // Constructs a flat parameter representation from the given set of parsed
199 : // parameters.
200 : explicit FlatAsanParameters(const InflatedAsanParameters& asan_parameters);
201 :
202 : // @name Accessors.
203 : // @{
204 E : const std::vector<uint8>& data() const { return data_; }
205 E : const AsanParameters& params() const {
206 E : return *reinterpret_cast<const AsanParameters*>(data_.data());
207 E : }
208 E : const AsanParameters* operator->() const {
209 E : return reinterpret_cast<const AsanParameters*>(data_.data());
210 E : }
211 : // @}
212 :
213 : protected:
214 : // The data backing the Asan parameters.
215 : std::vector<uint8> data_;
216 :
217 : private:
218 : DISALLOW_COPY_AND_ASSIGN(FlatAsanParameters);
219 : };
220 :
221 : // Default values of HeapProxy parameters
222 : extern const uint32 kDefaultQuarantineSize;
223 : extern const uint32 kDefaultQuarantineBlockSize;
224 : extern const uint32 kDefaultTrailerPaddingSize;
225 : extern const float kDefaultAllocationGuardRate;
226 : // Default values of StackCaptureCache parameters.
227 : extern const uint32 kDefaultReportingPeriod;
228 : extern const uint32 kDefaultMaxNumFrames;
229 : // Default values of StackCapture parameters.
230 : extern const uint32 kDefaultBottomFramesToSkip;
231 : // Default values of AsanRuntime parameters.
232 : extern const bool kDefaultExitOnFailure;
233 : extern const bool kDefaultCheckHeapOnFailure;
234 : extern const bool kDefaultDisableBreakpadReporting;
235 : extern const bool kDefaultFeatureRandomization;
236 : extern const bool kDefaultReportInvalidAccesses;
237 : // Default values of AsanLogger parameters.
238 : extern const bool kDefaultMiniDumpOnFailure;
239 : extern const bool kDefaultLogAsText;
240 : // Default values of ZebraBlockHeap parameters.
241 : extern const uint32 kDefaultZebraBlockHeapSize;
242 : extern const float kDefaultZebraBlockHeapQuarantineRatio;
243 : // Default values of the BlockHeapManager parameters.
244 : extern const bool kDefaultEnableZebraBlockHeap;
245 : extern const bool kDefaultEnableAllocationFilter;
246 : extern const float kDefaultQuarantineFloodFillRate;
247 : extern const bool kDefaultPreventDuplicateCorruptionCrashes;
248 : // Default values of LargeBlockHeap parameters.
249 : extern const bool kDefaultEnableLargeBlockHeap;
250 : extern const size_t kDefaultLargeAllocationThreshold;
251 : extern const bool kDefaultEnableRateTargetedHeaps;
252 :
253 : // The name of the environment variable containing the SyzyAsan command-line.
254 : extern const char kSyzyAsanOptionsEnvVar[];
255 :
256 : // String names of HeapProxy parameters.
257 : extern const char kParamQuarantineSize[];
258 : extern const char kParamQuarantineBlockSize[];
259 : extern const char kParamTrailerPaddingSize[];
260 : extern const char kParamAllocationGuardRate[];
261 : // String names of StackCaptureCache parameters.
262 : extern const char kParamReportingPeriod[];
263 : extern const char kParamBottomFramesToSkip[];
264 : // String names of StackCapture parameters.
265 : extern const char kParamMaxNumFrames[];
266 : // String names of AsanRuntime parameters.
267 : extern const char kParamIgnoredStackIds[];
268 : extern const char kParamExitOnFailure[];
269 : extern const char kParamDisableBreakpadReporting[];
270 : extern const char kParamFeatureRandomization[];
271 : extern const char kParamReportInvalidAccesses[];
272 : // String names of AsanLogger parameters.
273 : extern const char kParamMiniDumpOnFailure[];
274 : extern const char kParamLogAsText[];
275 : // String names of ZebraBlockHeap parameters.
276 : extern const char kParamZebraBlockHeapSize[];
277 : extern const char kParamZebraBlockHeapQuarantineRatio[];
278 : // String names of BlockHeapManager parameters.
279 : extern const char kParamDisableSizeTargetedHeaps[];
280 : extern const char kParamEnableZebraBlockHeap[];
281 : extern const char kParamEnableAllocationFilter[];
282 : extern const char kParamQuarantineFloodFillRate[];
283 : extern const char kParamPreventDuplicateCorruptionCrashes[];
284 : // String names of LargeBlockHeap parameters.
285 : extern const char kParamDisableLargeBlockHeap[];
286 : extern const char kParamLargeAllocationThreshold[];
287 :
288 : // Initializes an AsanParameters struct with default values.
289 : // @param asan_parameters The AsanParameters struct to be initialized.
290 : void SetDefaultAsanParameters(AsanParameters* asan_parameters);
291 :
292 : // Initializes an InflatedAsanParameters from a FlatAsanParameters.
293 : // @param params The POD asan parameters to copy.
294 : // @param inflated_params The inflated parameters to be populated.
295 : bool InflateAsanParameters(const AsanParameters* pod_params,
296 : InflatedAsanParameters* inflated_params);
297 :
298 : // Parses parameters from a string, and updates the provided structure.
299 : // @param param_string the string of parameters to be parsed.
300 : // @param asan_parameters The AsanParameters struct to be updated.
301 : // @returns true on success, false otherwise. Logs verbosely on failure.
302 : bool ParseAsanParameters(const base::StringPiece16& param_string,
303 : InflatedAsanParameters* asan_parameters);
304 :
305 : } // namespace common
306 :
307 : #endif // SYZYGY_COMMON_ASAN_PARAMETERS_H_
|