Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: syzygy/agent/asan/shadow.h

Issue 2508333002: Remove the is_nested bit from the BlockInfo structure. (Closed)
Patch Set: Address Siggi's comments. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « syzygy/agent/asan/runtime.cc ('k') | syzygy/agent/asan/shadow.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « syzygy/agent/asan/runtime.cc ('k') | syzygy/agent/asan/shadow.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698