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

Unified Diff: syzygy/agent/asan/shadow.cc

Issue 2363733003: Make syzyasan_rtl compile in 64 bit (Closed)
Patch Set: Bug fixes Created 4 years, 2 months 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 side-by-side diff with in-line comments
Download patch
Index: syzygy/agent/asan/shadow.cc
diff --git a/syzygy/agent/asan/shadow.cc b/syzygy/agent/asan/shadow.cc
index b397d5db0dd0fc6b70da2c376a536221da733d4f..35a1dcee4c2db710b5c19cdfd611a0bea5d67e2c 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) {
@@ -76,6 +77,16 @@ LONG NTAPI ShadowExceptionHandler(PEXCEPTION_POINTERS exception_pointers) {
? EXCEPTION_CONTINUE_EXECUTION
: EXCEPTION_CONTINUE_SEARCH;
}
+
+// 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;
+}
#endif // defined _WIN64
static const size_t kPageSize = GetPageSize();
@@ -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;
}
@@ -284,7 +295,7 @@ void Shadow::Init(bool own_memory, void* shadow, size_t length) {
shadow_instance = this;
}
exception_handler_ =
- AddVectoredExceptionHandler(TRUE, ShadowExceptionHandler);
+ ::AddVectoredExceptionHandler(TRUE, ShadowExceptionHandler);
#endif
// Handle the case of a failed allocation.
@@ -884,9 +895,22 @@ bool Shadow::ScanLeftForBracketingBlockStart(
size_t left = cursor;
int nesting_depth = static_cast<int>(initial_nesting_depth);
+#ifdef _WIN64
+ if (!AddressIsInCommittedMemory((&shadow_[left])))
chrisha 2016/10/13 20:22:49 This is going to cost a VirtualQuery per value of
Sébastien Marchand 2016/10/13 21:05:45 No, in the loop I'm evaluating the following condi
Sébastien Marchand 2016/10/14 19:04:14 Ha, didn't realized that VirtualQuery return the i
+ return false;
+ uint8_t* page_begin = ::common::AlignDown(&shadow_[left], kPageSize);
+#endif
if (ShadowMarkerHelper::IsBlockEnd(shadow_[left]))
--nesting_depth;
while (true) {
+#ifdef _WIN64
+ if (&shadow_[left] < page_begin &&
+ !AddressIsInCommittedMemory((&shadow_[left]))) {
+ return false;
+ } else {
+ page_begin = ::common::AlignDown(&shadow_[left], kPageSize);
+ }
+#endif
if (ShadowMarkerHelper::IsBlockStart(shadow_[left])) {
if (nesting_depth == 0) {
*location = left;
@@ -1049,6 +1073,11 @@ bool Shadow::BlockInfoFromShadowImpl(
size_t left = reinterpret_cast<uintptr_t>(addr) / kShadowRatio;
size_t right = left;
+#ifdef _WIN64
+ if (!AddressIsInCommittedMemory((&shadow_[left])))
+ return false;
+#endif
+
if (!ScanLeftForBracketingBlockStart(initial_nesting_depth, left, &left))
return false;
if (!ScanRightForBracketingBlockEnd(initial_nesting_depth, right, &right))
@@ -1141,7 +1170,7 @@ bool ShadowWalker::Next(BlockInfo* info) {
return false;
// Step to the beginning of the next region and try again.
- shadow_cursor_ = start_of_region;
+ shadow_cursor_ = end_of_region;
chrisha 2016/10/13 20:22:49 Oops! My bad. New unittest for this?
Sébastien Marchand 2016/10/14 19:04:14 Addressing this in https://codereview.chromium.org
continue;
}

Powered by Google App Engine
This is Rietveld 408576698