diff options
author | Mike McLaughlin <mikem@microsoft.com> | 2016-03-29 18:06:25 -0700 |
---|---|---|
committer | Mike McLaughlin <mikem@microsoft.com> | 2016-03-29 18:09:08 -0700 |
commit | 4a268f7141f7f2528a8f1c5437837046bd21664c (patch) | |
tree | 2b7d668349a5bdbb0104a0f15b0c7dfc35cbe131 /src/debug | |
parent | f0638c5b6aecec87b3a8aac8c808152c86febe9d (diff) | |
download | coreclr-4a268f7141f7f2528a8f1c5437837046bd21664c.tar.gz coreclr-4a268f7141f7f2528a8f1c5437837046bd21664c.tar.bz2 coreclr-4a268f7141f7f2528a8f1c5437837046bd21664c.zip |
Fix ReadMemory AV.
Use simple probing to validate read/write memory with a try/catch and explicit h/w exception holder.
Put probing in separate noinline and optnone function for optimized builds.
Fix assert in exception code mapping in context.cpp by handling SIGSEGV subcode SI_KERNEL.
Diffstat (limited to 'src/debug')
-rw-r--r-- | src/debug/shared/dbgtransportsession.cpp | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/src/debug/shared/dbgtransportsession.cpp b/src/debug/shared/dbgtransportsession.cpp index b6efe7cc2d..e3827735d5 100644 --- a/src/debug/shared/dbgtransportsession.cpp +++ b/src/debug/shared/dbgtransportsession.cpp @@ -1126,6 +1126,34 @@ DbgTransportSession::Message * DbgTransportSession::RemoveMessageFromSendQueue(D #endif #ifndef RIGHT_SIDE_COMPILE + +#ifdef FEATURE_PAL +__attribute__((noinline)) +__attribute__((optnone)) +static void +ProbeMemory(__in_ecount(cbBuffer) volatile PBYTE pbBuffer, DWORD cbBuffer, bool fWriteAccess) +{ + // Need an throw in this function to fool the C++ runtime into handling the + // possible h/w exception below. + if (pbBuffer == NULL) + { + throw PAL_SEHException(); + } + + // Simple one byte at a time probing + while (cbBuffer > 0) + { + volatile BYTE read = *pbBuffer; + if (fWriteAccess) + { + *pbBuffer = read; + } + ++pbBuffer; + --cbBuffer; + } +} +#endif // FEATURE_PAL + // Check read and optionally write memory access to the specified range of bytes. Used to check // ReadProcessMemory and WriteProcessMemory requests. HRESULT DbgTransportSession::CheckBufferAccess(__in_ecount(cbBuffer) PBYTE pbBuffer, DWORD cbBuffer, bool fWriteAccess) @@ -1138,7 +1166,6 @@ HRESULT DbgTransportSession::CheckBufferAccess(__in_ecount(cbBuffer) PBYTE pbBuf // VirtualQuery doesn't know much about memory allocated outside of PAL's VirtualAlloc // that's why on Unix we can't rely on in to detect invalid memory reads - // TODO: We need to find and use appropriate memory map API on other operating systems. #ifndef FEATURE_PAL do { @@ -1179,11 +1206,24 @@ HRESULT DbgTransportSession::CheckBufferAccess(__in_ecount(cbBuffer) PBYTE pbBuf } } while (cbBuffer > 0); +#else + try + { + // Need to explicit h/w exception holder so to catch them in ProbeMemory + CatchHardwareExceptionHolder __catchHardwareException; + + ProbeMemory(pbBuffer, cbBuffer, fWriteAccess); + } + catch(...) + { + return HRESULT_FROM_WIN32(ERROR_INVALID_ADDRESS); + } #endif // The specified region has passed all of our checks. return S_OK; } + #endif // !RIGHT_SIDE_COMPILE // Initialize all session state to correct starting values. Used during Init() and on the LS when we |