From: Jan Kotas Date: Thu, 7 May 2020 18:58:16 +0000 (-0700) Subject: Delete FEATURE_CORRUPTING_EXCEPTIONS (#35938) X-Git-Tag: submit/tizen/20210909.063632~8119 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5178041776634bfbc4f868425710e60d95f7066f;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Delete FEATURE_CORRUPTING_EXCEPTIONS (#35938) * Delete HCORMODULE * Delete FEATURE_CORRUPTING_EXCEPTIONS Ability to catch corrupting exceptions was disabled in .NET Core since early days for security reasons. This is still disabled after this change, but achieved in much simpler way without the full corrupting exceptions machinery. * Delete unused bSecurityCheck argument of GetComIPFromObjectRef --- diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index ce2bc38..aa071ea 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -105,7 +105,6 @@ endif(CLR_CMAKE_TARGET_WIN32) add_definitions(-DFEATURE_BASICFREEZE) add_definitions(-DFEATURE_CORECLR) add_definitions(-DFEATURE_CORESYSTEM) -add_definitions(-DFEATURE_CORRUPTING_EXCEPTIONS) if(FEATURE_DBGIPC) add_definitions(-DFEATURE_DBGIPC_TRANSPORT_DI) add_definitions(-DFEATURE_DBGIPC_TRANSPORT_VM) diff --git a/src/coreclr/src/inc/clrconfigvalues.h b/src/coreclr/src/inc/clrconfigvalues.h index 51b47e4..f4cf1d1 100644 --- a/src/coreclr/src/inc/clrconfigvalues.h +++ b/src/coreclr/src/inc/clrconfigvalues.h @@ -253,7 +253,6 @@ CONFIG_DWORD_INFO(INTERNAL_SuppressLockViolationsOnReentryFromOS, W("SuppressLoc CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_AssertOnFailFast, W("AssertOnFailFast"), "") RETAIL_CONFIG_DWORD_INFO_EX(UNSUPPORTED_legacyCorruptedStateExceptionsPolicy, W("legacyCorruptedStateExceptionsPolicy"), 0, "Enabled Pre-V4 CSE behavior", CLRConfig::EEConfig_default) CONFIG_DWORD_INFO_EX(INTERNAL_SuppressLostExceptionTypeAssert, W("SuppressLostExceptionTypeAssert"), 0, "", CLRConfig::EEConfig_default) -RETAIL_CONFIG_DWORD_INFO_EX(UNSUPPORTED_FailFastOnCorruptedStateException, W("FailFastOnCorruptedStateException"), 0, "Failfast if a CSE is encountered", CLRConfig::EEConfig_default) RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_UseEntryPointFilter, W("UseEntryPointFilter"), 0, "", CLRConfig::EEConfig_default) RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_Corhost_Swallow_Uncaught_Exceptions, W("Corhost_Swallow_Uncaught_Exceptions"), 0, "", CLRConfig::EEConfig_default) diff --git a/src/coreclr/src/inc/corpriv.h b/src/coreclr/src/inc/corpriv.h index f0261b3..6b92458 100644 --- a/src/coreclr/src/inc/corpriv.h +++ b/src/coreclr/src/inc/corpriv.h @@ -25,9 +25,6 @@ interface IAssemblyName; -// PE images loaded through the runtime. -typedef struct _dummyCOR { BYTE b; } *HCORMODULE; - class UTSemReadWrite; // Helper function to get a pointer to the Dispenser interface. @@ -70,11 +67,6 @@ STDAPI GetAssemblyMDInternalImport( // Return code. REFIID riid, // [IN] The interface desired. IUnknown **ppIUnk); // [OUT] Return interface on success. -HRESULT GetAssemblyMDInternalImportFromImage( - HCORMODULE hImage, //[IN] pointer to module handle to get the metadata from. - REFIID riid, //[IN] The interface desired. - IUnknown **ppIUnk); //[OUT] Return Interface on success. - STDAPI GetAssemblyMDInternalImportByStream( // Return code. IStream *pIStream, // [IN] The IStream for the file UINT64 AssemblyId, // [IN] Unique Id for the assembly @@ -303,60 +295,6 @@ typedef enum CorOpenFlagsInternal #define COR_MODULE_CLASS "" #define COR_WMODULE_CLASS W("") -STDAPI RuntimeOpenImage(LPCWSTR pszFileName, HCORMODULE* hHandle); -STDAPI RuntimeOpenImageInternal(LPCWSTR pszFileName, HCORMODULE* hHandle, - DWORD *pdwLength, MDInternalImportFlags flags, HANDLE hFile = INVALID_HANDLE_VALUE); -STDAPI RuntimeOpenImageByStream(IStream* pIStream, UINT64 AssemblyId, DWORD dwModuleId, - HCORMODULE* hHandle, DWORD *pdwLength, MDInternalImportFlags flags); - -void RuntimeAddRefHandle(HCORMODULE hHandle); -STDAPI RuntimeReleaseHandle(HCORMODULE hHandle); -STDAPI RuntimeGetImageBase(HCORMODULE hHandle, LPVOID* base, BOOL bMapped, COUNT_T* dwSize); -STDAPI RuntimeGetImageKind(HCORMODULE hHandle, DWORD* pdwKind, DWORD* pdwMachine); -STDAPI RuntimeOSHandle(HCORMODULE hHandle, HMODULE* hModule); -STDAPI RuntimeGetAssemblyStrongNameHashForModule(HCORMODULE hModule, - IMetaDataImport *pMDimport, - BYTE *pbSNHash, - DWORD *pcbSNHash); -STDAPI RuntimeGetMDInternalImport(HCORMODULE hHandle, - MDInternalImportFlags flags, - IMDInternalImport** ppMDImport); - -FORCEINLINE -void ReleaseHCorModule(HCORMODULE hModule) -{ - HRESULT hr = RuntimeReleaseHandle(hModule); - _ASSERTE(SUCCEEDED(hr)); -} - -typedef Wrapper, ReleaseHCorModule, (UINT_PTR) NULL> HCORMODULEHolder; - - -// =========================================================================== -// ISNAssemblySignature (similar to IAssemblySignature in V1) -// -// This is a private interface that allows querying of the strong name -// signature. -// This can be used for (strong-named) assemblies added to the GAC as -// a unique identifier. -// - -// {848845BC-0C4A-42e3-8915-DC850112443D} -EXTERN_GUID(IID_ISNAssemblySignature, 0x848845BC, 0x0C4A, 0x42e3, 0x89, 0x15, 0xDC, 0x85, 0x01, 0x12, 0x44, 0x3D); - -#undef INTERFACE -#define INTERFACE ISNAssemblySignature -DECLARE_INTERFACE_(ISNAssemblySignature, IUnknown) -{ - // Returns the strong-name signature if the assembly is strong-name-signed - // Returns the MVID if the assembly is delay-signed. - // Fails if the assembly is not signed at all. - STDMETHOD(GetSNAssemblySignature) ( - BYTE *pbSig, // [IN, OUT] Buffer to write signature - DWORD *pcbSig // [IN, OUT] Size of buffer, bytes written - ) PURE; -}; - //------------------------------------- //--- ICeeGenInternal //------------------------------------- diff --git a/src/coreclr/src/inc/ex.h b/src/coreclr/src/inc/ex.h index 48a3572..6d008c6 100644 --- a/src/coreclr/src/inc/ex.h +++ b/src/coreclr/src/inc/ex.h @@ -706,93 +706,17 @@ private: EX_RETHROW; \ } \ -// Don't use this - use RethrowCorruptingExceptions (see below) instead. #define SwallowAllExceptions ; -////////////////////////////////////////////////////////////////////// -// -// Corrupted State Exception Support -// -///////////////////////////////////////////////////////////////////// - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - -#define CORRUPTING_EXCEPTIONS_ONLY(expr) expr -#define COMMA_CORRUPTING_EXCEPTIONS_ONLY(expr) ,expr - -// EX_END_CATCH has been modified to not swallow Corrupting Exceptions (CE) when one of the -// following arguments are passed to it: -// -// 1) RethrowTerminalExceptions - rethrows both terminal and corrupting exceptions -// 2) RethrowCorruptingExceptions - swallows all exceptions exception corrupting exceptions. This SHOULD BE USED instead of SwallowAllExceptions. -// 3) RethrowTerminalExceptionsEx - same as (1) but rethrow of CE can be controlled via a condition. -// 4) RethrowCorruptingExceptionsEx - same as (2) but rethrow of CE can be controlled via a condition. -// -// By default, if a CE is encountered when one of the above policies are applied, the runtime will -// ensure that the CE propagates up the stack and not get swallowed unless the developer chooses to override the behaviour. -// This can be done by using the "Ex" versions above that take a conditional which evaluates to a BOOL. In such a case, -// the CE will *only* be rethrown if the conditional evalutes to TRUE. For examples, refer to COMToCLRWorker or -// DispatchInfo::InvokeMember implementations. -// -// SET_CE_RETHROW_FLAG_FOR_EX_CATCH macros helps evaluate if the CE is to be rethrown or not. This has been redefined in -// Clrex.h to add the condition of evaluating the throwable as well (which is not available outside the VM folder). -// -// Passing FALSE as the second argument to IsProcessCorruptedStateException implies that SET_CE_RETHROW_FLAG_FOR_EX_CATCH -// will ensure that we dont rethrow SO and allow EX_ENDTRY to SO specific processing. If none is done, then EX_ENDTRY will -// rethrow SO. By that time stack has been reclaimed and thus, throwing SO will be safe. -// -// We also check the global override flag incase it has been set to force pre-V4 beahviour. "0" implies it has not -// been overriden. -#define SET_CE_RETHROW_FLAG_FOR_EX_CATCH(expr) ((((expr) == TRUE) && \ - (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_legacyCorruptedStateExceptionsPolicy) == 0) && \ - IsProcessCorruptedStateException(GetCurrentExceptionCode(), FALSE))) - -// This rethrow policy can be used in EX_END_CATCH to swallow all exceptions except the corrupting ones. -// This macro can be used to rethrow the CE based upon a BOOL condition. -#define RethrowCorruptingExceptionsEx(expr) \ - if (SET_CE_RETHROW_FLAG_FOR_EX_CATCH(expr)) \ - { \ - STATIC_CONTRACT_THROWS_TERMINAL; \ - EX_RETHROW; \ - } - -#define RethrowCorruptingExceptionsExAndHookRethrow(shouldRethrowExpr, aboutToRethrowExpr) \ - if (SET_CE_RETHROW_FLAG_FOR_EX_CATCH(shouldRethrowExpr)) \ - { \ - STATIC_CONTRACT_THROWS_TERMINAL; \ - aboutToRethrowExpr; \ - EX_RETHROW; \ - } - -#else // !FEATURE_CORRUPTING_EXCEPTIONS - -#define CORRUPTING_EXCEPTIONS_ONLY(expr) -#define COMMA_CORRUPTING_EXCEPTIONS_ONLY(expr) - -// When we dont have support for CE, just map it to SwallowAllExceptions -#define RethrowCorruptingExceptionsEx(expr) SwallowAllExceptions -#define RethrowCorruptingExceptionsExAndHookRethrow(shouldRethrowExpr, aboutToRethrowExpr) SwallowAllExceptions -#define SET_CE_RETHROW_FLAG_FOR_EX_CATCH(expr) !TRUE -#endif // FEATURE_CORRUPTING_EXCEPTIONS - -// Map to RethrowCorruptingExceptionsEx so that it does the "right" thing -#define RethrowCorruptingExceptions RethrowCorruptingExceptionsEx(TRUE) - -// This macro can be used to rethrow the CE based upon a BOOL condition. It will continue to rethrow terminal -// exceptions unconditionally. -#define RethrowTerminalExceptionsEx(expr) \ - if (GET_EXCEPTION()->IsTerminal() || \ - SET_CE_RETHROW_FLAG_FOR_EX_CATCH(expr)) \ +// When applied to EX_END_CATCH, this policy will always rethrow Terminal exceptions if they are +// encountered. +#define RethrowTerminalExceptions \ + if (GET_EXCEPTION()->IsTerminal()) \ { \ STATIC_CONTRACT_THROWS_TERMINAL; \ EX_RETHROW; \ } \ - -// When applied to EX_END_CATCH, this policy will always rethrow Terminal and Corrupting exceptions if they are -// encountered. -#define RethrowTerminalExceptions RethrowTerminalExceptionsEx(TRUE) - // Special define to be used in EEStartup that will also check for VM initialization before // commencing on a path that may use the managed thread object. #define RethrowTerminalExceptionsWithInitCheck \ diff --git a/src/coreclr/src/inc/utilcode.h b/src/coreclr/src/inc/utilcode.h index 1721db0..14b261b 100644 --- a/src/coreclr/src/inc/utilcode.h +++ b/src/coreclr/src/inc/utilcode.h @@ -4715,13 +4715,6 @@ BOOL IsIPInModule(HMODULE_TGT hModule, PCODE ip); extern HINSTANCE g_hmodCoreCLR; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - -// Corrupting Exception limited support for outside the VM folder -BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, BOOL fCheckForSO = TRUE); - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - namespace UtilCode { // These are type-safe versions of Interlocked[Compare]Exchange diff --git a/src/coreclr/src/md/runtime/mdinternaldisp.h b/src/coreclr/src/md/runtime/mdinternaldisp.h index 510e873..530a141 100644 --- a/src/coreclr/src/md/runtime/mdinternaldisp.h +++ b/src/coreclr/src/md/runtime/mdinternaldisp.h @@ -16,7 +16,6 @@ #include "mdinternalro.h" - enum MDFileFormat { MDFormat_ReadOnly = 0, @@ -25,8 +24,6 @@ enum MDFileFormat MDFormat_Invalid = 3 }; - -HRESULT CheckFileFormat(LPVOID pData, ULONG cbData, MDFileFormat *pFormat); STDAPI GetMDInternalInterface( LPVOID pData, // [IN] Buffer with the metadata. ULONG cbData, // [IN] Size of the data in the buffer. @@ -34,11 +31,6 @@ STDAPI GetMDInternalInterface( REFIID riid, // [in] The interface desired. void **ppIUnk); // [out] Return interface on success. -HRESULT GetAssemblyMDInternalImportHelper(HCORMODULE hModule, - REFIID riid, - MDInternalImportFlags flags, - IUnknown **ppIUnk); - #endif //FEATURE_METADATA_INTERNAL_APIS #endif // __MDInternalDispenser__h__ diff --git a/src/coreclr/src/utilcode/util.cpp b/src/coreclr/src/utilcode/util.cpp index f1f004d..8c980df 100644 --- a/src/coreclr/src/utilcode/util.cpp +++ b/src/coreclr/src/utilcode/util.cpp @@ -3031,58 +3031,6 @@ lDone: ; return param.fRet; } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - -// To include definition of EXCEPTION_SOFTSO -#include "corexcep.h" - -// These functions provide limited support for corrupting exceptions -// outside the VM folder. Its limited since we don't have access to the -// throwable. -// -// These functions are also wrapped by the corresponding CEHelper -// methods in excep.cpp. - -// Given an exception code, this method returns a BOOL to indicate if the -// code belongs to a corrupting exception or not. -BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, BOOL fCheckForSO /*=TRUE*/) -{ - LIMITED_METHOD_CONTRACT; - - // By default, assume its not corrupting - BOOL fIsCorruptedStateException = FALSE; - - if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_legacyCorruptedStateExceptionsPolicy) == 1) - { - return fIsCorruptedStateException; - } - - // If we have been asked not to include SO in the CSE check - // and the code represent SO, then exit now. - if ((fCheckForSO == FALSE) && (dwExceptionCode == STATUS_STACK_OVERFLOW)) - { - return fIsCorruptedStateException; - } - - switch(dwExceptionCode) - { - case STATUS_ACCESS_VIOLATION: - case STATUS_STACK_OVERFLOW: - case EXCEPTION_ILLEGAL_INSTRUCTION: - case EXCEPTION_IN_PAGE_ERROR: - case EXCEPTION_INVALID_DISPOSITION: - case EXCEPTION_NONCONTINUABLE_EXCEPTION: - case EXCEPTION_PRIV_INSTRUCTION: - case STATUS_UNWIND_CONSOLIDATE: - fIsCorruptedStateException = TRUE; - break; - } - - return fIsCorruptedStateException; -} - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - namespace Clr { namespace Util diff --git a/src/coreclr/src/vm/.vscode/c_cpp_properties.json b/src/coreclr/src/vm/.vscode/c_cpp_properties.json index a4c0ec9..2a68e99 100644 --- a/src/coreclr/src/vm/.vscode/c_cpp_properties.json +++ b/src/coreclr/src/vm/.vscode/c_cpp_properties.json @@ -53,7 +53,6 @@ "FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION", "FEATURE_CORECLR", "FEATURE_CORESYSTEM", - "FEATURE_CORRUPTING_EXCEPTIONS", "FEATURE_DATABREAKPOINT", "FEATURE_DEFAULT_INTERFACES", "FEATURE_EVENT_TRACE=1", diff --git a/src/coreclr/src/vm/castcache.cpp b/src/coreclr/src/vm/castcache.cpp index 9fb5f7a..829d8b3 100644 --- a/src/coreclr/src/vm/castcache.cpp +++ b/src/coreclr/src/vm/castcache.cpp @@ -40,7 +40,7 @@ BASEARRAYREF CastCache::CreateCastCache(DWORD size) EX_CATCH { } - EX_END_CATCH(RethrowCorruptingExceptions) + EX_END_CATCH(RethrowTerminalExceptions) if (!table) { @@ -54,7 +54,7 @@ BASEARRAYREF CastCache::CreateCastCache(DWORD size) EX_CATCH { } - EX_END_CATCH(RethrowCorruptingExceptions) + EX_END_CATCH(RethrowTerminalExceptions) if (!table) { diff --git a/src/coreclr/src/vm/clrex.h b/src/coreclr/src/vm/clrex.h index 16b3257..3a570a5 100644 --- a/src/coreclr/src/vm/clrex.h +++ b/src/coreclr/src/vm/clrex.h @@ -735,7 +735,7 @@ class EEFileLoadException : public EEException // { // EX_RETHROW() // } -// EX_END_CATCH(RethrowTerminalExceptions or RethrowCorruptingExceptions) +// EX_END_CATCH(RethrowTerminalExceptions) // -------------------------------------------------------------------------------------------------------- // In DAC builds, we don't want to override the normal utilcode exception handling. @@ -746,62 +746,6 @@ class EEFileLoadException : public EEException #define GET_THROWABLE() CLRException::GetThrowableFromException(GET_EXCEPTION()) -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - -// For the VM folder, we redefine SET_CE_RETHROW_FLAG_FOR_EX_CATCH to also check the -// corruption severity when deciding whether to rethrow them or not. -// -// We also check the global override flag incase it has been set to force pre-V4 behaviour. -// -// Doing the checks for "__fCaughtSO" and "__fCaughtNonCxx" will ensure that we check for -// corruption severity only if the last exception was a managed exception that could have been rethrown in the VM. -// When "(__fCaughtSO == FALSE) && (__fCaughtNonCxx == true)" is true, it implies we are dealing with a managed exception -// inside the VM that is represented by the CLRLastThrownObjectException instance (see EX_TRY/EX_CATCH implementation in VM -// folder to see how CLRLastThrownObjectException is used). -// -// This macro also supports the following scenarios: -// -// Scenario 1 -// ---------- -// -// [VM1] -> [VM2] -> -// -// If a managed exception is swallowed by an EX_CATCH in native function VM2, which then returns back -// to native function VM1 that throws, for example, a VM C++ exception, an EX_CATCH(RethrowCorruptingExceptions) -// in VM1 that catches the C++ exception will not rethrow since the last exception was not a managed CSE but -// a C++ exception. -// -// A variation of this is for VM2 to return back in VM1, which calls VM3 that throws a VM C++ exception that -// reaches VM1's EX_CATCH(RethrowCorruptingExceptions). VM1 shouldn't be rethrowing the exception in such a case. -// -// Scenario 2 -// ---------- -// -// [VM1 - RethrowCSE] -> [VM2 - RethrowCSE] -> [VM3 - RethrowCSE] -> -// -// When managed code throws a CSE (e.g. TargetInvocationException flagged as CSE), [VM3] will rethrow it and we will -// enter EX_CATCH in VM2 which is supposed to rethrow it as well. But if the implementation of EX_CATCH in VM2 throws -// another VM C++ exception (e.g. EEFileLoadException) *before* rethrow policy is applied, control will reach EX_CATCH -// in VM1 that *shouldn't* rethrow (even though it has RethrowCSE as the policy) since the last exception was a VM C++ -// exception. -// -// Scenario 3 -// ---------- -// -// This is about VM throwing a managed exception that gets handled either within the VM, with or without CLR's managed code -// exception handler coming into the picture. -// -// This is explained in detail (alongwith relevant changes) in the implementation of RaiseTheException (in excep.cpp). - -#undef SET_CE_RETHROW_FLAG_FOR_EX_CATCH -#define SET_CE_RETHROW_FLAG_FOR_EX_CATCH(expr) (((expr) == TRUE) && \ - (g_pConfig->LegacyCorruptedStateExceptionsPolicy() == false) && \ - (CEHelper::IsProcessCorruptedStateException(GetCurrentExceptionCode(), FALSE) || \ - (!__state.DidCatchCxx() && \ - CEHelper::IsLastActiveExceptionCorrupting(TRUE)))) - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - #undef EX_TRY #define EX_TRY \ EX_TRY_CUSTOM(CLRException::HandlerState, (::GetThreadNULLOk()), CLRLastThrownObjectException) @@ -1002,25 +946,6 @@ LONG CLRNoCatchHandler(EXCEPTION_POINTERS* pExceptionInfo, PVOID pv); } \ } \ -// This macro should be used at the entry points (e.g. COM interop boundaries) -// where CE's are not expected to get swallowed. -#define END_EXTERNAL_ENTRYPOINT_RETHROW_CORRUPTING_EXCEPTIONS_EX(fCond) \ - } \ - EX_CATCH \ - { \ - *__phr = GET_EXCEPTION()->GetHR(); \ - } \ - EX_END_CATCH(RethrowCorruptingExceptionsEx(fCond)); \ - } \ - } \ - -// This macro should be used at the entry points (e.g. COM interop boundaries) -// where CE's are not expected to get swallowed. -#define END_EXTERNAL_ENTRYPOINT_RETHROW_CORRUPTING_EXCEPTIONS \ - END_EXTERNAL_ENTRYPOINT_RETHROW_CORRUPTING_EXCEPTIONS_EX(TRUE) - - - //============================================================================== // --------------------------------------------------------------------------- diff --git a/src/coreclr/src/vm/comcallablewrapper.cpp b/src/coreclr/src/vm/comcallablewrapper.cpp index c621eeb..583d52d 100644 --- a/src/coreclr/src/vm/comcallablewrapper.cpp +++ b/src/coreclr/src/vm/comcallablewrapper.cpp @@ -3678,8 +3678,7 @@ IDispatch* ComCallWrapper::GetIDispatchIP() CorIfaceAttr ifaceType = hndDefItfClass.GetMethodTable()->GetComInterfaceType(); if (IsDispatchBasedItf(ifaceType)) { - RETURN (IDispatch*)GetComIPFromCCW(this, GUID_NULL, hndDefItfClass.GetMethodTable(), - GetComIPFromCCW::SuppressSecurityCheck); + RETURN (IDispatch*)GetComIPFromCCW(this, GUID_NULL, hndDefItfClass.GetMethodTable()); } else { diff --git a/src/coreclr/src/vm/comcallablewrapper.h b/src/coreclr/src/vm/comcallablewrapper.h index 51b6f88..9ef02ec 100644 --- a/src/coreclr/src/vm/comcallablewrapper.h +++ b/src/coreclr/src/vm/comcallablewrapper.h @@ -957,8 +957,7 @@ struct GetComIPFromCCW { None = 0, CheckVisibility = 1, - SuppressSecurityCheck = 2, - SuppressCustomizedQueryInterface = 4 + SuppressCustomizedQueryInterface = 2 }; }; diff --git a/src/coreclr/src/vm/comdelegate.cpp b/src/coreclr/src/vm/comdelegate.cpp index 20a724b..e2b45fb 100644 --- a/src/coreclr/src/vm/comdelegate.cpp +++ b/src/coreclr/src/vm/comdelegate.cpp @@ -3282,44 +3282,7 @@ static void InvokeUnhandledSwallowing(OBJECTREF *pDelegate, EX_TRY { -#if defined(FEATURE_CORRUPTING_EXCEPTIONS) - BOOL fCanMethodHandleException = g_pConfig->LegacyCorruptedStateExceptionsPolicy(); - if (!fCanMethodHandleException) - { - // CSE policy has not been overridden - proceed with our checks. - // - // Notifications for CSE are only delivered if the delegate target follows CSE rules. - // So, get the corruption severity of the active exception that has gone unhandled. - // - // By Default, assume that the active exception is not corrupting. - CorruptionSeverity severity = NotCorrupting; - Thread *pCurThread = GetThread(); - _ASSERTE(pCurThread != NULL); - ThreadExceptionState *pExState = pCurThread->GetExceptionState(); - if (pExState->IsExceptionInProgress()) - { - // If an exception is active, it implies we have a tracker for it. - // Hence, get the corruption severity from the active exception tracker. - severity = pExState->GetCurrentExceptionTracker()->GetCorruptionSeverity(); - _ASSERTE(severity > NotSet); - } - - // Notifications are delivered based upon corruption severity of the exception - fCanMethodHandleException = ExceptionNotifications::CanDelegateBeInvokedForException(pDelegate, severity); - if (!fCanMethodHandleException) - { - LOG((LF_EH, LL_INFO100, "InvokeUnhandledSwallowing: ADUEN Delegate cannot be invoked for corruption severity %d\n", - severity)); - } - } - - if (fCanMethodHandleException) -#endif // defined(FEATURE_CORRUPTING_EXCEPTIONS) - { - // We've already exercised the prestub on this delegate's COMDelegate::GetMethodDesc, - // as part of wiring up a reliable event sink. Deliver the notification. - ExceptionNotifications::DeliverExceptionNotification(UnhandledExceptionHandler, pDelegate, pDomain, pEventArgs); - } + ExceptionNotifications::DeliverExceptionNotification(UnhandledExceptionHandler, pDelegate, pDomain, pEventArgs); } EX_CATCH { diff --git a/src/coreclr/src/vm/commodule.cpp b/src/coreclr/src/vm/commodule.cpp index 3a54696..51160cf 100644 --- a/src/coreclr/src/vm/commodule.cpp +++ b/src/coreclr/src/vm/commodule.cpp @@ -888,7 +888,7 @@ HINSTANCE QCALLTYPE COMModule::GetHINSTANCE(QCall::ModuleHandle pModule) BEGIN_QCALL; - // This returns the base address - this will work for either HMODULE or HCORMODULES + // This returns the base address // Other modules should have zero base PEFile *pPEFile = pModule->GetFile(); if (!pPEFile->IsDynamic() && !pPEFile->IsResource()) @@ -1093,4 +1093,3 @@ FCIMPL0(void*, COMPunkSafeHandle::nGetDReleaseTarget) } FCIMPLEND - diff --git a/src/coreclr/src/vm/dispatchinfo.cpp b/src/coreclr/src/vm/dispatchinfo.cpp index 8da1151..dca9108 100644 --- a/src/coreclr/src/vm/dispatchinfo.cpp +++ b/src/coreclr/src/vm/dispatchinfo.cpp @@ -2193,10 +2193,8 @@ HRESULT DispatchInfo::InvokeMember(SimpleComCallWrapper *pSimpleWrap, DISPID id, EX_CATCH { pThrowable = GET_THROWABLE(); - - // RethrowCorruptingExceptionsEx, in EX_END_CATCH below, will ensure that CEs are rethrown. } - EX_END_CATCH(RethrowCorruptingExceptionsEx(!CEHelper::CanIDispatchTargetHandleException())) + EX_END_CATCH(RethrowTerminalExceptions) catchFrame.Pop(); if (pThrowable != NULL) diff --git a/src/coreclr/src/vm/eeconfig.cpp b/src/coreclr/src/vm/eeconfig.cpp index bf0c602..bb4266f 100644 --- a/src/coreclr/src/vm/eeconfig.cpp +++ b/src/coreclr/src/vm/eeconfig.cpp @@ -126,11 +126,6 @@ HRESULT EEConfig::Init() fJitMinOpts = false; fPInvokeRestoreEsp = (DWORD)-1; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // By default, there is not pre-V4 CSE policy - fLegacyCorruptedStateExceptionsPolicy = false; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - fNgenBindOptimizeNonGac = false; fStressLog = false; fProbeForStackOverflow = true; diff --git a/src/coreclr/src/vm/eeconfig.h b/src/coreclr/src/vm/eeconfig.h index c657978..7ed91a4 100644 --- a/src/coreclr/src/vm/eeconfig.h +++ b/src/coreclr/src/vm/eeconfig.h @@ -133,11 +133,6 @@ public: } } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Returns a bool to indicate if the legacy CSE (pre-v4) behaviour is enabled or not - bool LegacyCorruptedStateExceptionsPolicy(void) const {LIMITED_METHOD_CONTRACT; return fLegacyCorruptedStateExceptionsPolicy; } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - bool InteropValidatePinnedObjects() const { LIMITED_METHOD_CONTRACT; return m_fInteropValidatePinnedObjects; } bool InteropLogArguments() const { LIMITED_METHOD_CONTRACT; return m_fInteropLogArguments; } @@ -559,10 +554,6 @@ private: //---------------------------------------------------------------- unsigned fPInvokeRestoreEsp; // -1=Default, 0=Never, Else=Always -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - bool fLegacyCorruptedStateExceptionsPolicy; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - LPUTF8 pszBreakOnClassLoad; // Halt just before loading this class #ifdef TEST_DATA_CONSISTENCY diff --git a/src/coreclr/src/vm/eventtrace.cpp b/src/coreclr/src/vm/eventtrace.cpp index aee5cae..d5099e4 100644 --- a/src/coreclr/src/vm/eventtrace.cpp +++ b/src/coreclr/src/vm/eventtrace.cpp @@ -974,7 +974,7 @@ HRESULT ETW::GCLog::ForceGCForDiagnostics() #ifndef FEATURE_REDHAWK } EX_CATCH { } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); #endif // FEATURE_REDHAWK return hr; @@ -1752,7 +1752,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th) { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) return -1; @@ -1791,7 +1791,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th) { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) return -1; } @@ -1811,7 +1811,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th) { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) return -1; } @@ -1850,7 +1850,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th) { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) return -1; } @@ -1888,7 +1888,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th) // won't have a name in it. pVal->sName.Clear(); } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); // Now that we know the full size of this type's data, see if it fits in our // batch or whether we need to flush @@ -1986,7 +1986,7 @@ void BulkTypeEventLogger::LogTypeAndParameters(ULONGLONG thAsAddr, ETW::TypeSyst { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) return; @@ -2551,7 +2551,7 @@ VOID ETW::GCLog::SendFinalizeObjectEvent(MethodTable * pMT, Object * pObj) EX_CATCH { } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); } } @@ -2977,7 +2977,7 @@ BOOL ETW::TypeSystemLog::AddOrReplaceTypeLoggingInfo(ETW::LoggedTypesFromModule { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); return fSucceeded; } @@ -3384,7 +3384,7 @@ ETW::TypeLoggingInfo ETW::TypeSystemLog::LookupOrCreateTypeLoggingInfo(TypeHandl { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) { *pfCreatedNew = FALSE; @@ -3422,7 +3422,7 @@ ETW::TypeLoggingInfo ETW::TypeSystemLog::LookupOrCreateTypeLoggingInfo(TypeHandl { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) { *pfCreatedNew = FALSE; @@ -3518,7 +3518,7 @@ BOOL ETW::TypeSystemLog::AddTypeToGlobalCacheIfNotExists(TypeHandle th, BOOL * p { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) { *pfCreatedNew = FALSE; @@ -3550,7 +3550,7 @@ BOOL ETW::TypeSystemLog::AddTypeToGlobalCacheIfNotExists(TypeHandle th, BOOL * p { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) { *pfCreatedNew = FALSE; @@ -4641,7 +4641,6 @@ VOID ETW::ExceptionLog::ExceptionThrown(CrawlFrame *pCf, BOOL bIsReThrownExcept pExInfo = pExState->GetCurrentExceptionTracker(); _ASSERTE(pExInfo != NULL); bIsNestedException = (pExInfo->GetPreviousExceptionTracker() != NULL); - bIsCSE = (pExInfo->GetCorruptionSeverity() == ProcessCorrupting); bIsCLSCompliant = IsException((gc.exceptionObj)->GetMethodTable()) && ((gc.exceptionObj)->GetMethodTable() != MscorlibBinder::GetException(kRuntimeWrappedException)); @@ -4656,7 +4655,6 @@ VOID ETW::ExceptionLog::ExceptionThrown(CrawlFrame *pCf, BOOL bIsReThrownExcept exceptionFlags = ((bHasInnerException ? ETW::ExceptionLog::ExceptionStructs::HasInnerException : 0) | (bIsNestedException ? ETW::ExceptionLog::ExceptionStructs::IsNestedException : 0) | (bIsReThrownException ? ETW::ExceptionLog::ExceptionStructs::IsReThrownException : 0) | - (bIsCSE ? ETW::ExceptionLog::ExceptionStructs::IsCSE : 0) | (bIsCLSCompliant ? ETW::ExceptionLog::ExceptionStructs::IsCLSCompliant : 0)); if (pCf->IsFrameless()) @@ -6279,7 +6277,7 @@ VOID ETW::MethodLog::SendMethodDetailsEvent(MethodDesc *pMethodDesc) { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) goto done; diff --git a/src/coreclr/src/vm/excep.cpp b/src/coreclr/src/vm/excep.cpp index 2dd54db..657717d 100644 --- a/src/coreclr/src/vm/excep.cpp +++ b/src/coreclr/src/vm/excep.cpp @@ -121,11 +121,7 @@ typedef struct { PEXCEPTION_REGISTRATION_RECORD GetCurrentSEHRecord(); BOOL IsUnmanagedToManagedSEHHandler(EXCEPTION_REGISTRATION_RECORD*); -VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity = NotCorrupting -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); +VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow); //------------------------------------------------------------------------------- // Basically, this asks whether the exception is a managed exception thrown by @@ -2711,85 +2707,6 @@ LONG RaiseExceptionFilter(EXCEPTION_POINTERS* ep, LPVOID pv) return EXCEPTION_CONTINUE_SEARCH; } -//========================================================================== -// Throw an object. -//========================================================================== -VOID DECLSPEC_NORETURN RaiseTheException(OBJECTREF throwable, BOOL rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ) -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_TRIGGERS; - STATIC_CONTRACT_MODE_COOPERATIVE; - - LOG((LF_EH, LL_INFO100, "RealCOMPlusThrow throwing %s\n", - throwable->GetMethodTable()->GetDebugClassName())); - - if (throwable == NULL) - { - _ASSERTE(!"RealCOMPlusThrow(OBJECTREF) called with NULL argument. Somebody forgot to post an exception!"); - EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE); - } - - _ASSERTE(throwable != CLRException::GetPreallocatedStackOverflowException()); - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - if (!g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - // This is Scenario 3 described in clrex.h around the definition of SET_CE_RETHROW_FLAG_FOR_EX_CATCH macro. - // - // We are here because the VM is attempting to throw a managed exception. It is posssible this exception - // may not be seen by CLR's exception handler for managed code (e.g. there maybe an EX_CATCH up the stack - // that will swallow or rethrow this exception). In the following scenario: - // - // [VM1 - RethrowCSE] -> [VM2 - RethrowCSE] -> [VM3 - RethrowCSE] -> - // - // When managed code throws a CSE (e.g. TargetInvocationException flagged as CSE), [VM3] will rethrow it and we will - // enter EX_CATCH in VM2 which is supposed to rethrow it as well. Two things can happen: - // - // 1) The implementation of EX_CATCH in VM2 throws a new managed exception *before* rethrow policy is applied and control - // will reach EX_CATCH in VM1, OR - // - // 2) EX_CATCH in VM2 swallows the exception, comes out of the catch block and later throws a new managed exception that - // will be caught by EX_CATCH in VM1. - // - // In either of the cases, rethrow in VM1 should be on the basis of the new managed exception's corruption severity. - // - // To support this scenario, we set corruption severity of the managed exception VM is throwing. If its a rethrow, - // it implies we are rethrowing the last exception that was seen by CLR's managed code exception handler. In such a case, - // we will copy over the corruption severity of that exception. - - // If throwable indicates corrupted state, forcibly set the severity. - if (CEHelper::IsProcessCorruptedStateException(throwable)) - { - severity = ProcessCorrupting; - } - - // No one should have passed us an invalid severity. - _ASSERTE(severity > NotSet); - - if (severity == NotSet) - { - severity = NotCorrupting; - } - - // Update the corruption severity of the exception being thrown by the VM. - GetThread()->GetExceptionState()->SetLastActiveExceptionCorruptionSeverity(severity); - - // Exception's corruption severity should be reused in reraise if this exception leaks out from the VM - // into managed code - CEHelper::MarkLastActiveExceptionCorruptionSeverityForReraiseReuse(); - - LOG((LF_EH, LL_INFO100, "RaiseTheException - Set VM thrown managed exception severity to %d.\n", severity)); - } - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - - RaiseTheExceptionInternalOnly(throwable,rethrow); -} - HRESULT GetHRFromThrowable(OBJECTREF throwable) { STATIC_CONTRACT_THROWS; @@ -2965,11 +2882,8 @@ VOID DECLSPEC_NORETURN RaiseTheExceptionInternalOnly(OBJECTREF throwable, BOOL r // INSTALL_COMPLUS_EXCEPTION_HANDLER has a filter, so must put the call in a separate fcn -static VOID DECLSPEC_NORETURN RealCOMPlusThrowWorker(OBJECTREF throwable, BOOL rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS -) { +static VOID DECLSPEC_NORETURN RealCOMPlusThrowWorker(OBJECTREF throwable, BOOL rethrow) +{ STATIC_CONTRACT_THROWS; STATIC_CONTRACT_GC_TRIGGERS; STATIC_CONTRACT_MODE_ANY; @@ -2982,23 +2896,24 @@ static VOID DECLSPEC_NORETURN RealCOMPlusThrowWorker(OBJECTREF throwable, BOOL r // TODO: Do we need to install COMPlusFrameHandler here? INSTALL_COMPLUS_EXCEPTION_HANDLER(); - RaiseTheException(throwable, rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + if (throwable == NULL) + { + _ASSERTE(!"RealCOMPlusThrow(OBJECTREF) called with NULL argument. Somebody forgot to post an exception!"); + EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE); + } + RaiseTheExceptionInternalOnly(throwable, rethrow); UNINSTALL_COMPLUS_EXCEPTION_HANDLER(); } - -VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS -) { +VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow) +{ STATIC_CONTRACT_THROWS; STATIC_CONTRACT_GC_TRIGGERS; STATIC_CONTRACT_MODE_ANY; + + LOG((LF_EH, LL_INFO100, "RealCOMPlusThrow throwing %s\n", + throwable->GetMethodTable()->GetDebugClassName())); + GCPROTECT_BEGIN(throwable); _ASSERTE(IsException(throwable->GetMethodTable())); @@ -3019,20 +2934,12 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow ExceptionPreserveStackTrace(throwable); } - RealCOMPlusThrowWorker(throwable, rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + RealCOMPlusThrowWorker(throwable, rethrow); GCPROTECT_END(); } -VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ) +VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable) { CONTRACTL { @@ -3042,11 +2949,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable } CONTRACTL_END; - RealCOMPlusThrow(throwable, FALSE -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + RealCOMPlusThrow(throwable, FALSE); } // this function finds the managed callback to get a resource @@ -3709,14 +3612,6 @@ BOOL IsUncatchable(OBJECTREF *pThrowable) if (OBJECTREFToObject(*pThrowable)->GetMethodTable() == g_pExecutionEngineExceptionClass) return TRUE; - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Corrupting exceptions are also uncatchable - if (CEHelper::IsProcessCorruptedStateException(*pThrowable)) - { - return TRUE; - } -#endif //FEATURE_CORRUPTING_EXCEPTIONS } return FALSE; @@ -8552,35 +8447,6 @@ LONG ReflectionInvocationExceptionFilter( } #endif // !TARGET_UNIX - // If the application has opted into triggering a failfast when a CorruptedStateException enters the Reflection system, - // then do the needful. - if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_FailFastOnCorruptedStateException) == 1) - { - // Get the thread and the managed exception object - they must exist at this point - Thread *pCurThread = GetThread(); - _ASSERTE(pCurThread != NULL); - - // Get the thread exception state - ThreadExceptionState * pCurTES = pCurThread->GetExceptionState(); - _ASSERTE(pCurTES != NULL); - - // Get the exception tracker for the current exception -#ifdef FEATURE_EH_FUNCLETS - PTR_ExceptionTracker pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#elif TARGET_X86 - PTR_ExInfo pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#else // !(HOST_64BIT || TARGET_X86) -#error Unsupported platform -#endif // HOST_64BIT - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - if (pEHTracker->GetCorruptionSeverity() == ProcessCorrupting) - { - EEPolicy::HandleFatalError(COR_E_FAILFAST, reinterpret_cast(pExceptionInfo->ExceptionRecord->ExceptionAddress), NULL, pExceptionInfo); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - } - return ret; } // LONG ReflectionInvocationExceptionFilter() @@ -11095,781 +10961,43 @@ PTR_ExInfo GetEHTrackerForException(OBJECTREF oThrowable, PTR_ExInfo pStartingEH return fFoundTracker ? pEHTracker : NULL; } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -// ----------------------------------------------------------------------- -// Support for CorruptedState Exceptions -// ----------------------------------------------------------------------- - // Given an exception code, this method returns a BOOL to indicate if the // code belongs to a corrupting exception or not. /* static */ -BOOL CEHelper::IsProcessCorruptedStateException(DWORD dwExceptionCode, BOOL fCheckForSO /*= TRUE*/) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return FALSE; - } - - // Call into the utilcode helper function to check if this - // is a CE or not. - return (::IsProcessCorruptedStateException(dwExceptionCode, fCheckForSO)); -} - -// This is used in the VM folder version of "SET_CE_RETHROW_FLAG_FOR_EX_CATCH" (in clrex.h) -// to check if the managed exception caught by EX_END_CATCH is CSE or not. -// -// If you are using it from rethrow boundaries (e.g. SET_CE_RETHROW_FLAG_FOR_EX_CATCH -// macro that is used to automatically rethrow corrupting exceptions), then you may -// want to set the "fMarkForReuseIfCorrupting" to TRUE to enable propagation of the -// corruption severity when the reraised exception is seen by managed code again. -/* static */ -BOOL CEHelper::IsLastActiveExceptionCorrupting(BOOL fMarkForReuseIfCorrupting /* = FALSE */) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(GetThread() != NULL); - } - CONTRACTL_END; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return FALSE; - } - - BOOL fIsCorrupting = FALSE; - ThreadExceptionState *pCurTES = GetThread()->GetExceptionState(); - - // Check the corruption severity - CorruptionSeverity severity = pCurTES->GetLastActiveExceptionCorruptionSeverity(); - fIsCorrupting = (severity == ProcessCorrupting); - if (fIsCorrupting && fMarkForReuseIfCorrupting) - { - // Mark the corruption severity for reuse - CEHelper::MarkLastActiveExceptionCorruptionSeverityForReraiseReuse(); - } - - LOG((LF_EH, LL_INFO100, "CEHelper::IsLastActiveExceptionCorrupting - Using corruption severity from TES.\n")); - - return fIsCorrupting; -} - -// Given a MethodDesc, this method will return a BOOL to indicate if -// the containing assembly was built for PreV4 runtime or not. -/* static */ -BOOL CEHelper::IsMethodInPreV4Assembly(PTR_MethodDesc pMethodDesc) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(pMethodDesc != NULL); - } - CONTRACTL_END; - - // By default, assume that the containing assembly was not - // built for PreV4 runtimes. - BOOL fBuiltForPreV4Runtime = FALSE; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return TRUE; - } - - LPCSTR pszVersion = NULL; - - // Retrieve the manifest metadata reference since that contains - // the "built-for" runtime details - IMDInternalImport *pImport = pMethodDesc->GetAssembly()->GetManifestImport(); - if (pImport && SUCCEEDED(pImport->GetVersionString(&pszVersion))) - { - if (pszVersion != NULL) - { - // If version begins with "v1.*" or "v2.*", it was built for preV4 runtime - if ((pszVersion[0] == 'v' || pszVersion[0] == 'V') && - IS_DIGIT(pszVersion[1]) && - (pszVersion[2] == '.') ) - { - // Looks like a version. Is it lesser than v4.0 major version where we start using new behavior? - fBuiltForPreV4Runtime = ((DIGIT_TO_INT(pszVersion[1]) != 0) && - (DIGIT_TO_INT(pszVersion[1]) <= HIGHEST_MAJOR_VERSION_OF_PREV4_RUNTIME)); - } - } - } - - return fBuiltForPreV4Runtime; -} - -// Given a MethodDesc and CorruptionSeverity, this method will return a -// BOOL indicating if the method can handle those kinds of CEs or not. -/* static */ -BOOL CEHelper::CanMethodHandleCE(PTR_MethodDesc pMethodDesc, CorruptionSeverity severity) -{ - BOOL fCanMethodHandleSeverity = FALSE; - -#ifndef DACCESS_COMPILE - CONTRACTL - { - GC_NOTRIGGER; - THROWS; - MODE_ANY; - PRECONDITION(pMethodDesc != NULL); - } - CONTRACTL_END; - - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return TRUE; - } - - // Since the method is Security Critical, now check if it is - // attributed to handle the CE or not. - IMDInternalImport *pImport = pMethodDesc->GetMDImport(); - if (pImport != NULL) - { - mdMethodDef methodDef = pMethodDesc->GetMemberDef(); - switch(severity) - { - case ProcessCorrupting: - fCanMethodHandleSeverity = (S_OK == pImport->GetCustomAttributeByName( - methodDef, - HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE, - NULL, - NULL)); - break; - default: - _ASSERTE(!"Unknown Exception Corruption Severity!"); - break; - } - } -#endif // !DACCESS_COMPILE - - return fCanMethodHandleSeverity; -} - -// Given a MethodDesc, this method will return a BOOL to indicate if the method should be examined for exception -// handlers for the specified exception. -// -// This method accounts for both corrupting and non-corrupting exceptions. -/* static */ -BOOL CEHelper::CanMethodHandleException(CorruptionSeverity severity, PTR_MethodDesc pMethodDesc) -{ - CONTRACTL - { - GC_NOTRIGGER; - THROWS; - MODE_ANY; - PRECONDITION(pMethodDesc != NULL); - } - CONTRACTL_END; - - // By default, assume that the runtime shouldn't look for exception handlers - // in the method pointed by the MethodDesc - BOOL fLookForExceptionHandlersInMethod = FALSE; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return TRUE; - } - - // If we have been asked to use the last active corruption severity (e.g. in cases of Reflection - // or COM interop), then retrieve it. - if (severity == UseLast) - { - LOG((LF_EH, LL_INFO100, "CEHelper::CanMethodHandleException - Using LastActiveExceptionCorruptionSeverity.\n")); - severity = GetThread()->GetExceptionState()->GetLastActiveExceptionCorruptionSeverity(); - } - - LOG((LF_EH, LL_INFO100, "CEHelper::CanMethodHandleException - Processing CorruptionSeverity: %d.\n", severity)); - - if (severity > NotCorrupting) - { - // If the method lies in an assembly built for pre-V4 runtime, allow the runtime - // to look for exception handler for the CE. - BOOL fIsMethodInPreV4Assembly = FALSE; - fIsMethodInPreV4Assembly = CEHelper::IsMethodInPreV4Assembly(pMethodDesc); - - if (!fIsMethodInPreV4Assembly) - { - // Method lies in an assembly built for V4 or later runtime. - LOG((LF_EH, LL_INFO100, "CEHelper::CanMethodHandleException - Method is in an assembly built for V4 or later runtime.\n")); - - // Depending upon the corruption severity of the exception, see if the - // method supports handling that. - LOG((LF_EH, LL_INFO100, "CEHelper::CanMethodHandleException - Exception is corrupting.\n")); - - // Check if the method can handle the severity specified in the exception object. - fLookForExceptionHandlersInMethod = CEHelper::CanMethodHandleCE(pMethodDesc, severity); - } - else - { - // Method is in a Pre-V4 assembly - allow it to be examined for processing the CE - fLookForExceptionHandlersInMethod = TRUE; - } - } - else - { - // Non-corrupting exceptions can continue to be delivered - fLookForExceptionHandlersInMethod = TRUE; - } - - return fLookForExceptionHandlersInMethod; -} - -// Given a managed exception object, this method will return a BOOL -// indicating if it corresponds to a ProcessCorruptedState exception -// or not. -/* static */ -BOOL CEHelper::IsProcessCorruptedStateException(OBJECTREF oThrowable) +BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, OBJECTREF throwable) { CONTRACTL { NOTHROW; GC_NOTRIGGER; MODE_COOPERATIVE; - PRECONDITION(oThrowable != NULL); } CONTRACTL_END; - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) + switch (dwExceptionCode) { + case STATUS_ACCESS_VIOLATION: + if (throwable != NULL && MscorlibBinder::IsException(throwable->GetMethodTable(), kNullReferenceException)) + return FALSE; + break; + case STATUS_STACK_OVERFLOW: + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_IN_PAGE_ERROR: + case EXCEPTION_INVALID_DISPOSITION: + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + case EXCEPTION_PRIV_INSTRUCTION: + case STATUS_UNWIND_CONSOLIDATE: + break; + default: return FALSE; } -#ifndef DACCESS_COMPILE - // If the throwable represents preallocated SO, then indicate it as a CSE - if (CLRException::GetPreallocatedStackOverflowException() == oThrowable) - { - return TRUE; - } -#endif // !DACCESS_COMPILE - - // Check if we have an exception tracker for this exception - // and if so, if it represents corrupting exception or not. - // Get the exception tracker for the current exception -#ifdef FEATURE_EH_FUNCLETS - PTR_ExceptionTracker pEHTracker = GetEHTrackerForException(oThrowable, NULL); -#elif TARGET_X86 - PTR_ExInfo pEHTracker = GetEHTrackerForException(oThrowable, NULL); -#else -#error Unsupported platform -#endif - - if (pEHTracker != NULL) - { - // Found the tracker for exception object - check if its CSE or not. - return (pEHTracker->GetCorruptionSeverity() == ProcessCorrupting); - } - - return FALSE; -} - -#ifdef FEATURE_EH_FUNCLETS -void CEHelper::SetupCorruptionSeverityForActiveExceptionInUnwindPass(Thread *pCurThread, PTR_ExceptionTracker pEHTracker, BOOL fIsFirstPass, - DWORD dwExceptionCode) -{ -#ifndef DACCESS_COMPILE - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(!fIsFirstPass); // This method should only be called during an unwind - PRECONDITION(pCurThread != NULL); - } - CONTRACTL_END; - - // - // - // Typically, exception tracker is created for an exception when the OS is in the first pass. - // However, it may be created during the 2nd pass under specific cases. Managed C++ provides - // such a scenario. In the following, stack grows left to right: - // - // CallDescrWorker -> ILStub1 -> -> UMThunkStub -> IL_Stub2 -> - // - // If a CSE exception goes unhandled from managed main, it will reach the OS. The [CRT in?] OS triggers - // unwind that results in invoking the personality routine of UMThunkStub, called UMThunkStubUnwindFrameChainHandler, - // that releases all exception trackers below it. Thus, the tracker for the CSE, which went unhandled, is also - // released. This detail is 64bit specific and the crux of this issue. - // - // Now, it is expected that by the time we are in the unwind pass, the corruption severity would have already been setup in the - // exception tracker and thread exception state (TES) as part of the first pass, and thus, are identical. - // - // However, for the scenario above, when the unwind continues and reaches ILStub1, its personality routine (which is ProcessCLRException) - // is invoked. It attempts to get the exception tracker corresponding to the exception. Since none exists, it creates a brand new one, - // which has the exception corruption severity as NotSet. - // - // During the stack walk, we know (from TES) that the active exception was a CSE, and thus, ILStub1 cannot handle the exception. Prior - // to bailing out, we assert that our data structures are intact by comparing the exception severity in TES with the one in the current - // exception tracker. Since the tracker was recreated, it had the severity as NotSet and this does not match the severity in TES. - // Thus, the assert fires. [This check is performed in ProcessManagedCallFrame.] - // - // To address such a case, if we have created a new exception tracker in the unwind (2nd) pass, then set its - // exception corruption severity to what the TES holds currently. This will maintain the same semantic as the case - // where new tracker is not created (for e.g. the exception was caught in Managed main). - // - // The exception is the scenario of code that uses longjmp to jump to a different context. Longjmp results in a raise - // of a new exception with the longjmp exception code (0x80000026) but with ExceptionFlags set indicating unwind. When this is - // seen by ProcessCLRException (64bit personality routine), it will create a new tracker in the 2nd pass. - // - // Longjmp outside an exceptional path does not interest us, but the one in the exceptional - // path would only happen when a method attributed to handle CSE invokes it. Thus, if the longjmp happened during the 2nd pass of a CSE, - // we want it to proceed (and thus, jump) as expected and not apply the CSE severity to the tracker - this is equivalent to - // a catch block that handles a CSE and then does a "throw new Exception();". The new exception raised is - // non-CSE in nature as well. - // - // http://www.nynaeve.net/?p=105 has a brief description of how exception-safe setjmp/longjmp works. - // - // - if (pEHTracker->GetCorruptionSeverity() == NotSet) - { - // Get the thread exception state - ThreadExceptionState *pCurTES = pCurThread->GetExceptionState(); - - // Set the tracker to have the same corruption severity as the last active severity unless we are dealing - // with LONGJMP - if (dwExceptionCode == STATUS_LONGJUMP) - { - pCurTES->SetLastActiveExceptionCorruptionSeverity(NotCorrupting); - } - - pEHTracker->SetCorruptionSeverity(pCurTES->GetLastActiveExceptionCorruptionSeverity()); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveExceptionInUnwindPass - Setup the corruption severity in the second pass.\n")); - } -#endif // !DACCESS_COMPILE -} -#endif // FEATURE_EH_FUNCLETS - -// This method is invoked from the personality routine for managed code and is used to setup the -// corruption severity for the active exception on the thread exception state and the -// exception tracker corresponding to the exception. -/* static */ -void CEHelper::SetupCorruptionSeverityForActiveException(BOOL fIsRethrownException, BOOL fIsNestedException, BOOL fShouldTreatExceptionAsNonCorrupting /* = FALSE */) -{ -#ifndef DACCESS_COMPILE - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - // Get the thread and the managed exception object - they must exist at this point - Thread *pCurThread = GetThread(); - _ASSERTE(pCurThread != NULL); - - OBJECTREF oThrowable = pCurThread->GetThrowable(); - _ASSERTE(oThrowable != NULL); - - // Get the thread exception state - ThreadExceptionState * pCurTES = pCurThread->GetExceptionState(); - _ASSERTE(pCurTES != NULL); - - // Get the exception tracker for the current exception -#ifdef FEATURE_EH_FUNCLETS - PTR_ExceptionTracker pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#elif TARGET_X86 - PTR_ExInfo pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#else // !(HOST_64BIT || TARGET_X86) -#error Unsupported platform -#endif // HOST_64BIT - - _ASSERTE(pEHTracker != NULL); - - // Get the current exception code from the tracker. - PEXCEPTION_RECORD pEHRecord = pCurTES->GetExceptionRecord(); - _ASSERTE(pEHRecord != NULL); - DWORD dwActiveExceptionCode = pEHRecord->ExceptionCode; - - if (pEHTracker->GetCorruptionSeverity() != NotSet) - { - // Since the exception tracker already has the corruption severity set, - // we dont have much to do. Just confirm that our assumptions are correct. - _ASSERTE(pEHTracker->GetCorruptionSeverity() == pCurTES->GetLastActiveExceptionCorruptionSeverity()); - - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Current tracker already has the corruption severity set.\n")); - return; - } - - // If the exception in question is to be treated as non-corrupting, - // then flag it and exit. - if (fShouldTreatExceptionAsNonCorrupting || g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - pEHTracker->SetCorruptionSeverity(NotCorrupting); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Exception treated as non-corrupting.\n")); - goto done; - } - - if (!fIsRethrownException && !fIsNestedException) - { - // There should be no previously active exception for this case - _ASSERTE(pEHTracker->GetPreviousExceptionTracker() == NULL); - - CorruptionSeverity severityTES = NotSet; - - if (pCurTES->ShouldLastActiveExceptionCorruptionSeverityBeReused()) - { - // Get the corruption severity from the ThreadExceptionState (TES) for the last active exception - severityTES = pCurTES->GetLastActiveExceptionCorruptionSeverity(); - - // Incase of scenarios like AD transition or Reflection invocation, - // TES would hold corruption severity of the last active exception. To propagate it - // to the current exception, we will apply it to current tracker and only if the applied - // severity is "NotSet", will we proceed to check the current exception for corruption - // severity. - pEHTracker->SetCorruptionSeverity(severityTES); - } - - // Reset TES Corruption Severity - pCurTES->SetLastActiveExceptionCorruptionSeverity(NotSet); - - if (severityTES == NotSet) - { - // Since the last active exception's severity was "NotSet", we will look up the - // exception code and the exception object to see if the exception should be marked - // corrupting. - // - // Since this exception was neither rethrown nor is nested, it implies that we are - // outside an active exception. Thus, even if it contains inner exceptions, we wont have - // corruption severity for them since that information is tracked in EH tracker and - // we wont have an EH tracker for the inner most exception. - - if (CEHelper::IsProcessCorruptedStateException(dwActiveExceptionCode) || - CEHelper::IsProcessCorruptedStateException(oThrowable)) - { - pEHTracker->SetCorruptionSeverity(ProcessCorrupting); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Marked non-rethrow/non-nested exception as ProcessCorrupting.\n")); - } - else - { - pEHTracker->SetCorruptionSeverity(NotCorrupting); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Marked non-rethrow/non-nested exception as NotCorrupting.\n")); - } - } - else - { - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Copied the corruption severity to tracker from ThreadExceptionState for non-rethrow/non-nested exception.\n")); - } - } - else - { - // Its either a rethrow or nested exception - -#ifdef FEATURE_EH_FUNCLETS - PTR_ExceptionTracker pOrigEHTracker = NULL; -#elif TARGET_X86 - PTR_ExInfo pOrigEHTracker = NULL; -#else -#error Unsupported platform -#endif - - BOOL fDoWeHaveCorruptionSeverity = FALSE; - - if (fIsRethrownException) - { - // Rethrown exceptions are nested by nature (of our implementation). The - // original EHTracker will exist for the exception - infact, it will be - // the tracker previous to the current one. We will simply copy - // its severity to the current EH tracker representing the rethrow. - pOrigEHTracker = pEHTracker->GetPreviousExceptionTracker(); - _ASSERTE(pOrigEHTracker != NULL); - - // Ideally, we would like have the assert below enabled. But, as may happen under OOM - // stress, this can be false. Here's how it will happen: - // - // An exception is thrown, which is later caught and rethrown in the catch block. Rethrow - // results in calling IL_Rethrow that will call RaiseTheExceptionInternalOnly to actually - // raise the exception. Prior to the raise, we update the last thrown object on the thread - // by calling Thread::SafeSetLastThrownObject which, internally, could have an OOM, resulting - // in "changing" the throwable used to raise the exception to be preallocated OOM object. - // - // When the rethrow happens and CLR's exception handler for managed code sees the exception, - // the exception tracker created for the rethrown exception will contain the reference to - // the last thrown object, which will be the preallocated OOM object. - // - // Thus, though, we came here because of a rethrow, and logically, the throwable should remain - // the same, it neednt be. Simply put, rethrow can result in working with a completely different - // exception object than what was originally thrown. - // - // Hence, the assert cannot be enabled. - // - // Thus, we will use the EH tracker corresponding to the original exception, to get the - // rethrown exception's corruption severity, only when the rethrown throwable is the same - // as the original throwable. Otherwise, we will pretend that we didnt get the original tracker - // and will automatically enter the path below to set the corruption severity based upon the - // rethrown throwable. - - // _ASSERTE(pOrigEHTracker->GetThrowable() == oThrowable); - if (pOrigEHTracker->GetThrowable() != oThrowable) - { - pOrigEHTracker = NULL; - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Rethrown throwable does not match the original throwable. Corruption severity will be set based upon rethrown throwable.\n")); - } - } - else - { - // Get the corruption severity from the ThreadExceptionState (TES) for the last active exception - CorruptionSeverity severityTES = NotSet; - - if (pCurTES->ShouldLastActiveExceptionCorruptionSeverityBeReused()) - { - severityTES = pCurTES->GetLastActiveExceptionCorruptionSeverity(); - - // Incase of scenarios like AD transition or Reflection invocation, - // TES would hold corruption severity of the last active exception. To propagate it - // to the current exception, we will apply it to current tracker and only if the applied - // severity is "NotSet", will we proceed to check the current exception for corruption - // severity. - pEHTracker->SetCorruptionSeverity(severityTES); - } - - // Reset TES Corruption Severity - pCurTES->SetLastActiveExceptionCorruptionSeverity(NotSet); - - // If the last exception didnt have any corruption severity, proceed to look for it. - if (severityTES == NotSet) - { - // This is a nested exception - check if it has an inner exception(s). If it does, - // find the EH tracker corresponding to the innermost exception and we will copy the - // corruption severity from the original tracker to the current one. - OBJECTREF oInnermostThrowable = ((EXCEPTIONREF)oThrowable)->GetBaseException(); - if (oInnermostThrowable != NULL) - { - // Find the tracker corresponding to the inner most exception, starting from - // the tracker previous to the current one. An EH tracker may not be found if - // the code did the following inside a catch clause: - // - // Exception ex = new Exception("inner exception"); - // throw new Exception("message", ex); - // - // Or, an exception like AV happened in the catch clause. - pOrigEHTracker = GetEHTrackerForException(oInnermostThrowable, pEHTracker->GetPreviousExceptionTracker()); - } - } - else - { - // We have the corruption severity from the TES. Set the flag indicating so. - fDoWeHaveCorruptionSeverity = TRUE; - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Copied the corruption severity to tracker from ThreadExceptionState for nested exception.\n")); - } - } - - if (!fDoWeHaveCorruptionSeverity) - { - if (pOrigEHTracker != NULL) - { - // Copy the severity from the original EH tracker to the current one - CorruptionSeverity origCorruptionSeverity = pOrigEHTracker->GetCorruptionSeverity(); - _ASSERTE(origCorruptionSeverity != NotSet); - pEHTracker->SetCorruptionSeverity(origCorruptionSeverity); - - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Copied the corruption severity (%d) from the original EH tracker for rethrown exception.\n", origCorruptionSeverity)); - } - else - { - if (CEHelper::IsProcessCorruptedStateException(dwActiveExceptionCode) || - CEHelper::IsProcessCorruptedStateException(oThrowable)) - { - pEHTracker->SetCorruptionSeverity(ProcessCorrupting); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Marked nested exception as ProcessCorrupting.\n")); - } - else - { - pEHTracker->SetCorruptionSeverity(NotCorrupting); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Marked nested exception as NotCorrupting.\n")); - } - } - } - } - -done: - // Save the current exception's corruption severity in the ThreadExceptionState (TES) - // for cases when we catch the managed exception in the runtime using EX_CATCH. - // At such a time, all exception trackers get released (due to unwind triggered - // by EX_END_CATCH) and yet we need the corruption severity information for - // scenarios like AD Transition, Reflection invocation, etc. - CorruptionSeverity currentSeverity = pEHTracker->GetCorruptionSeverity(); - - // We should be having a valid corruption severity at this point - _ASSERTE(currentSeverity != NotSet); - - // Save it in the TES - pCurTES->SetLastActiveExceptionCorruptionSeverity(currentSeverity); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Copied the corruption severity (%d) to ThreadExceptionState.\n", currentSeverity)); - -#endif // !DACCESS_COMPILE -} - -// CE can be caught in the VM and later reraised again. Examples of such scenarios -// include AD transition, COM interop, Reflection invocation, to name a few. -// In such cases, we want to mark the corruption severity for reuse upon reraise, -// implying that when the VM does a reraise of such an exception, we should use -// the original corruption severity for the new raised exception, instead of creating -// a new one for it. -/* static */ -void CEHelper::MarkLastActiveExceptionCorruptionSeverityForReraiseReuse() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(GetThread() != NULL); - } - CONTRACTL_END; - - // If the last active exception's corruption severity is anything but - // "NotSet", mark it for ReraiseReuse - ThreadExceptionState *pCurTES = GetThread()->GetExceptionState(); - _ASSERTE(pCurTES != NULL); - - CorruptionSeverity severityTES = pCurTES->GetLastActiveExceptionCorruptionSeverity(); - if (severityTES != NotSet) - { - pCurTES->SetLastActiveExceptionCorruptionSeverity((CorruptionSeverity)(severityTES | ReuseForReraise)); - } -} - -// This method will return a BOOL to indicate if the current exception is to be treated as -// non-corrupting. Currently, this returns true for NullReferenceException only. -/* static */ -BOOL CEHelper::ShouldTreatActiveExceptionAsNonCorrupting() -{ - BOOL fShouldTreatAsNonCorrupting = FALSE; - -#ifndef DACCESS_COMPILE - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(GetThread() != NULL); - } - CONTRACTL_END; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return TRUE; - } - - DWORD dwActiveExceptionCode = GetThread()->GetExceptionState()->GetExceptionRecord()->ExceptionCode; - if (dwActiveExceptionCode == STATUS_ACCESS_VIOLATION) - { - // NullReference has the same exception code as AV - OBJECTREF oThrowable = NULL; - GCPROTECT_BEGIN(oThrowable); - - // Get the throwable and check if it represents null reference exception - oThrowable = GetThread()->GetThrowable(); - _ASSERTE(oThrowable != NULL); - if (MscorlibBinder::GetException(kNullReferenceException) == oThrowable->GetMethodTable()) - { - fShouldTreatAsNonCorrupting = TRUE; - } - GCPROTECT_END(); - } -#endif // !DACCESS_COMPILE - - return fShouldTreatAsNonCorrupting; -} - -// If we were working in a nested exception scenario, reset the corruption severity to the last -// exception we were processing, based upon its EH tracker. -// -// If none was present, reset it to NotSet. -// -// Note: This method must be called once the exception trackers have been adjusted post catch-block execution. -/* static */ -void CEHelper::ResetLastActiveCorruptionSeverityPostCatchHandler(Thread *pThread) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(pThread != NULL); - } - CONTRACTL_END; - - ThreadExceptionState *pCurTES = pThread->GetExceptionState(); - - // By this time, we would have set the correct exception tracker for the active exception domain, - // if applicable. An example is throwing and catching an exception within a catch block. We will update - // the LastActiveCorruptionSeverity based upon the active exception domain. If we are not in one, we will - // set it to "NotSet". -#ifdef FEATURE_EH_FUNCLETS - PTR_ExceptionTracker pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#elif TARGET_X86 - PTR_ExInfo pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#else -#error Unsupported platform -#endif - - if (pEHTracker) - { - pCurTES->SetLastActiveExceptionCorruptionSeverity(pEHTracker->GetCorruptionSeverity()); - } - else - { - pCurTES->SetLastActiveExceptionCorruptionSeverity(NotSet); - } - - LOG((LF_EH, LL_INFO100, "CEHelper::ResetLastActiveCorruptionSeverityPostCatchHandler - Reset LastActiveException corruption severity to %d.\n", - pCurTES->GetLastActiveExceptionCorruptionSeverity())); -} - -// This method will return a BOOL indicating if the target of IDispatch can handle the specified exception or not. -/* static */ -BOOL CEHelper::CanIDispatchTargetHandleException() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(GetThread() != NULL); - } - CONTRACTL_END; - - // By default, assume that the target of IDispatch cannot handle the exception. - BOOL fCanMethodHandleException = FALSE; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return TRUE; - } - - // IDispatch implementation in COM interop works by invoking the actual target via reflection. - // Thus, a COM client could use the V4 runtime to invoke a V2 method. In such a case, a CSE - // could come unhandled at the actual target invoked via reflection. - // - // Reflection invocation would have set a flag for us, indicating if the actual target was - // enabled to handle the CE or not. If it is, then we should allow the COM client to get the - // hresult from the call and not let the exception continue up the stack. - ThreadExceptionState *pCurTES = GetThread()->GetExceptionState(); - fCanMethodHandleException = pCurTES->CanReflectionTargetHandleException(); - - // Reset the flag so that subsequent invocations work as expected. - pCurTES->SetCanReflectionTargetHandleException(FALSE); + if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_legacyCorruptedStateExceptionsPolicy)) + return FALSE; - return fCanMethodHandleException; + return TRUE; } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - #ifndef DACCESS_COMPILE // This method will deliver the actual exception notification. Its assumed that the caller has done the necessary checks, including // checking whether the delegate can be invoked for the exception's corruption severity. @@ -11964,7 +11092,7 @@ void ExceptionNotifications::GetEventArgsForNotification(ExceptionNotificationHa *pOutEventArgs = NULL; LOG((LF_EH, LL_INFO100, "ExceptionNotifications::GetEventArgsForNotification: Setting event args to NULL due to an exception.\n")); } - EX_END_CATCH(RethrowCorruptingExceptions); // Dont swallow any CSE that may come in from the .ctor. + EX_END_CATCH(RethrowTerminalExceptions); } // This SEH filter will be invoked when an exception escapes out of the exception notification @@ -11975,89 +11103,6 @@ static LONG ExceptionNotificationFilter(PEXCEPTION_POINTERS pExceptionInfo, LPVO return -1; } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -// This method will return a BOOL indicating if the delegate should be invoked for the exception -// of the specified corruption severity. -BOOL ExceptionNotifications::CanDelegateBeInvokedForException(OBJECTREF *pDelegate, CorruptionSeverity severity) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(pDelegate != NULL && IsProtectedByGCFrame(pDelegate) && (*pDelegate != NULL)); - PRECONDITION(severity > NotSet); - } - CONTRACTL_END; - - // Notifications for CSE are only delivered if the delegate target follows CSE rules. - BOOL fCanMethodHandleException = g_pConfig->LegacyCorruptedStateExceptionsPolicy() ? TRUE:(severity == NotCorrupting); - if (!fCanMethodHandleException) - { - EX_TRY - { - // Get the MethodDesc of the delegate to be invoked - MethodDesc *pMDDelegate = COMDelegate::GetMethodDesc(*pDelegate); - _ASSERTE(pMDDelegate != NULL); - - // Check the callback target and see if it is following CSE rules or not. - fCanMethodHandleException = CEHelper::CanMethodHandleException(severity, pMDDelegate); - } - EX_CATCH - { - // Incase of any exceptions, pretend we cannot handle the exception - fCanMethodHandleException = FALSE; - LOG((LF_EH, LL_INFO100, "ExceptionNotifications::CanDelegateBeInvokedForException: Exception while trying to determine if exception notification can be invoked or not.\n")); - } - EX_END_CATCH(RethrowCorruptingExceptions); // Dont swallow any CSEs. - } - - return fCanMethodHandleException; -} -#endif // FEATURE_CORRUPTING_EXCEPTIONS - -// This method will make the actual delegate invocation for the exception notification to be delivered. If an -// exception escapes out of the notification, our filter in ExceptionNotifications::DeliverNotification will -// address it. -void ExceptionNotifications::InvokeNotificationDelegate(ExceptionNotificationHandlerType notificationType, OBJECTREF *pDelegate, OBJECTREF *pEventArgs, - OBJECTREF *pAppDomain -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(pDelegate != NULL && IsProtectedByGCFrame(pDelegate) && (*pDelegate != NULL)); - PRECONDITION(pEventArgs != NULL && IsProtectedByGCFrame(pEventArgs)); - PRECONDITION(pAppDomain != NULL && IsProtectedByGCFrame(pAppDomain)); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - PRECONDITION(severity > NotSet); -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // Unhandled Exception Notification is delivered via Unhandled Exception Processing - // mechanism. - PRECONDITION(notificationType != UnhandledExceptionHandler); - } - CONTRACTL_END; - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Notifications are delivered based upon corruption severity of the exception - if (!ExceptionNotifications::CanDelegateBeInvokedForException(pDelegate, severity)) - { - LOG((LF_EH, LL_INFO100, "ExceptionNotifications::InvokeNotificationDelegate: Delegate cannot be invoked for corruption severity %d\n", - severity)); - return; - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - - // We've already exercised the prestub on this delegate's COMDelegate::GetMethodDesc, - // as part of wiring up a reliable event sink in the BCL. Deliver the notification. - ExceptionNotifications::DeliverExceptionNotification(notificationType, pDelegate, pAppDomain, pEventArgs); -} - // This method returns a BOOL to indicate if the AppDomain is ready to receive exception notifications or not. BOOL ExceptionNotifications::CanDeliverNotificationToCurrentAppDomain(ExceptionNotificationHandlerType notificationType) { @@ -12087,11 +11132,7 @@ BOOL ExceptionNotifications::CanDeliverNotificationToCurrentAppDomain(ExceptionN // so that if an exception escapes out of the notification callback, we will trigger failfast from // our filter. void ExceptionNotifications::DeliverNotification(ExceptionNotificationHandlerType notificationType, - OBJECTREF *pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ) + OBJECTREF *pThrowable) { STATIC_CONTRACT_GC_TRIGGERS; STATIC_CONTRACT_NOTHROW; // NOTHROW because incase of an exception, we will FailFast. @@ -12101,26 +11142,16 @@ void ExceptionNotifications::DeliverNotification(ExceptionNotificationHandlerTyp { ExceptionNotificationHandlerType notificationType; OBJECTREF *pThrowable; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - CorruptionSeverity severity; -#endif // FEATURE_CORRUPTING_EXCEPTIONS } args; args.notificationType = notificationType; args.pThrowable = pThrowable; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - args.severity = severity; -#endif // FEATURE_CORRUPTING_EXCEPTIONS PAL_TRY(TryArgs *, pArgs, &args) { // Make the call to the actual method that will invoke the callbacks ExceptionNotifications::DeliverNotificationInternal(pArgs->notificationType, - pArgs->pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , pArgs->severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + pArgs->pThrowable); } PAL_EXCEPT_FILTER(ExceptionNotificationFilter) { @@ -12134,11 +11165,7 @@ void ExceptionNotifications::DeliverNotification(ExceptionNotificationHandlerTyp // This method will deliver the exception notification to the current AppDomain. void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHandlerType notificationType, - OBJECTREF *pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ) + OBJECTREF *pThrowable) { CONTRACTL { @@ -12151,9 +11178,6 @@ void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHa PRECONDITION(notificationType != UnhandledExceptionHandler); PRECONDITION((pThrowable != NULL) && (*pThrowable != NULL)); PRECONDITION(ExceptionNotifications::CanDeliverNotificationToCurrentAppDomain(notificationType)); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - PRECONDITION(severity > NotSet); // Exception corruption severity must be valid at this point. -#endif // FEATURE_CORRUPTING_EXCEPTIONS } CONTRACTL_END; @@ -12220,12 +11244,7 @@ void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHa gc.arrDelegates = (PTRARRAYREF) ((DELEGATEREF)(gc.oNotificationDelegate))->GetInvocationList(); if (gc.arrDelegates == NULL || !gc.arrDelegates->GetMethodTable()->IsArray()) { - ExceptionNotifications::InvokeNotificationDelegate(notificationType, &gc.oNotificationDelegate, &gc.oEventArgs, - &gc.oCurAppDomain -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + ExceptionNotifications::DeliverExceptionNotification(notificationType, &gc.oNotificationDelegate, &gc.oCurAppDomain, &gc.oEventArgs); } else { @@ -12237,12 +11256,7 @@ void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHa for (UINT_PTR i=0; im_Array[i]; - ExceptionNotifications::InvokeNotificationDelegate(notificationType, &gc.oInnerDelegate, &gc.oEventArgs, - &gc.oCurAppDomain -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + ExceptionNotifications::DeliverExceptionNotification(notificationType, &gc.oInnerDelegate, &gc.oCurAppDomain, &gc.oEventArgs); } } } @@ -12282,11 +11296,7 @@ void ExceptionNotifications::DeliverFirstChanceNotification() oThrowable = pCurTES->GetThrowable(); _ASSERTE(oThrowable != NULL); - ExceptionNotifications::DeliverNotification(FirstChanceExceptionHandler, &oThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , pCurTES->GetCurrentExceptionTracker()->GetCorruptionSeverity() -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + ExceptionNotifications::DeliverNotification(FirstChanceExceptionHandler, &oThrowable); GCPROTECT_END(); } diff --git a/src/coreclr/src/vm/excep.h b/src/coreclr/src/vm/excep.h index c31ead4..661eefe 100644 --- a/src/coreclr/src/vm/excep.h +++ b/src/coreclr/src/vm/excep.h @@ -26,6 +26,8 @@ BOOL IsExceptionFromManagedCode(const EXCEPTION_RECORD * pExceptionRecord); BOOL IsIPinVirtualStub(PCODE f_IP); bool IsIPInMarkedJitHelper(UINT_PTR uControlPc); +BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, OBJECTREF throwable); + BOOL AdjustContextForJITHelpers(EXCEPTION_RECORD *pExceptionRecord, CONTEXT *pContext); #if defined(FEATURE_HIJACK) && (!defined(TARGET_X86) || defined(TARGET_UNIX)) @@ -70,8 +72,6 @@ struct ThrowCallbackType void * pPrevExceptionRecord; #endif - // Is the current exception a longjmp? - CORRUPTING_EXCEPTIONS_ONLY(BOOL m_fIsLongJump;) void Init() { LIMITED_METHOD_CONTRACT; @@ -92,8 +92,6 @@ struct ThrowCallbackType pCurrentExceptionRecord = 0; pPrevExceptionRecord = 0; #endif - // By default, the current exception is not a longjmp - CORRUPTING_EXCEPTIONS_ONLY(m_fIsLongJump = FALSE;) } }; @@ -251,11 +249,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowNonLocalized(RuntimeExceptionKind reKind, // Throw an object. //========================================================================== -VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity = NotCorrupting -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); +VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable); //========================================================================== // Throw an undecorated runtime exception. @@ -800,44 +794,6 @@ LONG ReflectionInvocationExceptionFilter( EXCEPTION_POINTERS *pExceptionInfo, // the pExceptionInfo passed to a filter function. PVOID pParam); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -// ----------------------------------------------------------------------- -// Support for Corrupted State Exceptions -// ----------------------------------------------------------------------- -#ifndef HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE -#define HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE "System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute" -#endif // HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE - -#ifndef HIGHEST_MAJOR_VERSION_OF_PREV4_RUNTIME -#define HIGHEST_MAJOR_VERSION_OF_PREV4_RUNTIME 2 -#endif // HIGHEST_MAJOR_VERSION_OF_PREV4_RUNTIME - -// This helper class contains static method to support working with Corrupted State Exceptions, -// including checking if a method can handle it or not, copy state across throwables, etc. -class CEHelper -{ - BOOL static IsMethodInPreV4Assembly(PTR_MethodDesc pMethodDesc); - BOOL static CanMethodHandleCE(PTR_MethodDesc pMethodDesc, CorruptionSeverity severity); - -public: - BOOL static CanMethodHandleException(CorruptionSeverity severity, PTR_MethodDesc pMethodDesc); - BOOL static CanIDispatchTargetHandleException(); - BOOL static IsProcessCorruptedStateException(DWORD dwExceptionCode, BOOL fCheckForSO = TRUE); - BOOL static IsProcessCorruptedStateException(OBJECTREF oThrowable); - BOOL static IsLastActiveExceptionCorrupting(BOOL fMarkForReuseIfCorrupting = FALSE); - BOOL static ShouldTreatActiveExceptionAsNonCorrupting(); - void static MarkLastActiveExceptionCorruptionSeverityForReraiseReuse(); - void static SetupCorruptionSeverityForActiveException(BOOL fIsRethrownException, BOOL fIsNestedException, BOOL fShouldTreatExceptionAsNonCorrupting = FALSE); -#ifdef FEATURE_EH_FUNCLETS - typedef DPTR(class ExceptionTracker) PTR_ExceptionTracker; - void static SetupCorruptionSeverityForActiveExceptionInUnwindPass(Thread *pCurThread, PTR_ExceptionTracker pEHTracker, BOOL fIsFirstPass, - DWORD dwExceptionCode); -#endif // FEATURE_EH_FUNCLETS - void static ResetLastActiveCorruptionSeverityPostCatchHandler(Thread *pThread); -}; - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - #ifndef DACCESS_COMPILE // exception filter invoked for unhandled exceptions on the entry point thread (thread 0) LONG EntryPointFilter(PEXCEPTION_POINTERS pExceptionInfo, PVOID _pData); @@ -860,36 +816,17 @@ private: OBJECTREF *pOutEventArgs, OBJECTREF *pThrowable); void static DeliverNotificationInternal(ExceptionNotificationHandlerType notificationType, - OBJECTREF *pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); - - void static InvokeNotificationDelegate(ExceptionNotificationHandlerType notificationType, OBJECTREF *pDelegate, OBJECTREF *pEventArgs, - OBJECTREF *pAppDomain -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + OBJECTREF *pThrowable); public: - BOOL static CanDeliverNotificationToCurrentAppDomain(ExceptionNotificationHandlerType notificationType); + void static DeliverExceptionNotification(ExceptionNotificationHandlerType notificationType, OBJECTREF *pDelegate, OBJECTREF *pEventArgs, + OBJECTREF *pAppDomain); - void static DeliverNotification(ExceptionNotificationHandlerType notificationType, - OBJECTREF *pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + BOOL static CanDeliverNotificationToCurrentAppDomain(ExceptionNotificationHandlerType notificationType); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - BOOL static CanDelegateBeInvokedForException(OBJECTREF *pDelegate, CorruptionSeverity severity); -#endif // FEATURE_CORRUPTING_EXCEPTIONS + void static DeliverNotification(ExceptionNotificationHandlerType notificationType, OBJECTREF *pThrowable); public: - void static DeliverExceptionNotification(ExceptionNotificationHandlerType notificationType, OBJECTREF *pDelegate, - OBJECTREF *pAppDomain, OBJECTREF *pEventArgs); void static DeliverFirstChanceNotification(); }; diff --git a/src/coreclr/src/vm/exceptionhandling.cpp b/src/coreclr/src/vm/exceptionhandling.cpp index 740678e..c655fe8 100644 --- a/src/coreclr/src/vm/exceptionhandling.cpp +++ b/src/coreclr/src/vm/exceptionhandling.cpp @@ -1006,23 +1006,13 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord !(dwExceptionFlags & EXCEPTION_UNWINDING), &STState); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Only setup the Corruption Severity in the first pass if (!(dwExceptionFlags & EXCEPTION_UNWINDING)) { // Switch to COOP mode GCX_COOP(); - if (pTracker && pTracker->GetThrowable() != NULL) - { - // Setup the state in current exception tracker indicating the corruption severity - // of the active exception. - CEHelper::SetupCorruptionSeverityForActiveException((STState == ExceptionTracker::STS_FirstRethrowFrame), (pTracker->GetPreviousExceptionTracker() != NULL), - CEHelper::ShouldTreatActiveExceptionAsNonCorrupting()); - } - // Failfast if exception indicates corrupted process state - if (pTracker->GetCorruptionSeverity() == ProcessCorrupting) + if (IsProcessCorruptedStateException(pExceptionRecord->ExceptionCode, pTracker->GetThrowable())) { OBJECTREF oThrowable = NULL; SString message; @@ -1045,7 +1035,6 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(pExceptionRecord->ExceptionCode, (LPCWSTR)message); } } -#endif // FEATURE_CORRUPTING_EXCEPTIONS #ifndef TARGET_UNIX // Watson is on Windows only // Setup bucketing details for nested exceptions (rethrow and non-rethrow) only if we are in the first pass @@ -2446,25 +2435,6 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame( if (fIsILStub && !fIsFunclet) // only make this callback on the main method body of IL stubs pUserMDForILStub = GetUserMethodForILStub(pThread, sf.SP, pMD, &pILStubFrame); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - BOOL fCanMethodHandleException = TRUE; - CorruptionSeverity currentSeverity = NotCorrupting; - { - // Switch to COOP mode since we are going to request throwable - GCX_COOP(); - - // We must defer to the MethodDesc of the user method instead of the IL stub - // itself because the user can specify the policy on a per-method basis and - // that won't be reflected via the IL stub's MethodDesc. - MethodDesc * pMDWithCEAttribute = (pUserMDForILStub != NULL) ? pUserMDForILStub : pMD; - - // Check if the exception can be delivered to the method? It will check if the exception - // is a CE or not. If it is, it will check if the method can process it or not. - currentSeverity = pThread->GetExceptionState()->GetCurrentExceptionTracker()->GetCorruptionSeverity(); - fCanMethodHandleException = CEHelper::CanMethodHandleException(currentSeverity, pMDWithCEAttribute); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // Doing rude abort. Skip all non-constrained execution region code. // When rude abort is initiated, we cannot intercept any exceptions. if (pThread->IsRudeAbortInitiated()) @@ -2673,27 +2643,7 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame( const METHODTOKEN& MethToken = pcfThisFrame->GetMethodToken(); EH_CLAUSE_ENUMERATOR EnumState; - unsigned EHCount; - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // The method cannot handle the exception (e.g. cannot handle the CE), then simply bail out - // without examining the EH clauses in it. - if (!fCanMethodHandleException) - { - LOG((LF_EH, LL_INFO100, "ProcessManagedCallFrame - CEHelper decided not to look for exception handlers in the method(MD:%p).\n", pMD)); - - // Set the flag to skip this frame since the CE cannot be delivered - _ASSERTE(currentSeverity == ProcessCorrupting); - - // Force EHClause count to be zero - EHCount = 0; - } - else -#endif // FEATURE_CORRUPTING_EXCEPTIONS - { - EHCount = pJitMan->InitializeEHEnumeration(MethToken, &EnumState); - } - + unsigned EHCount = pJitMan->InitializeEHEnumeration(MethToken, &EnumState); if (!fIsFirstPass) { @@ -3961,20 +3911,6 @@ ExceptionTracker* ExceptionTracker::GetOrCreateTracker( } } } - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - if (fCreateNewTracker) - { - // Exception tracker should be in the 2nd pass right now - _ASSERTE(!pTracker->IsInFirstPass()); - - // The corruption severity of a newly created tracker is NotSet - _ASSERTE(pTracker->GetCorruptionSeverity() == NotSet); - - // See comment in CEHelper::SetupCorruptionSeverityForActiveExceptionInUnwindPass for details - CEHelper::SetupCorruptionSeverityForActiveExceptionInUnwindPass(pThread, pTracker, FALSE, pExceptionRecord->ExceptionCode); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS } _ASSERTE(pTracker->m_pLimitFrame >= pThread->GetFrame()); @@ -4776,20 +4712,6 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHar ThreadExceptionState * pCurTES = pCurThread->GetExceptionState(); _ASSERTE(pCurTES != NULL); - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - ExceptionTracker* pEHTracker = pCurTES->GetCurrentExceptionTracker(); - if (pEHTracker == NULL) - { - CorruptionSeverity severity = NotCorrupting; - if (CEHelper::IsProcessCorruptedStateException(ex.GetExceptionRecord()->ExceptionCode)) - { - severity = ProcessCorrupting; - } - - pCurTES->SetLastActiveExceptionCorruptionSeverity(severity); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS } throw std::move(ex); diff --git a/src/coreclr/src/vm/exceptionhandling.h b/src/coreclr/src/vm/exceptionhandling.h index 2f56f20..dfdaf49 100644 --- a/src/coreclr/src/vm/exceptionhandling.h +++ b/src/coreclr/src/vm/exceptionhandling.h @@ -70,11 +70,6 @@ public: m_WatsonBucketTracker.Init(); #endif // !TARGET_UNIX -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Initialize the default exception severity to NotCorrupting - m_CorruptionSeverity = NotSet; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // By default, mark the tracker as not having delivered the first // chance exception notification m_fDeliveredFirstChanceNotification = FALSE; @@ -130,11 +125,6 @@ public: m_WatsonBucketTracker.Init(); #endif // !TARGET_UNIX -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Initialize the default exception severity to NotCorrupting - m_CorruptionSeverity = NotSet; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // By default, mark the tracker as not having delivered the first // chance exception notification m_fDeliveredFirstChanceNotification = FALSE; @@ -586,25 +576,6 @@ public: } #endif // !TARGET_UNIX -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -private: - CorruptionSeverity m_CorruptionSeverity; -public: - inline CorruptionSeverity GetCorruptionSeverity() - { - LIMITED_METHOD_CONTRACT; - - return (CorruptionSeverity)GET_CORRUPTION_SEVERITY(m_CorruptionSeverity); - } - - inline void SetCorruptionSeverity(CorruptionSeverity severityToSet) - { - LIMITED_METHOD_CONTRACT; - - m_CorruptionSeverity = severityToSet; - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - private: BOOL m_fDeliveredFirstChanceNotification; diff --git a/src/coreclr/src/vm/exceptmacros.h b/src/coreclr/src/vm/exceptmacros.h index 55bfec8..31fb8c7 100644 --- a/src/coreclr/src/vm/exceptmacros.h +++ b/src/coreclr/src/vm/exceptmacros.h @@ -246,38 +246,6 @@ LONG WINAPI CLRVectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo); // Actual UEF worker prototype for use by GCUnhandledExceptionFilter. extern LONG InternalUnhandledExceptionFilter_Worker(PEXCEPTION_POINTERS pExceptionInfo); -//========================================================================== -// Installs a handler to unwind exception frames, but not catch the exception -//========================================================================== - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -// ----------------------------------------------------------------------- -// Support for Corrupted State Exceptions -// ----------------------------------------------------------------------- -// This enumeration defines the corruption severity of an exception and -// whether it should be reused for the next exception thrown or not. -enum CorruptionSeverity -{ - UseLast = 0x0, // When specified, the last active corruption severity from TES should be used - NotSet = 0x1, // Corruption Severity has not been set - this is the default/reset value - NotCorrupting = 0x2, // Indicates exception is not corrupting - ProcessCorrupting = 0x4, // Indicates exception represents process corrupted state - ReuseForReraise = 0x2000 // Indicates that the corruption severity should be reused for the next exception thrown, - // provided its not nested and isnt a rethrow. This flag is used typically for propagation of - // severity across boundaries like Reflection invocation, AD transition etc. -}; - -#define GET_CORRUPTION_SEVERITY(severity) (((severity) & (~ReuseForReraise))) -#define CAN_REUSE_CORRUPTION_SEVERITY(severity) (((severity) & ReuseForReraise) == ReuseForReraise) - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - -VOID DECLSPEC_NORETURN RaiseTheException(OBJECTREF throwable, BOOL rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS -); - VOID DECLSPEC_NORETURN RaiseTheExceptionInternalOnly(OBJECTREF throwable, BOOL rethrow, BOOL fForStackOverflow = FALSE); #if defined(DACCESS_COMPILE) || defined(CROSSGEN_COMPILE) diff --git a/src/coreclr/src/vm/exinfo.cpp b/src/coreclr/src/vm/exinfo.cpp index 8a9ed80..58e353a 100644 --- a/src/coreclr/src/vm/exinfo.cpp +++ b/src/coreclr/src/vm/exinfo.cpp @@ -110,11 +110,6 @@ void ExInfo::Init() DestroyExceptionHandle(); m_hThrowable = NULL; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Initialize the default exception severity to NotCorrupting - m_CorruptionSeverity = NotSet; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // By default, mark the tracker as not having delivered the first // chance exception notification m_fDeliveredFirstChanceNotification = FALSE; diff --git a/src/coreclr/src/vm/exinfo.h b/src/coreclr/src/vm/exinfo.h index 5e57e0c..332d224 100644 --- a/src/coreclr/src/vm/exinfo.h +++ b/src/coreclr/src/vm/exinfo.h @@ -90,25 +90,6 @@ public: } #endif -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -private: - CorruptionSeverity m_CorruptionSeverity; -public: - inline CorruptionSeverity GetCorruptionSeverity() - { - LIMITED_METHOD_CONTRACT; - - return (CorruptionSeverity)GET_CORRUPTION_SEVERITY(m_CorruptionSeverity); - } - - inline void SetCorruptionSeverity(CorruptionSeverity severityToSet) - { - LIMITED_METHOD_CONTRACT; - - m_CorruptionSeverity = severityToSet; - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - private: BOOL m_fDeliveredFirstChanceNotification; public: diff --git a/src/coreclr/src/vm/exstate.cpp b/src/coreclr/src/vm/exstate.cpp index c2c2c0a..db238df 100644 --- a/src/coreclr/src/vm/exstate.cpp +++ b/src/coreclr/src/vm/exstate.cpp @@ -43,13 +43,6 @@ ThreadExceptionState::ThreadExceptionState() // Init the UE Watson BucketTracker m_UEWatsonBucketTracker.Init(); #endif // !TARGET_UNIX - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Initialize the default exception severity to NotCorrupting - m_LastActiveExceptionCorruptionSeverity = NotSet; - m_fCanReflectionTargetHandleException = FALSE; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - } ThreadExceptionState::~ThreadExceptionState() diff --git a/src/coreclr/src/vm/exstate.h b/src/coreclr/src/vm/exstate.h index 1ea8790..e3971d3 100644 --- a/src/coreclr/src/vm/exstate.h +++ b/src/coreclr/src/vm/exstate.h @@ -162,56 +162,6 @@ public: } #endif -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -private: - CorruptionSeverity m_LastActiveExceptionCorruptionSeverity; - BOOL m_fCanReflectionTargetHandleException; - -public: - // Returns the corruption severity of the last active exception - inline CorruptionSeverity GetLastActiveExceptionCorruptionSeverity() - { - LIMITED_METHOD_CONTRACT; - - return (CorruptionSeverity)GET_CORRUPTION_SEVERITY(m_LastActiveExceptionCorruptionSeverity); - } - - // Set the corruption severity of the last active exception - inline void SetLastActiveExceptionCorruptionSeverity(CorruptionSeverity severityToSet) - { - LIMITED_METHOD_CONTRACT; - - m_LastActiveExceptionCorruptionSeverity = severityToSet; - } - - // Returns a bool indicating if the last active exception's corruption severity should - // be used when exception is reraised (e.g. Reflection Invocation, AD transition, etc) - inline BOOL ShouldLastActiveExceptionCorruptionSeverityBeReused() - { - LIMITED_METHOD_CONTRACT; - - return CAN_REUSE_CORRUPTION_SEVERITY(m_LastActiveExceptionCorruptionSeverity); - } - - // Returns a BOOL to indicate if reflection target can handle CSE or not. - // This is used in DispatchInfo::CanIDispatchTargetHandleException. - inline BOOL CanReflectionTargetHandleException() - { - LIMITED_METHOD_CONTRACT; - - return m_fCanReflectionTargetHandleException; - } - - // Sets a BOOL indicate if the Reflection invocation target can handle exception or not. - // Used in ReflectionInvocation.cpp. - inline void SetCanReflectionTargetHandleException(BOOL fCanReflectionTargetHandleException) - { - LIMITED_METHOD_CONTRACT; - - m_fCanReflectionTargetHandleException = fCanReflectionTargetHandleException; - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - private: ThreadExceptionFlag m_flag; diff --git a/src/coreclr/src/vm/frames.h b/src/coreclr/src/vm/frames.h index 5c8a1ca..3437030 100644 --- a/src/coreclr/src/vm/frames.h +++ b/src/coreclr/src/vm/frames.h @@ -742,11 +742,7 @@ private: friend class StackFrameIterator; friend class TailCallFrame; friend class AppDomain; - friend VOID RealCOMPlusThrow(OBJECTREF -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + friend VOID RealCOMPlusThrow(OBJECTREF); friend FCDECL0(VOID, JIT_StressGC); #ifdef _DEBUG friend LONG WINAPI CLRVectoredExceptionHandlerShim(PEXCEPTION_POINTERS pExceptionInfo); diff --git a/src/coreclr/src/vm/i386/excepx86.cpp b/src/coreclr/src/vm/i386/excepx86.cpp index 5b333e9..a89e715 100644 --- a/src/coreclr/src/vm/i386/excepx86.cpp +++ b/src/coreclr/src/vm/i386/excepx86.cpp @@ -1065,18 +1065,11 @@ CPFH_RealFirstPassHandler( // ExceptionContinueSearch, etc. GCPROTECT_BEGIN(throwable); throwable = pThread->GetThrowable(); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS + if (IsProcessCorruptedStateException(exceptionCode, throwable)) { - // Setup the state in current exception tracker indicating the corruption severity - // of the active exception. - CEHelper::SetupCorruptionSeverityForActiveException(bRethrownException, bNestedException, - CEHelper::ShouldTreatActiveExceptionAsNonCorrupting()); - // Failfast if exception indicates corrupted process state - if (pExInfo->GetCorruptionSeverity() == ProcessCorrupting) - EEPOLICY_HANDLE_FATAL_ERROR(exceptionCode); + EEPOLICY_HANDLE_FATAL_ERROR(exceptionCode); } -#endif // FEATURE_CORRUPTING_EXCEPTIONS // If we're out of memory, then we figure there's probably not memory to maintain a stack trace, so we skip it. // If we've got a stack overflow, then we figure the stack will be so huge as to make tracking the stack trace @@ -1392,10 +1385,6 @@ CPFH_UnwindFrames1(Thread* pThread, EXCEPTION_REGISTRATION_RECORD* pEstablisherF tct.pTopFrame = GetCurrFrame(pEstablisherFrame); // highest frame to search to tct.pBottomFrame = NULL; - // Set the flag indicating if the current exception represents a longjmp. - // See comment in COMPlusUnwindCallback for details. - CORRUPTING_EXCEPTIONS_ONLY(tct.m_fIsLongJump = (exceptionCode == STATUS_LONGJUMP);) - #ifdef _DEBUG tct.pCurrentExceptionRecord = pEstablisherFrame; tct.pPrevExceptionRecord = GetPrevSEHRecord(pEstablisherFrame); @@ -2366,20 +2355,6 @@ StackWalkAction COMPlusThrowCallback( // SWA value if (fIsILStub) pUserMDForILStub = GetUserMethodForILStub(pThread, currentSP, pFunc, &pILStubFrame); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - CorruptionSeverity currentSeverity = pThread->GetExceptionState()->GetCurrentExceptionTracker()->GetCorruptionSeverity(); - { - // We must defer to the MethodDesc of the user method instead of the IL stub - // itself because the user can specify the policy on a per-method basis and - // that won't be reflected via the IL stub's MethodDesc. - MethodDesc * pMDWithCEAttribute = fIsILStub ? pUserMDForILStub : pFunc; - - // Check if the exception can be delivered to the method? It will check if the exception - // is a CE or not. If it is, it will check if the method can process it or not. - fMethodCanHandleException = CEHelper::CanMethodHandleException(currentSeverity, pMDWithCEAttribute); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // Let the profiler know that we are searching for a handler within this function instance if (fGiveDebuggerAndProfilerNotification) EEToProfilerExceptionInterfaceWrapper::ExceptionSearchFunctionEnter(pFunc); @@ -2406,29 +2381,12 @@ StackWalkAction COMPlusThrowCallback( // SWA value ExceptionNotifications::DeliverFirstChanceNotification(); } } + IJitManager* pJitManager = pCf->GetJitManager(); _ASSERTE(pJitManager); - EH_CLAUSE_ENUMERATOR pEnumState; - unsigned EHCount = 0; - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // If exception cannot be handled, then just bail out. We shouldnt examine the EH clauses - // in such a method. - if (!fMethodCanHandleException) - { - LOG((LF_EH, LL_INFO100, "COMPlusThrowCallback - CEHelper decided not to look for exception handlers in the method(MD:%p).\n", pFunc)); - // Set the flag to skip this frame since the CE cannot be delivered - _ASSERTE(currentSeverity == ProcessCorrupting); - - // Ensure EHClause count is zero - EHCount = 0; - } - else -#endif // FEATURE_CORRUPTING_EXCEPTIONS - { - EHCount = pJitManager->InitializeEHEnumeration(pCf->GetMethodToken(), &pEnumState); - } + EH_CLAUSE_ENUMERATOR pEnumState; + unsigned EHCount = pJitManager->InitializeEHEnumeration(pCf->GetMethodToken(), &pEnumState); if (EHCount == 0) { @@ -2708,59 +2666,6 @@ StackWalkAction COMPlusUnwindCallback (CrawlFrame *pCf, ThrowCallbackType *pData TypeHandle thrownType = TypeHandle(); - BOOL fCanMethodHandleException = TRUE; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // MethodDesc's security information (i.e. whether it is critical or transparent) is calculated lazily. - // If this method's security information was not precalculated, then it would have been in the first pass - // already using Security::IsMethodCritical which could take have taken us down a path which is GC_TRIGGERS. - // - // - // However, this unwind callback (for X86) is GC_NOTRIGGER and at this point the security information would have been - // calculated already. Hence, we wouldnt endup in the GC_TRIGGERS path. Thus, to keep SCAN.EXE (static contract analyzer) happy, - // we will pass a FALSE to the CanMethodHandleException call, indicating we dont need to calculate security information (and thus, - // not go down the GC_TRIGGERS path. - // - // Check if the exception can be delivered to the method? It will check if the exception - // is a CE or not. If it is, it will check if the method can process it or not. - CorruptionSeverity currentSeverity = pThread->GetExceptionState()->GetCurrentExceptionTracker()->GetCorruptionSeverity(); - - // We have to do this check for x86 since, unlike 64bit which will setup a new exception tracker for longjmp, - // x86 only sets up new trackers in the first pass (and longjmp is 2nd pass only exception). Hence, we pass - // this information in the callback structure without affecting any existing exception tracker (incase longjmp was - // a nested exception). - if (pData->m_fIsLongJump) - { - // Longjump is not a CSE. With a CSE in progress, this can be invoked by either: - // - // 1) Managed code (e.g. finally/fault/catch), OR - // 2) By native code - // - // In scenario (1), managed code can invoke it only if it was attributed with HPCSE attribute. Thus, - // longjmp is no different than managed code doing a "throw new Exception();". - // - // In scenario (2), longjmp is no different than any other non-CSE native exception raised. - // - // In both these case, longjmp should be treated as non-CSE. Since x86 does not setup a tracker for - // it (see comment above), we pass this information (of whether the current exception is a longjmp or not) - // to this callback (from UnwindFrames) to setup the correct corruption severity. - // - // http://www.nynaeve.net/?p=105 has a brief description of how exception-safe setjmp/longjmp works. - currentSeverity = NotCorrupting; - } - { - MethodDesc * pFuncWithCEAttribute = pFunc; - Frame * pILStubFrame = NULL; - if (pFunc->IsILStub()) - { - // We must defer to the MethodDesc of the user method instead of the IL stub - // itself because the user can specify the policy on a per-method basis and - // that won't be reflected via the IL stub's MethodDesc. - pFuncWithCEAttribute = GetUserMethodForILStub(pThread, (UINT_PTR)pStack, pFunc, &pILStubFrame); - } - fCanMethodHandleException = CEHelper::CanMethodHandleException(currentSeverity, pFuncWithCEAttribute); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - #ifdef DEBUGGING_SUPPORTED LOG((LF_EH, LL_INFO1000, "COMPlusUnwindCallback: Intercept %d, pData->pFunc 0x%X, pFunc 0x%X, pData->pStack 0x%X, pStack 0x%X\n", pExInfo->m_ExceptionFlags.DebuggerInterceptInfo(), @@ -2786,24 +2691,7 @@ StackWalkAction COMPlusUnwindCallback (CrawlFrame *pCf, ThrowCallbackType *pData EEToProfilerExceptionInterfaceWrapper::ExceptionUnwindFunctionEnter(pFunc); EH_CLAUSE_ENUMERATOR pEnumState; - unsigned EHCount; - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - if (!fCanMethodHandleException) - { - LOG((LF_EH, LL_INFO100, "COMPlusUnwindCallback - CEHelper decided not to look for exception handlers in the method(MD:%p).\n", pFunc)); - - // Set the flag to skip this frame since the CE cannot be delivered - _ASSERTE(currentSeverity == ProcessCorrupting); - - // Force EHClause count to be zero - EHCount = 0; - } - else -#endif // FEATURE_CORRUPTING_EXCEPTIONS - { - EHCount = pJitManager->InitializeEHEnumeration(pCf->GetMethodToken(), &pEnumState); - } + unsigned EHCount = pJitManager->InitializeEHEnumeration(pCf->GetMethodToken(), &pEnumState); if (EHCount == 0) { diff --git a/src/coreclr/src/vm/interopconverter.cpp b/src/coreclr/src/vm/interopconverter.cpp index 64312e1..2c67182 100644 --- a/src/coreclr/src/vm/interopconverter.cpp +++ b/src/coreclr/src/vm/interopconverter.cpp @@ -80,7 +80,7 @@ namespace //-------------------------------------------------------------------------------- // IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, ...) // Convert ObjectRef to a COM IP, based on MethodTable* pMT. -IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bSecurityCheck, BOOL bEnableCustomizedQueryInterface) +IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bEnableCustomizedQueryInterface) { CONTRACT (IUnknown*) { @@ -119,7 +119,6 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bSecuri CCWHolder pCCWHold = ComCallWrapper::InlineGetWrapper(poref); GetComIPFromCCW::flags flags = GetComIPFromCCW::None; - if (!bSecurityCheck) { flags |= GetComIPFromCCW::SuppressSecurityCheck; } if (!bEnableCustomizedQueryInterface) { flags |= GetComIPFromCCW::SuppressCustomizedQueryInterface; } pUnk = ComCallWrapper::GetComIPFromCCW(pCCWHold, GUID_NULL, pMT, flags); diff --git a/src/coreclr/src/vm/interopconverter.h b/src/coreclr/src/vm/interopconverter.h index ad6b9a0..a41c169 100644 --- a/src/coreclr/src/vm/interopconverter.h +++ b/src/coreclr/src/vm/interopconverter.h @@ -113,7 +113,7 @@ enum ComIpType //-------------------------------------------------------------------------------- // IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, ...); // Convert ObjectRef to a COM IP, based on MethodTable* pMT. -IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bSecurityCheck = TRUE, BOOL bEnableCustomizedQueryInterface = TRUE); +IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bEnableCustomizedQueryInterface = TRUE); //-------------------------------------------------------------------------------- diff --git a/src/coreclr/src/vm/jithelpers.cpp b/src/coreclr/src/vm/jithelpers.cpp index 8e5d20d..38a6af1 100644 --- a/src/coreclr/src/vm/jithelpers.cpp +++ b/src/coreclr/src/vm/jithelpers.cpp @@ -4185,23 +4185,6 @@ HCIMPL1(void, IL_Throw, Object* obj) } } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - if (!g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - // Within the VM, we could have thrown and caught a managed exception. This is done by - // RaiseTheException that will flag that exception's corruption severity to be used - // incase it leaks out to managed code. - // - // If it does not leak out, but ends up calling into managed code that throws, - // we will come here. In such a case, simply reset the corruption-severity - // since we want the exception being thrown to have its correct severity set - // when CLR's managed code exception handler sets it. - - ThreadExceptionState *pExState = GetThread()->GetExceptionState(); - pExState->SetLastActiveExceptionCorruptionSeverity(NotSet); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - RaiseTheExceptionInternalOnly(oref, FALSE); HELPER_METHOD_FRAME_END(); diff --git a/src/coreclr/src/vm/listlock.h b/src/coreclr/src/vm/listlock.h index 0fdaf6e..2b135b1 100644 --- a/src/coreclr/src/vm/listlock.h +++ b/src/coreclr/src/vm/listlock.h @@ -55,10 +55,6 @@ public: HRESULT m_hrResultCode; LOADERHANDLE m_hInitException; PTR_LoaderAllocator m_pLoaderAllocator; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Field to maintain the corruption severity of the exception - CorruptionSeverity m_CorruptionSeverity; -#endif // FEATURE_CORRUPTING_EXCEPTIONS ListLockEntryBase(List_t *pList, ELEMENT data, const char *description = NULL) : m_deadlock(description), @@ -72,10 +68,6 @@ public: m_hrResultCode(S_FALSE), m_hInitException(NULL), m_pLoaderAllocator(dac_cast(nullptr)) -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , - m_CorruptionSeverity(NotCorrupting) -#endif // FEATURE_CORRUPTING_EXCEPTIONS { WRAPPER_NO_CONTRACT; } diff --git a/src/coreclr/src/vm/marshalnative.cpp b/src/coreclr/src/vm/marshalnative.cpp index 5665794..2e06801 100644 --- a/src/coreclr/src/vm/marshalnative.cpp +++ b/src/coreclr/src/vm/marshalnative.cpp @@ -923,7 +923,7 @@ FCIMPL4(IUnknown*, MarshalNative::GetComInterfaceForObjectNative, Object* orefUN if (fOnlyInContext && !IsObjectInContext(&oref)) retVal = NULL; else - retVal = GetComIPFromObjectRef(&oref, th.GetMethodTable(), TRUE, bEnableCustomizedQueryInterface); + retVal = GetComIPFromObjectRef(&oref, th.GetMethodTable(), bEnableCustomizedQueryInterface); HELPER_METHOD_FRAME_END(); return retVal; diff --git a/src/coreclr/src/vm/methodtable.cpp b/src/coreclr/src/vm/methodtable.cpp index 1706f0c..6092551 100644 --- a/src/coreclr/src/vm/methodtable.cpp +++ b/src/coreclr/src/vm/methodtable.cpp @@ -3123,39 +3123,6 @@ BOOL MethodTable::RunClassInitEx(OBJECTREF *pThrowable) // a subclass of Error *pThrowable = GET_THROWABLE(); _ASSERTE(fRet == FALSE); - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // If active thread state does not have a CorruptionSeverity set for the exception, - // then set one up based upon the current exception code and/or the throwable. - // - // When can we be here and current exception tracker may not have corruption severity set? - // Incase of SO in managed code, SO is never seen by CLR's exception handler for managed code - // and if this happens in cctor, we can end up here without the corruption severity set. - Thread *pThread = GetThread(); - _ASSERTE(pThread != NULL); - ThreadExceptionState *pCurTES = pThread->GetExceptionState(); - _ASSERTE(pCurTES != NULL); - if (pCurTES->GetLastActiveExceptionCorruptionSeverity() == NotSet) - { - if (CEHelper::IsProcessCorruptedStateException(GetCurrentExceptionCode()) || - CEHelper::IsProcessCorruptedStateException(*pThrowable)) - { - // Process Corrupting - pCurTES->SetLastActiveExceptionCorruptionSeverity(ProcessCorrupting); - LOG((LF_EH, LL_INFO100, "MethodTable::RunClassInitEx - Exception treated as ProcessCorrupting.\n")); - } - else - { - // Not Corrupting - pCurTES->SetLastActiveExceptionCorruptionSeverity(NotCorrupting); - LOG((LF_EH, LL_INFO100, "MethodTable::RunClassInitEx - Exception treated as non-corrupting.\n")); - } - } - else - { - LOG((LF_EH, LL_INFO100, "MethodTable::RunClassInitEx - Exception already has corruption severity set.\n")); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS } EX_END_CATCH(SwallowAllExceptions) @@ -3289,17 +3256,7 @@ void MethodTable::DoRunClassInitThrowing() ((EXCEPTIONREF)(gc.pThrowable))->ClearStackTraceForThrow(); } - // - // Specify the corruption severity to be used to raise this exception in COMPlusThrow below. - // This will ensure that when the exception is seen by the managed code personality routine, - // it will setup the correct corruption severity in the exception tracker. - // - - COMPlusThrow(gc.pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , pEntry->m_CorruptionSeverity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + COMPlusThrow(gc.pThrowable); } description = ".cctor lock"; @@ -3389,21 +3346,7 @@ void MethodTable::DoRunClassInitThrowing() pEntry->m_hrResultCode = E_FAIL; SetClassInitError(); - #ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Save the corruption severity of the exception so that if the type system - // attempts to pick it up from its cache list and throw again, it should - // treat the exception as corrupting, if applicable. - pEntry->m_CorruptionSeverity = pThread->GetExceptionState()->GetLastActiveExceptionCorruptionSeverity(); - - // We should be having a valid corruption severity at this point - _ASSERTE(pEntry->m_CorruptionSeverity != NotSet); - #endif // FEATURE_CORRUPTING_EXCEPTIONS - - COMPlusThrow(gc.pThrowable - #ifdef FEATURE_CORRUPTING_EXCEPTIONS - , pEntry->m_CorruptionSeverity - #endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + COMPlusThrow(gc.pThrowable); } GCPROTECT_END(); diff --git a/src/coreclr/src/vm/rcwwalker.cpp b/src/coreclr/src/vm/rcwwalker.cpp index 5c94a3e..e10da3f 100644 --- a/src/coreclr/src/vm/rcwwalker.cpp +++ b/src/coreclr/src/vm/rcwwalker.cpp @@ -570,7 +570,7 @@ void RCWWalker::WalkRCWs() { hr = GET_EXCEPTION()->GetHR(); } - EX_END_CATCH(RethrowCorruptingExceptions) // Make sure we crash on AV (instead of swallowing everything) + EX_END_CATCH(RethrowTerminalExceptions) if (FAILED(hr)) { diff --git a/src/coreclr/src/vm/reflectioninvocation.cpp b/src/coreclr/src/vm/reflectioninvocation.cpp index 2724de4..b604b1a 100644 --- a/src/coreclr/src/vm/reflectioninvocation.cpp +++ b/src/coreclr/src/vm/reflectioninvocation.cpp @@ -882,15 +882,6 @@ void DECLSPEC_NORETURN ThrowInvokeMethodException(MethodDesc * pMethod, OBJECTRE } #endif // _DEBUG && !TARGET_UNIX -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Get the corruption severity of the exception that came in through reflection invocation. - CorruptionSeverity severity = GetThread()->GetExceptionState()->GetLastActiveExceptionCorruptionSeverity(); - - // Since we are dealing with an exception, set the flag indicating if the target of Reflection can handle exception or not. - // This flag is used in CEHelper::CanIDispatchTargetHandleException. - GetThread()->GetExceptionState()->SetCanReflectionTargetHandleException(CEHelper::CanMethodHandleException(severity, pMethod)); -#endif // FEATURE_CORRUPTING_EXCEPTIONS - OBJECTREF except = InvokeUtil::CreateTargetExcept(&targetException); #ifndef TARGET_UNIX @@ -944,11 +935,7 @@ void DECLSPEC_NORETURN ThrowInvokeMethodException(MethodDesc * pMethod, OBJECTRE // Since VM is throwing the exception, we set it to use the same corruption severity // that the original exception came in with from reflection invocation. - COMPlusThrow(except -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + COMPlusThrow(except); GCPROTECT_END(); } @@ -1254,12 +1241,6 @@ FCIMPL5(Object*, RuntimeMethodHandle::InvokeMethod, ENDFORBIDGC(); } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // By default, set the flag in TES indicating the reflection target can handle CSE. - // This flag is used in CEHelper::CanIDispatchTargetHandleException. - pThread->GetExceptionState()->SetCanReflectionTargetHandleException(TRUE); -#endif // FEATURE_CORRUPTING_EXCEPTIONS - if (pValueClasses != NULL) { pProtectValueClassFrame = new (_alloca (sizeof (FrameWithCookie))) diff --git a/src/coreclr/src/vm/stdinterfaces.cpp b/src/coreclr/src/vm/stdinterfaces.cpp index 7ca4975..240bdc9 100644 --- a/src/coreclr/src/vm/stdinterfaces.cpp +++ b/src/coreclr/src/vm/stdinterfaces.cpp @@ -1502,7 +1502,7 @@ InternalDispatchImpl_Invoke hr = pDispInfo->InvokeMember(pSimpleWrap, dispidMember, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, NULL, puArgErr); } - END_EXTERNAL_ENTRYPOINT_RETHROW_CORRUPTING_EXCEPTIONS; // This will ensure that entry points wont swallow CE and continue to let them propagate out. + END_EXTERNAL_ENTRYPOINT; return hr; } diff --git a/src/coreclr/src/vm/threads.cpp b/src/coreclr/src/vm/threads.cpp index 19b318e..324c65d 100644 --- a/src/coreclr/src/vm/threads.cpp +++ b/src/coreclr/src/vm/threads.cpp @@ -4500,17 +4500,6 @@ void Thread::SyncManagedExceptionState(bool fIsDebuggerThread) // Syncup the LastThrownObject on the managed thread SafeUpdateLastThrownObject(); } - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Since the catch clause has successfully executed and we are exiting it, reset the corruption severity - // in the ThreadExceptionState for the last active exception. This will ensure that when the next exception - // gets thrown/raised, EH tracker wont pick up an invalid value. - if (!fIsDebuggerThread) - { - CEHelper::ResetLastActiveCorruptionSeverityPostCatchHandler(this); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - } void Thread::SetLastThrownObjectHandle(OBJECTHANDLE h)