From 8ea2fbd76ad9a893c66db2fbc79bf2f9047b4f4b Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Thu, 12 Apr 2018 13:55:15 -0700 Subject: Protect SuperPMI from crashes calling jitStartup When we call jitStartup, we pass a JitHost interface that the JIT calls to query for data. These queries look up in the recorded MCH data, and could fail (and throw an exception) if data is missing, which it can be for running non-matching altjit against a collection. Protect these calls with exception handling. --- src/ToolBox/superpmi/superpmi/jitinstance.cpp | 69 ++++++++++++++++++++++----- src/ToolBox/superpmi/superpmi/jitinstance.h | 2 + 2 files changed, 60 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/ToolBox/superpmi/superpmi/jitinstance.cpp b/src/ToolBox/superpmi/superpmi/jitinstance.cpp index 52f2b90d22..ee589f12ea 100644 --- a/src/ToolBox/superpmi/superpmi/jitinstance.cpp +++ b/src/ToolBox/superpmi/superpmi/jitinstance.cpp @@ -190,7 +190,11 @@ HRESULT JitInstance::StartUp(char* PathToJit, { mc = firstContext; jitHost = new JitHost(*this); - pnjitStartup(jitHost); + if (!callJitStartup(jitHost)) + { + LogError("jitStartup failed"); + return -1; + } } pJitInstance = pngetJit(); @@ -256,7 +260,11 @@ bool JitInstance::reLoad(MethodContext* firstContext) { mc = firstContext; jitHost = new JitHost(*this); - pnjitStartup(jitHost); + if (!callJitStartup(jitHost)) + { + LogError("jitStartup failed"); + return false; + } } pJitInstance = pngetJit(); @@ -465,17 +473,56 @@ void JitInstance::freeLongLivedArray(void* array) HeapFree(ourHeap, 0, array); } +// Helper for calling pnjitStartup. Needed to allow SEH here. +bool JitInstance::callJitStartup(ICorJitHost* jithost) +{ + // Calling into the collection, which could fail, especially + // for altjits. So protect the call. + + struct Param : FilterSuperPMIExceptionsParam_CaptureException + { + JitInstance* pThis; + ICorJitHost* jithost; + bool result; + } param; + param.pThis = this; + param.jithost = jithost; + param.result = false; + + PAL_TRY(Param*, pParam, ¶m) + { + pParam->pThis->pnjitStartup(pParam->jithost); + pParam->result = true; + } + PAL_EXCEPT_FILTER(FilterSuperPMIExceptions_CaptureExceptionAndStop) + { + SpmiException e(¶m.exceptionPointers); + + LogError("failed to call jitStartup."); + e.ShowAndDeleteMessage(); + } + PAL_ENDTRY + + return param.result; +} + // Reset JitConfig, that stores Enviroment variables. bool JitInstance::resetConfig(MethodContext* firstContext) { - if (pnjitStartup != nullptr) + if (pnjitStartup == nullptr) + { + return false; + } + + mc = firstContext; + ICorJitHost* newHost = new JitHost(*this); + + if (!callJitStartup(newHost)) { - mc = firstContext; - ICorJitHost* newHost = new JitHost(*this); - pnjitStartup(newHost); - delete static_cast(jitHost); - jitHost = newHost; - return true; + return false; } - return false; -} + + delete static_cast(jitHost); + jitHost = newHost; + return true; +} \ No newline at end of file diff --git a/src/ToolBox/superpmi/superpmi/jitinstance.h b/src/ToolBox/superpmi/superpmi/jitinstance.h index eeb2ff7081..e7b5fdb034 100644 --- a/src/ToolBox/superpmi/superpmi/jitinstance.h +++ b/src/ToolBox/superpmi/superpmi/jitinstance.h @@ -54,6 +54,8 @@ public: HRESULT StartUp(char* PathToJit, bool copyJit, bool breakOnDebugBreakorAV, MethodContext* firstContext); bool reLoad(MethodContext* firstContext); + bool callJitStartup(ICorJitHost* newHost); + bool resetConfig(MethodContext* firstContext); Result CompileMethod(MethodContext* MethodToCompile, int mcIndex, bool collectThroughput); -- cgit v1.2.3