From 4a268f7141f7f2528a8f1c5437837046bd21664c Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Tue, 29 Mar 2016 18:06:25 -0700 Subject: 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. --- src/debug/shared/dbgtransportsession.cpp | 42 +++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) (limited to 'src/debug') 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 -- cgit v1.2.3