OLD | NEW |
1 // Copyright 2012 Google Inc. All Rights Reserved. | 1 // Copyright 2012 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with 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 | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 15 matching lines...) Expand all Loading... |
26 // and end of a block simply by scanning and looking for balanced markers. | 26 // and end of a block simply by scanning and looking for balanced markers. |
27 // - The left and right redzones are uniquely identified by distinct markers. | 27 // - The left and right redzones are uniquely identified by distinct markers. |
28 // - The location of the header and trailer of a block are always at the | 28 // - The location of the header and trailer of a block are always at the |
29 // extremes, thus knowing the locations of the start and end markers | 29 // extremes, thus knowing the locations of the start and end markers |
30 // uniquely identifies their positions. | 30 // uniquely identifies their positions. |
31 // - The left redzone markers uniquely encodes the length of the header padding | 31 // - The left redzone markers uniquely encodes the length of the header padding |
32 // as it must also be a multiple of kShadowRatio in length. | 32 // as it must also be a multiple of kShadowRatio in length. |
33 // - The right redzone implies the length of the body of the allocation and | 33 // - The right redzone implies the length of the body of the allocation and |
34 // the trailer padding modulo kShadowRatio. The remaining bits are encoded | 34 // the trailer padding modulo kShadowRatio. The remaining bits are encoded |
35 // directly in the block start marker. | 35 // directly in the block start marker. |
36 // - Nested blocks and regular blocks use differing block start/end markers. | |
37 // This allows navigation through allocation hierarchies to terminate | |
38 // without necessitating a scan through the entire shadow memory. | |
39 // | 36 // |
40 // A typical block will look something like the following in shadow memory: | 37 // A typical block will look something like the following in shadow memory: |
41 // | 38 // |
42 // 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 39 // 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F |
43 // E7 FA FA FA 00 00 00 00 00 00 FB FB FB FB FB F4 | 40 // E7 FA FA FA 00 00 00 00 00 00 FB FB FB FB FB F4 |
44 // | \______/ \_______________/ \____________/ | | 41 // | \______/ \_______________/ \____________/ | |
45 // | : | : +-- Block end. | 42 // | : | : +-- Block end. |
46 // | : | + - - - - - Right redzone. | 43 // | : | + - - - - - Right redzone. |
47 // | : +--------------------------- Body of allocation. | 44 // | : +--------------------------- Body of allocation. |
48 // | +- - - - - - - - - - - - - - - - - - - - - Left redzone. | 45 // | +- - - - - - - - - - - - - - - - - - - - - Left redzone. |
49 // +----------------------------------------------- Block start. | 46 // +----------------------------------------------- Block start. |
50 // | 47 // |
51 // - Both the end marker and the start marker indicate the block | |
52 // is not nested. Together they indicate the total length of the | |
53 // block is 128 bytes. | |
54 // - The start marker indicates that the body length is 7 % 8. | 48 // - The start marker indicates that the body length is 7 % 8. |
55 // - The header padding indicates that the 16 byte header is followed | 49 // - The header padding indicates that the 16 byte header is followed |
56 // by a further 16 bytes of padding. | 50 // by a further 16 bytes of padding. |
57 // - The 6 body markers indicate an allocation size of 41..48 bytes. | 51 // - The 6 body markers indicate an allocation size of 41..48 bytes. |
58 // Combined with the start marker bits the allocation size can be | 52 // Combined with the start marker bits the allocation size can be |
59 // inferred as being 47 bytes, with the last byte contributing to | 53 // inferred as being 47 bytes, with the last byte contributing to |
60 // the trailer padding. | 54 // the trailer padding. |
61 // - The 5 right redzone markers indicate that the 20 byte trailer is | 55 // - The 5 right redzone markers indicate that the 20 byte trailer is |
62 // preceded by at least 28 trailer padding bytes. The additional | 56 // preceded by at least 28 trailer padding bytes. The additional |
63 // padding from the body means that there are in total 29 trailer | 57 // padding from the body means that there are in total 29 trailer |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 // @param size The size of the memory to poison. | 127 // @param size The size of the memory to poison. |
134 // @param shadow_val The poison marker value. | 128 // @param shadow_val The poison marker value. |
135 void Poison(const void* addr, size_t size, ShadowMarker shadow_val); | 129 void Poison(const void* addr, size_t size, ShadowMarker shadow_val); |
136 | 130 |
137 // Un-poisons @p size bytes starting at @p addr. | 131 // Un-poisons @p size bytes starting at @p addr. |
138 // @pre addr mod 8 == 0 && size mod 8 == 0. | 132 // @pre addr mod 8 == 0 && size mod 8 == 0. |
139 // @param addr The starting address. | 133 // @param addr The starting address. |
140 // @param size The size of the memory to unpoison. | 134 // @param size The size of the memory to unpoison. |
141 void Unpoison(const void* addr, size_t size); | 135 void Unpoison(const void* addr, size_t size); |
142 | 136 |
143 // Mark @p size bytes starting at @p addr as freed. This will preserve | 137 // Mark @p size bytes starting at @p addr as freed. |
144 // nested block headers/trailers/redzones, but mark all contents as freed. | |
145 // It is expected that the states of all nested blocks have already been | |
146 // marked as freed prior to possibly freeing the parent block. | |
147 // @param addr The starting address. | 138 // @param addr The starting address. |
148 // @param size The size of the memory to mark as freed. | 139 // @param size The size of the memory to mark as freed. |
149 void MarkAsFreed(const void* addr, size_t size); | 140 void MarkAsFreed(const void* addr, size_t size); |
150 | 141 |
151 // Returns true iff the byte at @p addr is not poisoned. | 142 // Returns true iff the byte at @p addr is not poisoned. |
152 // @param addr The address that we want to check. | 143 // @param addr The address that we want to check. |
153 // @returns true if this address is accessible, false otherwise. | 144 // @returns true if this address is accessible, false otherwise. |
154 bool IsAccessible(const void* addr) const; | 145 bool IsAccessible(const void* addr) const; |
155 | 146 |
156 // Returns true iff all the bytes from @p addr to @p addrs + size - 1 are | 147 // Returns true iff all the bytes from @p addr to @p addrs + size - 1 are |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 template<typename type> | 212 template<typename type> |
222 bool GetNullTerminatedArraySize(const void* addr, | 213 bool GetNullTerminatedArraySize(const void* addr, |
223 size_t max_size, | 214 size_t max_size, |
224 size_t* size) const; | 215 size_t* size) const; |
225 | 216 |
226 // Calculate the allocation size of a block by using the shadow memory. | 217 // Calculate the allocation size of a block by using the shadow memory. |
227 // @param mem A pointer inside the memory block for which we want to calculate | 218 // @param mem A pointer inside the memory block for which we want to calculate |
228 // the underlying allocation size. | 219 // the underlying allocation size. |
229 // @returns The underlying allocation size or 0 if it can't find a valid block | 220 // @returns The underlying allocation size or 0 if it can't find a valid block |
230 // at this address. | 221 // at this address. |
231 // @note This function doesn't work for nested blocks. | |
232 // TODO(sebmarchand): Add support for nested blocks. | |
233 size_t GetAllocSize(const uint8_t* mem) const; | 222 size_t GetAllocSize(const uint8_t* mem) const; |
234 | 223 |
235 // Poisons memory for an freshly allocated block. | 224 // Poisons memory for an freshly allocated block. |
236 // @param info Info about the block layout. | 225 // @param info Info about the block layout. |
237 // @note The block must be readable. | 226 // @note The block must be readable. |
238 void PoisonAllocatedBlock(const BlockInfo& info); | 227 void PoisonAllocatedBlock(const BlockInfo& info); |
239 | 228 |
240 // Determines if the block is nested simply by inspecting shadow memory. | |
241 bool BlockIsNested(const BlockInfo& info) const; | |
242 | |
243 // Inspects shadow memory to determine the layout of a block in memory. | 229 // Inspects shadow memory to determine the layout of a block in memory. |
244 // Does not rely on any block content itself, strictly reading from the | 230 // Does not rely on any block content itself, strictly reading from the |
245 // shadow memory. In the case of nested blocks this will always return | 231 // shadow memory. |
246 // the innermost containing block. | |
247 // @param addr An address in the block to be inspected. | 232 // @param addr An address in the block to be inspected. |
248 // @param info The block information to be populated. | 233 // @param info The block information to be populated. |
249 // @returns true on success, false otherwise. | 234 // @returns true on success, false otherwise. |
250 bool BlockInfoFromShadow(const void* addr, CompactBlockInfo* info) const; | 235 bool BlockInfoFromShadow(const void* addr, CompactBlockInfo* info) const; |
251 bool BlockInfoFromShadow(const void* addr, BlockInfo* info) const; | 236 bool BlockInfoFromShadow(const void* addr, BlockInfo* info) const; |
252 | 237 |
253 // Inspects shadow memory to find the block containing a nested block. | |
254 // @param nested Information about the nested block. | |
255 // @param info The block information to be populated. | |
256 // @returns true on success, false otherwise. | |
257 bool ParentBlockInfoFromShadow( | |
258 const BlockInfo& nested, BlockInfo* info) const; | |
259 | |
260 // Checks if the address @p addr corresponds to the beginning of a block's | 238 // Checks if the address @p addr corresponds to the beginning of a block's |
261 // body, i.e. if it's preceded by a left redzone. | 239 // body, i.e. if it's preceded by a left redzone. |
262 // @param addr The address that we want to check. | 240 // @param addr The address that we want to check. |
263 // @returns true if the address corresponds to the beginning of a block's | 241 // @returns true if the address corresponds to the beginning of a block's |
264 // body, false otherwise. | 242 // body, false otherwise. |
265 bool IsBeginningOfBlockBody(const void* addr) const; | 243 bool IsBeginningOfBlockBody(const void* addr) const; |
266 | 244 |
267 // Queries a given page's protection status. | 245 // Queries a given page's protection status. |
268 // @param addr An address in the page to be queried. | 246 // @param addr An address in the page to be queried. |
269 // @returns true if the address containing the given page is protected, | 247 // @returns true if the address containing the given page is protected, |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 // shadow_[index] to shadow_[index + 7], prefixed by @p prefix. If the index | 323 // shadow_[index] to shadow_[index + 7], prefixed by @p prefix. If the index |
346 // @p bug_index is present in this range then its value will be surrounded by | 324 // @p bug_index is present in this range then its value will be surrounded by |
347 // brackets. | 325 // brackets. |
348 void AppendShadowByteText(const char *prefix, | 326 void AppendShadowByteText(const char *prefix, |
349 uintptr_t index, | 327 uintptr_t index, |
350 std::string* output, | 328 std::string* output, |
351 size_t bug_index) const; | 329 size_t bug_index) const; |
352 | 330 |
353 // Scans to the left of the provided cursor, looking for the presence of a | 331 // Scans to the left of the provided cursor, looking for the presence of a |
354 // block start marker that brackets the cursor. | 332 // block start marker that brackets the cursor. |
355 // @param initial_nesting_depth If zero then this will return the inner | |
356 // most block containing the cursor. If 1 then this will find the start of | |
357 // the block containing that block, and so on. | |
358 // @param cursor The position in shadow memory from which to start the scan. | 333 // @param cursor The position in shadow memory from which to start the scan. |
359 // @param location Will be set to the location of the start marker, if found. | 334 // @param location Will be set to the location of the start marker, if found. |
360 // @returns true on success, false otherwise. | 335 // @returns true on success, false otherwise. |
361 bool ScanLeftForBracketingBlockStart( | 336 bool ScanLeftForBracketingBlockStart(size_t cursor, size_t* location) const; |
362 size_t initial_nesting_depth, size_t cursor, size_t* location) const; | |
363 | 337 |
364 // Scans to the right of the provided cursor, looking for the presence of a | 338 // Scans to the right of the provided cursor, looking for the presence of a |
365 // block end marker that brackets the cursor. | 339 // block end marker that brackets the cursor. |
366 // @param initial_nesting_depth If zero then this will return the inner | |
367 // most block containing the cursor. If 1 then this will find the end of | |
368 // the block containing that block, and so on. | |
369 // @param cursor The position in shadow memory from which to start the scan. | 340 // @param cursor The position in shadow memory from which to start the scan. |
370 // @param location Will be set to the location of the end marker, if found. | 341 // @param location Will be set to the location of the end marker, if found. |
371 // @returns true on success, false otherwise. | 342 // @returns true on success, false otherwise. |
372 bool ScanRightForBracketingBlockEnd( | 343 bool ScanRightForBracketingBlockEnd(size_t cursor, size_t* location) const; |
373 size_t initial_nesting_depth, size_t cursor, size_t* location) const; | |
374 | 344 |
375 // Inspects shadow memory to determine the layout of a block in memory. | 345 // Inspects shadow memory to determine the layout of a block in memory. |
376 // @param initial_nesting_depth If zero then this will return the inner | |
377 // most block containing the cursor. If 1 then this will find the end of | |
378 // the block containing that block, and so on. | |
379 // @param addr An address in the block to be inspected. | 346 // @param addr An address in the block to be inspected. |
380 // @param info The block information to be populated. | 347 // @param info The block information to be populated. |
381 // @returns true on success, false otherwise. | 348 // @returns true on success, false otherwise. |
382 bool BlockInfoFromShadowImpl( | 349 bool BlockInfoFromShadowImpl( |
383 size_t initial_nesting_depth, | |
384 const void* addr, | 350 const void* addr, |
385 CompactBlockInfo* info) const; | 351 CompactBlockInfo* info) const; |
386 | 352 |
387 // If this is true then this shadow object owns the memory. | 353 // If this is true then this shadow object owns the memory. |
388 bool own_memory_; | 354 bool own_memory_; |
389 | 355 |
390 // The actual shadow that is being referred to. In case of large | 356 // The actual shadow that is being referred to. In case of large |
391 // address spaces it's stored as a sparse array | 357 // address spaces it's stored as a sparse array |
392 // (see ShadowExceptionHandler in the .cc file). | 358 // (see ShadowExceptionHandler in the .cc file). |
393 uint8_t* shadow_; | 359 uint8_t* shadow_; |
(...skipping 18 matching lines...) Expand all Loading... |
412 HANDLE exception_handler_; | 378 HANDLE exception_handler_; |
413 #endif | 379 #endif |
414 }; | 380 }; |
415 | 381 |
416 // A helper class to walk over the blocks contained in a given memory region. | 382 // A helper class to walk over the blocks contained in a given memory region. |
417 // This uses only the metadata present in the shadow to identify the blocks. | 383 // This uses only the metadata present in the shadow to identify the blocks. |
418 class ShadowWalker { | 384 class ShadowWalker { |
419 public: | 385 public: |
420 // Constructor. | 386 // Constructor. |
421 // @param shadow The shadow memory object to walk. | 387 // @param shadow The shadow memory object to walk. |
422 // @param recursive If true then this will recursively descend into nested | |
423 // blocks. Otherwise it will only return the outermost blocks in the | |
424 // provided region. | |
425 // @param lower_bound The lower bound of the region that this walker should | 388 // @param lower_bound The lower bound of the region that this walker should |
426 // cover in the actual memory. | 389 // cover in the actual memory. |
427 // @param upper_bound The upper bound of the region that this walker should | 390 // @param upper_bound The upper bound of the region that this walker should |
428 // cover in the actual memory. This can overflow to 0 to indicate walking | 391 // cover in the actual memory. This can overflow to 0 to indicate walking |
429 // all of memory. | 392 // all of memory. |
430 ShadowWalker(const Shadow* shadow, | 393 ShadowWalker(const Shadow* shadow, |
431 bool recursive, | |
432 const void* lower_bound, | 394 const void* lower_bound, |
433 const void* upper_bound); | 395 const void* upper_bound); |
434 | 396 |
435 // Return the next block in this memory region. | 397 // Return the next block in this memory region. |
436 // @param info The block information to be populated. | 398 // @param info The block information to be populated. |
437 // @return true if a block was found, false otherwise. | 399 // @return true if a block was found, false otherwise. |
438 bool Next(BlockInfo* info); | 400 bool Next(BlockInfo* info); |
439 | 401 |
440 // Reset the walker to its initial state. | 402 // Reset the walker to its initial state. |
441 void Reset(); | 403 void Reset(); |
442 | 404 |
443 // @returns the nesting depth of the last returned block. If no blocks have | |
444 // been walked then this returns -1. | |
445 int nesting_depth() const { return nesting_depth_; } | |
446 | |
447 private: | 405 private: |
448 // The shadow memory being walked. | 406 // The shadow memory being walked. |
449 const Shadow* shadow_; | 407 const Shadow* shadow_; |
450 | 408 |
451 // Indicates whether or not the walker will descend recursively into nested | |
452 // blocks. | |
453 bool recursive_; | |
454 | |
455 // The bounds of the memory region for this walker, expressed as pointers in | 409 // The bounds of the memory region for this walker, expressed as pointers in |
456 // the shadow memory. This allows walking to occur without worrying about | 410 // the shadow memory. This allows walking to occur without worrying about |
457 // overflow. | 411 // overflow. |
458 size_t lower_index_; | 412 size_t lower_index_; |
459 size_t upper_index_; | 413 size_t upper_index_; |
460 | 414 |
461 // The shadow cursor. | 415 // The shadow cursor. |
462 const uint8_t* shadow_cursor_; | 416 const uint8_t* shadow_cursor_; |
463 | 417 |
464 // The current nesting depth. Starts at -1. | |
465 int nesting_depth_; | |
466 | |
467 DISALLOW_COPY_AND_ASSIGN(ShadowWalker); | 418 DISALLOW_COPY_AND_ASSIGN(ShadowWalker); |
468 }; | 419 }; |
469 | 420 |
470 // The static shadow memory that is referred to by the memory interceptors. | 421 // The static shadow memory that is referred to by the memory interceptors. |
471 // These are provided by one of 'dummy_shadow.cc' or 'static_shadow.cc'. | 422 // These are provided by one of 'dummy_shadow.cc' or 'static_shadow.cc'. |
472 extern "C" { | 423 extern "C" { |
473 extern const size_t asan_memory_interceptors_shadow_memory_size; | 424 extern const size_t asan_memory_interceptors_shadow_memory_size; |
474 extern uint8_t asan_memory_interceptors_shadow_memory[]; | 425 extern uint8_t asan_memory_interceptors_shadow_memory[]; |
475 } | 426 } |
476 | 427 |
477 // Bring in the implementation of the templated functions. | 428 // Bring in the implementation of the templated functions. |
478 #include "syzygy/agent/asan/shadow_impl.h" | 429 #include "syzygy/agent/asan/shadow_impl.h" |
479 | 430 |
480 } // namespace asan | 431 } // namespace asan |
481 } // namespace agent | 432 } // namespace agent |
482 | 433 |
483 #endif // SYZYGY_AGENT_ASAN_SHADOW_H_ | 434 #endif // SYZYGY_AGENT_ASAN_SHADOW_H_ |
OLD | NEW |