From 2e084370ab67e0ed38d7d7b28cdeb3855a0a12fc Mon Sep 17 00:00:00 2001 From: Chuck Ries Date: Mon, 26 Nov 2018 22:06:34 -0800 Subject: [PATCH] Fix a use after free for Managed Data BP (dotnet/coreclr#21205) ShimProxyCallback::DataBreakpoint::DataBreakpointEvent was holding onto a bare BYTE* for the CONTEXT rather than copying the buffer and taking ownership. Due to lifetime, this resulted in a use after free. Apparently in retail code we got lucky and this worked enough of the time that we never noticed it. Commit migrated from https://github.com/dotnet/coreclr/commit/870267fac0b16ac246d6ba01f49ba4c6acd2319c --- src/coreclr/src/debug/di/shimcallback.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/coreclr/src/debug/di/shimcallback.cpp b/src/coreclr/src/debug/di/shimcallback.cpp index 84ee345..e987f9b 100644 --- a/src/coreclr/src/debug/di/shimcallback.cpp +++ b/src/coreclr/src/debug/di/shimcallback.cpp @@ -1392,7 +1392,7 @@ HRESULT ShimProxyCallback::DataBreakpoint(ICorDebugProcess* pProcess, ICorDebugT // callbacks parameters. These are strong references RSExtSmartPtr m_pProcess; RSExtSmartPtr m_pThread; - BYTE* m_pContext; + CONTEXT m_context; ULONG32 m_contextSize; public: @@ -1402,13 +1402,15 @@ HRESULT ShimProxyCallback::DataBreakpoint(ICorDebugProcess* pProcess, ICorDebugT { this->m_pProcess.Assign(pProcess); this->m_pThread.Assign(pThread); - this->m_pContext = pContext; - this->m_contextSize = contextSize; + + _ASSERTE(contextSize == sizeof(CONTEXT)); + this->m_contextSize = min(contextSize, sizeof(CONTEXT)); + memcpy(&(this->m_context), pContext, this->m_contextSize); } HRESULT Dispatch(DispatchArgs args) { - return args.GetCallback4()->DataBreakpoint(m_pProcess, m_pThread, m_pContext, m_contextSize); + return args.GetCallback4()->DataBreakpoint(m_pProcess, m_pThread, reinterpret_cast(&m_context), m_contextSize); } }; // end class AfterGarbageCollectionEvent -- 2.7.4