| Index: syzygy/agent/asan/shadow.cc
|
| diff --git a/syzygy/agent/asan/shadow.cc b/syzygy/agent/asan/shadow.cc
|
| index de8452cc53c35745a564d6997cd3227c68fe609f..0f7fe599370aac2ab9f4d3537e42290fe5e9dfe4 100644
|
| --- a/syzygy/agent/asan/shadow.cc
|
| +++ b/syzygy/agent/asan/shadow.cc
|
| @@ -33,7 +33,7 @@ base::Lock shadow_instance_lock;
|
| // The pointer for the exception handler to know what shadow object is
|
| // currently used. Under shadow_instance_lock.
|
| // TODO(loskutov): eliminate this by enforcing Shadow to be a singleton.
|
| -const Shadow* shadow_instance;
|
| +const Shadow* shadow_instance = nullptr;
|
|
|
| // The exception handler, intended to map the pages for shadow and page_bits
|
| // on demand. When a page fault happens, the operating systems calls
|
| @@ -41,6 +41,7 @@ const Shadow* shadow_instance;
|
| // commited seamlessly for the caller, and then execution continues.
|
| // Otherwise, the OS keeps searching for an appropriate handler.
|
| LONG NTAPI ShadowExceptionHandler(PEXCEPTION_POINTERS exception_pointers) {
|
| + DCHECK_NE(static_cast<const Shadow*>(nullptr), shadow_instance);
|
| // Only handle access violations.
|
| if (exception_pointers->ExceptionRecord->ExceptionCode !=
|
| EXCEPTION_ACCESS_VIOLATION) {
|
| @@ -92,6 +93,16 @@ inline void AddressToPageMask(const void* address,
|
| *mask = 1 << (i % 8);
|
| }
|
|
|
| +// Check if |addr| is in a memory region that has been committed.
|
| +bool AddressIsInCommittedMemory(const void* addr) {
|
| + MEMORY_BASIC_INFORMATION memory_info = {};
|
| + SIZE_T mem_status = ::VirtualQuery(addr, &memory_info, sizeof(memory_info));
|
| + DCHECK_GT(mem_status, 0u);
|
| + if (memory_info.State != MEM_COMMIT)
|
| + return false;
|
| + return true;
|
| +}
|
| +
|
| } // namespace
|
|
|
| Shadow::Shadow() : own_memory_(false), shadow_(nullptr), length_(0) {
|
| @@ -215,7 +226,7 @@ bool Shadow::IsClean() const {
|
| auto ret = ::VirtualQuery(cursor, &info, sizeof(info));
|
| DCHECK_GT(ret, 0u);
|
| next_cursor = static_cast<uint8_t*>(info.BaseAddress) + info.RegionSize;
|
| - if (info.Type == MEM_COMMIT)
|
| + if (info.State == MEM_COMMIT)
|
| break;
|
| cursor = next_cursor;
|
| }
|
| @@ -884,9 +895,13 @@ bool Shadow::ScanLeftForBracketingBlockStart(
|
|
|
| size_t left = cursor;
|
| int nesting_depth = static_cast<int>(initial_nesting_depth);
|
| + if (!AddressIsInCommittedMemory((&shadow_[left])))
|
| + return false;
|
| if (ShadowMarkerHelper::IsBlockEnd(shadow_[left]))
|
| --nesting_depth;
|
| while (true) {
|
| + if (!AddressIsInCommittedMemory((&shadow_[left])))
|
| + return false;
|
| if (ShadowMarkerHelper::IsBlockStart(shadow_[left])) {
|
| if (nesting_depth == 0) {
|
| *location = left;
|
| @@ -1049,6 +1064,9 @@ bool Shadow::BlockInfoFromShadowImpl(
|
| size_t left = reinterpret_cast<uintptr_t>(addr) / kShadowRatio;
|
| size_t right = left;
|
|
|
| + if (!AddressIsInCommittedMemory(&shadow_[left]))
|
| + return false;
|
| +
|
| if (!ScanLeftForBracketingBlockStart(initial_nesting_depth, left, &left))
|
| return false;
|
| if (!ScanRightForBracketingBlockEnd(initial_nesting_depth, right, &right))
|
|
|