From d0c80e025ed180f7e3f27155b06289b1bd8f3997 Mon Sep 17 00:00:00 2001 From: danmosemsft Date: Fri, 10 Feb 2017 22:15:01 -0800 Subject: [PATCH] Revert "Remove always defined FEATURE_CORRUPTING_EXCEPTIONS" This reverts commit dotnet/coreclr@b0dab0d6de90a38dfbf0d6b2039a7b8f5269d802. Commit migrated from https://github.com/dotnet/coreclr/commit/87f8b67a4ee90ef807927f5083e237cb88b34725 --- src/coreclr/src/inc/ex.h | 11 ++++++ src/coreclr/src/inc/utilcode.h | 2 ++ src/coreclr/src/utilcode/util.cpp | 2 ++ src/coreclr/src/vm/callhelpers.cpp | 6 ++++ src/coreclr/src/vm/callhelpers.h | 2 ++ src/coreclr/src/vm/classfactory.cpp | 38 +++++++++++++++++++++ src/coreclr/src/vm/clrex.h | 2 ++ src/coreclr/src/vm/comdelegate.cpp | 2 +- src/coreclr/src/vm/crossdomaincalls.cpp | 6 ++++ src/coreclr/src/vm/eeconfig.cpp | 2 ++ src/coreclr/src/vm/eeconfig.h | 4 +++ src/coreclr/src/vm/excep.cpp | 50 ++++++++++++++++++++++++++++ src/coreclr/src/vm/excep.h | 12 +++++++ src/coreclr/src/vm/exceptionhandling.cpp | 10 ++++++ src/coreclr/src/vm/exceptionhandling.h | 6 ++++ src/coreclr/src/vm/exceptmacros.h | 4 +++ src/coreclr/src/vm/exinfo.cpp | 2 ++ src/coreclr/src/vm/exinfo.h | 2 ++ src/coreclr/src/vm/exstate.cpp | 2 ++ src/coreclr/src/vm/exstate.h | 2 ++ src/coreclr/src/vm/frames.h | 2 ++ src/coreclr/src/vm/i386/excepx86.cpp | 10 ++++++ src/coreclr/src/vm/jithelpers.cpp | 2 ++ src/coreclr/src/vm/listlock.cpp | 2 ++ src/coreclr/src/vm/listlock.h | 2 ++ src/coreclr/src/vm/methodtable.cpp | 8 +++++ src/coreclr/src/vm/namespace.h | 2 ++ src/coreclr/src/vm/reflectioninvocation.cpp | 6 ++++ src/coreclr/src/vm/stdinterfaces_wrapper.cpp | 6 ++++ src/coreclr/src/vm/threads.cpp | 6 ++++ src/coreclr/src/vm/util.hpp | 2 ++ 31 files changed, 214 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/inc/ex.h b/src/coreclr/src/inc/ex.h index 760aefa..80b9aa0 100644 --- a/src/coreclr/src/inc/ex.h +++ b/src/coreclr/src/inc/ex.h @@ -751,6 +751,7 @@ private: // ///////////////////////////////////////////////////////////////////// +#ifdef FEATURE_CORRUPTING_EXCEPTIONS #define CORRUPTING_EXCEPTIONS_ONLY(expr) expr #define COMMA_CORRUPTING_EXCEPTIONS_ONLY(expr) ,expr @@ -803,6 +804,16 @@ private: 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) diff --git a/src/coreclr/src/inc/utilcode.h b/src/coreclr/src/inc/utilcode.h index 3f70041..5394f1b 100644 --- a/src/coreclr/src/inc/utilcode.h +++ b/src/coreclr/src/inc/utilcode.h @@ -5145,10 +5145,12 @@ void OnUninitializedCoreClrCallbacks(); #endif //_DEBUG +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // Corrupting Exception limited support for outside the VM folder BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, BOOL fCheckForSO = TRUE); +#endif // FEATURE_CORRUPTING_EXCEPTIONS BOOL IsV2RuntimeLoaded(void); diff --git a/src/coreclr/src/utilcode/util.cpp b/src/coreclr/src/utilcode/util.cpp index 7cde4f7..67e353b 100644 --- a/src/coreclr/src/utilcode/util.cpp +++ b/src/coreclr/src/utilcode/util.cpp @@ -3362,6 +3362,7 @@ lDone: ; return param.fRet; } +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // To include definition of EXCEPTION_SOFTSO #include "corexcep.h" @@ -3411,6 +3412,7 @@ BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, BOOL fCheckForSO /* return fIsCorruptedStateException; } +#endif // FEATURE_CORRUPTING_EXCEPTIONS void EnableTerminationOnHeapCorruption() { diff --git a/src/coreclr/src/vm/callhelpers.cpp b/src/coreclr/src/vm/callhelpers.cpp index 0e0efb5..addd519 100644 --- a/src/coreclr/src/vm/callhelpers.cpp +++ b/src/coreclr/src/vm/callhelpers.cpp @@ -251,7 +251,9 @@ void DispatchCall( CallDescrData * pCallDescrData, OBJECTREF *pRefException, ContextTransitionFrame* pFrame /* = NULL */ +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , CorruptionSeverity *pSeverity /*= NULL*/ +#endif // FEATURE_CORRUPTING_EXCEPTIONS ) { CONTRACTL @@ -267,11 +269,13 @@ void DispatchCall( g_pDebugInterface->TraceCall((const BYTE *)pCallDescrData->pTarget); #endif // DEBUGGING_SUPPORTED +#ifdef FEATURE_CORRUPTING_EXCEPTIONS if (pSeverity != NULL) { // By default, assume any exception that comes out is NotCorrupting *pSeverity = NotCorrupting; } +#endif // FEATURE_CORRUPTING_EXCEPTIONS EX_TRY { @@ -283,11 +287,13 @@ void DispatchCall( { *pRefException = GET_THROWABLE(); +#ifdef FEATURE_CORRUPTING_EXCEPTIONS if (pSeverity != NULL) { // By default, assume any exception that comes out is NotCorrupting *pSeverity = GetThread()->GetExceptionState()->GetLastActiveExceptionCorruptionSeverity(); } +#endif // FEATURE_CORRUPTING_EXCEPTIONS } EX_END_CATCH(RethrowTransientExceptions); diff --git a/src/coreclr/src/vm/callhelpers.h b/src/coreclr/src/vm/callhelpers.h index 3175d9a..446105b 100644 --- a/src/coreclr/src/vm/callhelpers.h +++ b/src/coreclr/src/vm/callhelpers.h @@ -61,7 +61,9 @@ void DispatchCall( CallDescrData * pCallDescrData, OBJECTREF * pRefException, ContextTransitionFrame* pFrame = NULL +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , CorruptionSeverity * pSeverity = NULL +#endif // FEATURE_CORRUPTING_EXCEPTIONS ); // Helper for VM->managed calls with simple signatures. diff --git a/src/coreclr/src/vm/classfactory.cpp b/src/coreclr/src/vm/classfactory.cpp index e636c1a..9d60b5b 100644 --- a/src/coreclr/src/vm/classfactory.cpp +++ b/src/coreclr/src/vm/classfactory.cpp @@ -145,6 +145,7 @@ public: STDMETHODIMP CreateInstance(LPUNKNOWN punkOuter, REFIID riid, void** ppv) { HRESULT hr = S_OK; +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // SetupForComCallHR uses "SO_INTOLERANT_CODE_NOTHROW" to setup the SO-Intolerant transition // for COM Interop. However, "SO_INTOLERANT_CODE_NOTHROW" expects that no exception can escape // through this boundary but all it does is (in addition to checking that no exception has escaped it) @@ -155,10 +156,17 @@ public: // SO_INTOLERANT_CODE_NOTHROW and yet allow for CEs to escape through. Since there will be a corresponding // END_SO_INTOLERANT_CODE, the call is splitted into two parts: the Begin and End (see below). BeginSetupForComCallHRWithEscapingCorruptingExceptions(); +#else // !FEATURE_CORRUPTING_EXCEPTIONS + SetupForComCallHR(); +#endif // FEATURE_CORRUPTING_EXCEPTIONS CONTRACTL { +#ifdef FEATURE_CORRUPTING_EXCEPTIONS THROWS; // CSE can escape out of this function +#else // !FEATURE_CORRUPTING_EXCEPTIONS + NOTHROW; +#endif // FEATURE_CORRUPTING_EXCEPTIONS GC_TRIGGERS; MODE_PREEMPTIVE; SO_TOLERANT; @@ -175,7 +183,9 @@ public: hr = EEAllocateInstance(punkOuter, m_pMethodTable, m_hasLicensing, riid, TRUE, NULL, ppv); } +#ifdef FEATURE_CORRUPTING_EXCEPTIONS EndSetupForComCallHRWithEscapingCorruptingExceptions(); +#endif // FEATURE_CORRUPTING_EXCEPTIONS return hr; } @@ -204,6 +214,7 @@ public: { HRESULT hr = S_OK; +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // SetupForComCallHR uses "SO_INTOLERANT_CODE_NOTHROW" to setup the SO-Intolerant transition // for COM Interop. However, "SO_INTOLERANT_CODE_NOTHROW" expects that no exception can escape // through this boundary but all it does is (in addition to checking that no exception has escaped it) @@ -214,10 +225,17 @@ public: // SO_INTOLERANT_CODE_NOTHROW and yet allow for CEs to escape through. Since there will be a corresponding // END_SO_INTOLERANT_CODE, the call is splitted into two parts: the Begin and End (see below). BeginSetupForComCallHRWithEscapingCorruptingExceptions(); +#else // !FEATURE_CORRUPTING_EXCEPTIONS + SetupForComCallHR(); +#endif // FEATURE_CORRUPTING_EXCEPTIONS CONTRACTL { +#ifdef FEATURE_CORRUPTING_EXCEPTIONS THROWS; // CSE can escape out of this function +#else // !FEATURE_CORRUPTING_EXCEPTIONS + NOTHROW; +#endif // FEATURE_CORRUPTING_EXCEPTIONS GC_TRIGGERS; MODE_PREEMPTIVE; @@ -256,7 +274,9 @@ public: } done: ; +#ifdef FEATURE_CORRUPTING_EXCEPTIONS EndSetupForComCallHRWithEscapingCorruptingExceptions(); +#endif // FEATURE_CORRUPTING_EXCEPTIONS return hr; } @@ -265,6 +285,7 @@ done: ; { HRESULT hr = S_OK; +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // SetupForComCallHR uses "SO_INTOLERANT_CODE_NOTHROW" to setup the SO-Intolerant transition // for COM Interop. However, "SO_INTOLERANT_CODE_NOTHROW" expects that no exception can escape // through this boundary but all it does is (in addition to checking that no exception has escaped it) @@ -275,10 +296,17 @@ done: ; // SO_INTOLERANT_CODE_NOTHROW and yet allow for CEs to escape through. Since there will be a corresponding // END_SO_INTOLERANT_CODE, the call is splitted into two parts: the Begin and End (see below). BeginSetupForComCallHRWithEscapingCorruptingExceptions(); +#else // !FEATURE_CORRUPTING_EXCEPTIONS + SetupForComCallHR(); +#endif // FEATURE_CORRUPTING_EXCEPTIONS CONTRACTL { +#ifdef FEATURE_CORRUPTING_EXCEPTIONS THROWS; // CSE can escape out of this function +#else // !FEATURE_CORRUPTING_EXCEPTIONS + NOTHROW; +#endif // FEATURE_CORRUPTING_EXCEPTIONS GC_TRIGGERS; MODE_PREEMPTIVE; SO_TOLERANT; @@ -292,7 +320,9 @@ done: ; hr = EEAllocateInstance(punkOuter, m_pMethodTable, m_hasLicensing, riid, TRUE, NULL, ppv); } +#ifdef FEATURE_CORRUPTING_EXCEPTIONS EndSetupForComCallHRWithEscapingCorruptingExceptions(); +#endif // FEATURE_CORRUPTING_EXCEPTIONS return hr; } @@ -562,7 +592,11 @@ HRESULT STDMETHODCALLTYPE EEAllocateInstance(LPUNKNOWN pOuter, MethodTable* pMT, { CONTRACTL { +#ifdef FEATURE_CORRUPTING_EXCEPTIONS THROWS; // CSE can escape out of this function +#else // !FEATURE_CORRUPTING_EXCEPTIONS + NOTHROW; +#endif // FEATURE_CORRUPTING_EXCEPTIONS GC_TRIGGERS; MODE_PREEMPTIVE; SO_TOLERANT; @@ -584,16 +618,19 @@ HRESULT STDMETHODCALLTYPE EEAllocateInstance(LPUNKNOWN pOuter, MethodTable* pMT, HRESULT hr = S_OK; +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // Get the MethodDesc of the type being instantiated. Based upon it, // we will decide whether to rethrow a CSE or not in // END_EXTERNAL_ENTRYPOINT_RETHROW_CORRUPTING_EXCEPTIONS_EX below. PTR_MethodDesc pMDDefConst = NULL; BOOL fHasConstructor = FALSE; +#endif // FEATURE_CORRUPTING_EXCEPTIONS BEGIN_EXTERNAL_ENTRYPOINT(&hr) { GCX_COOP_THREAD_EXISTS(GET_THREAD()); +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // Get the MethodDesc of the type being instantiated. Based upon it, // we will decide whether to rethrow a CSE or not in // END_EXTERNAL_ENTRYPOINT_RETHROW_CORRUPTING_EXCEPTIONS_EX below. @@ -602,6 +639,7 @@ HRESULT STDMETHODCALLTYPE EEAllocateInstance(LPUNKNOWN pOuter, MethodTable* pMT, pMDDefConst = pMT->GetDefaultConstructor(); fHasConstructor = (pMDDefConst != NULL); } +#endif // FEATURE_CORRUPTING_EXCEPTIONS EEAllocateInstanceWorker(pOuter, pMT, fHasLicensing, riid, fDesignTime, bstrKey, ppv); } diff --git a/src/coreclr/src/vm/clrex.h b/src/coreclr/src/vm/clrex.h index c6935a1..02de452 100644 --- a/src/coreclr/src/vm/clrex.h +++ b/src/coreclr/src/vm/clrex.h @@ -762,6 +762,7 @@ 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. @@ -815,6 +816,7 @@ class EEFileLoadException : public EEException ((!__state.DidCatchSO()) && (!__state.DidCatchCxx()) && \ CEHelper::IsLastActiveExceptionCorrupting(TRUE)))) +#endif // FEATURE_CORRUPTING_EXCEPTIONS #undef EX_TRY #define EX_TRY \ diff --git a/src/coreclr/src/vm/comdelegate.cpp b/src/coreclr/src/vm/comdelegate.cpp index 987ab7f..f0799ad 100644 --- a/src/coreclr/src/vm/comdelegate.cpp +++ b/src/coreclr/src/vm/comdelegate.cpp @@ -3970,7 +3970,7 @@ static void InvokeUnhandledSwallowing(OBJECTREF *pDelegate, // specified would enable this change for builds that dont support // FEATURE_EXCEPTION_NOTIFICATIONS, like CoreCLR. We dont want that to happen // as well. -#if defined(FEATURE_EXCEPTION_NOTIFICATIONS) +#if defined(FEATURE_CORRUPTING_EXCEPTIONS) && defined(FEATURE_EXCEPTION_NOTIFICATIONS) BOOL fCanMethodHandleException = g_pConfig->LegacyCorruptedStateExceptionsPolicy(); if (!fCanMethodHandleException) { diff --git a/src/coreclr/src/vm/crossdomaincalls.cpp b/src/coreclr/src/vm/crossdomaincalls.cpp index 955e81e..b528915 100644 --- a/src/coreclr/src/vm/crossdomaincalls.cpp +++ b/src/coreclr/src/vm/crossdomaincalls.cpp @@ -1148,8 +1148,10 @@ CrossDomainChannel::BlitAndCall() } } +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // Assume that exception at server was NotCorrupting CorruptionSeverity severity = NotCorrupting; +#endif // FEATURE_CORRUPTING_EXCEPTIONS // Push the frame ENTER_DOMAIN_ID(m_pSrvDomain); @@ -1525,7 +1527,9 @@ struct MarshalAndCallArgs : public CtxTransitionBaseArgs UINT64 uRegTypeMap; #endif +#ifdef FEATURE_CORRUPTING_EXCEPTIONS CorruptionSeverity severity; +#endif // FEATURE_CORRUPTING_EXCEPTIONS }; // Simple wrapper to go from C to C++. @@ -2535,8 +2539,10 @@ CrossDomainChannel::MarshalAndCall() args.uRegTypeMap = *(UINT64*)pMap; #endif +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // By default assume that exception thrown across the cross-AD call is NotCorrupting. args.severity = NotCorrupting; +#endif // FEATURE_CORRUPTING_EXCEPTIONS MakeCallWithPossibleAppDomainTransition(m_pSrvDomain, (FPAPPDOMAINCALLBACK) MarshalAndCall_Wrapper2, &args); } diff --git a/src/coreclr/src/vm/eeconfig.cpp b/src/coreclr/src/vm/eeconfig.cpp index 9c170d9..4abfcc7 100644 --- a/src/coreclr/src/vm/eeconfig.cpp +++ b/src/coreclr/src/vm/eeconfig.cpp @@ -265,8 +265,10 @@ HRESULT EEConfig::Init() fNewComVTableLayout = false; iImpersonationPolicy = IMP_DEFAULT; +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // By default, there is not pre-V4 CSE policy fLegacyCorruptedStateExceptionsPolicy = false; +#endif // FEATURE_CORRUPTING_EXCEPTIONS #ifdef _DEBUG fLogTransparencyErrors = false; diff --git a/src/coreclr/src/vm/eeconfig.h b/src/coreclr/src/vm/eeconfig.h index eb6801f..8e21c44 100644 --- a/src/coreclr/src/vm/eeconfig.h +++ b/src/coreclr/src/vm/eeconfig.h @@ -315,8 +315,10 @@ public: bool LegacyComVTableLayout(void) const {LIMITED_METHOD_CONTRACT; return fLegacyComVTableLayout; } bool NewComVTableLayout(void) const {LIMITED_METHOD_CONTRACT; return fNewComVTableLayout; } +#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 // SECURITY unsigned ImpersonationMode(void) const @@ -906,7 +908,9 @@ private: //---------------------------------------------------------------- bool fLegacyUnhandledExceptionPolicy; // Old unhandled exception policy (many are swallowed) bool fLegacyVirtualMethodCallVerification; // Old (pre-whidbey) policy for call (nonvirt) of virtual function +#ifdef FEATURE_CORRUPTING_EXCEPTIONS bool fLegacyCorruptedStateExceptionsPolicy; +#endif // FEATURE_CORRUPTING_EXCEPTIONS bool fLegacyApartmentInitPolicy; // Old nondeterministic COM apartment initialization switch bool fLegacyComHierarchyVisibility; // Old behavior allowing QIs for classes with invisible parents diff --git a/src/coreclr/src/vm/excep.cpp b/src/coreclr/src/vm/excep.cpp index 8b863ce..3a4685e 100644 --- a/src/coreclr/src/vm/excep.cpp +++ b/src/coreclr/src/vm/excep.cpp @@ -162,7 +162,9 @@ 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 ); //------------------------------------------------------------------------------- @@ -2798,7 +2800,9 @@ LONG RaiseExceptionFilter(EXCEPTION_POINTERS* ep, LPVOID pv) // Throw an object. //========================================================================== VOID DECLSPEC_NORETURN RaiseTheException(OBJECTREF throwable, BOOL rethrow +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , CorruptionSeverity severity +#endif // FEATURE_CORRUPTING_EXCEPTIONS ) { STATIC_CONTRACT_THROWS; @@ -2830,6 +2834,7 @@ VOID DECLSPEC_NORETURN RaiseTheException(OBJECTREF throwable, BOOL rethrow _ASSERTE(throwable != CLRException::GetPreallocatedStackOverflowException()); #endif +#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. @@ -2879,6 +2884,7 @@ VOID DECLSPEC_NORETURN RaiseTheException(OBJECTREF throwable, BOOL rethrow LOG((LF_EH, LL_INFO100, "RaiseTheException - Set VM thrown managed exception severity to %d.\n", severity)); } +#endif // FEATURE_CORRUPTING_EXCEPTIONS RaiseTheExceptionInternalOnly(throwable,rethrow); } @@ -3120,7 +3126,9 @@ 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_CONTRACT_THROWS; STATIC_CONTRACT_GC_TRIGGERS; @@ -3149,14 +3157,18 @@ 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 ); UNINSTALL_COMPLUS_EXCEPTION_HANDLER(); } VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , CorruptionSeverity severity +#endif // FEATURE_CORRUPTING_EXCEPTIONS ) { STATIC_CONTRACT_THROWS; STATIC_CONTRACT_GC_TRIGGERS; @@ -3182,14 +3194,18 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow } RealCOMPlusThrowWorker(throwable, rethrow +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , severity +#endif // FEATURE_CORRUPTING_EXCEPTIONS ); GCPROTECT_END(); } VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , CorruptionSeverity severity +#endif // FEATURE_CORRUPTING_EXCEPTIONS ) { CONTRACTL @@ -3201,7 +3217,9 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable CONTRACTL_END; RealCOMPlusThrow(throwable, FALSE +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , severity +#endif // FEATURE_CORRUPTING_EXCEPTIONS ); } @@ -3924,11 +3942,13 @@ 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; @@ -8869,10 +8889,12 @@ LONG ReflectionInvocationExceptionFilter( #error Unsupported platform #endif // _WIN64 +#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; @@ -11395,6 +11417,7 @@ PTR_ExInfo GetEHTrackerForException(OBJECTREF oThrowable, PTR_ExInfo pStartingEH return fFoundTracker ? pEHTracker : NULL; } +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // ----------------------------------------------------------------------- // Support for CorruptedState Exceptions // ----------------------------------------------------------------------- @@ -12222,6 +12245,7 @@ BOOL CEHelper::CanIDispatchTargetHandleException() return fCanMethodHandleException; } +#endif // FEATURE_CORRUPTING_EXCEPTIONS #ifndef DACCESS_COMPILE // When a managed thread starts in non-default domain, its callstack looks like below: @@ -12584,6 +12608,7 @@ static LONG ExceptionNotificationFilter(PEXCEPTION_POINTERS pExceptionInfo, LPVO EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE); } +#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) @@ -12622,13 +12647,16 @@ BOOL ExceptionNotifications::CanDelegateBeInvokedForException(OBJECTREF *pDelega 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 @@ -12639,13 +12667,16 @@ void ExceptionNotifications::InvokeNotificationDelegate(ExceptionNotificationHan 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)) { @@ -12653,6 +12684,7 @@ void ExceptionNotifications::InvokeNotificationDelegate(ExceptionNotificationHan 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. @@ -12701,7 +12733,9 @@ BOOL ExceptionNotifications::CanDeliverNotificationToCurrentAppDomain(ExceptionN // our filter. void ExceptionNotifications::DeliverNotification(ExceptionNotificationHandlerType notificationType, OBJECTREF *pThrowable +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , CorruptionSeverity severity +#endif // FEATURE_CORRUPTING_EXCEPTIONS ) { STATIC_CONTRACT_GC_TRIGGERS; @@ -12712,19 +12746,25 @@ 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 ); } PAL_EXCEPT_FILTER(ExceptionNotificationFilter) @@ -12740,7 +12780,9 @@ 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 ) { CONTRACTL @@ -12754,7 +12796,9 @@ 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; @@ -12824,7 +12868,9 @@ void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHa { ExceptionNotifications::InvokeNotificationDelegate(notificationType, &gc.oNotificationDelegate, &gc.oEventArgs, &gc.oCurAppDomain +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , severity +#endif // FEATURE_CORRUPTING_EXCEPTIONS ); } else @@ -12839,7 +12885,9 @@ void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHa gc.oInnerDelegate = gc.arrDelegates->m_Array[i]; ExceptionNotifications::InvokeNotificationDelegate(notificationType, &gc.oInnerDelegate, &gc.oEventArgs, &gc.oCurAppDomain +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , severity +#endif // FEATURE_CORRUPTING_EXCEPTIONS ); } } @@ -12881,7 +12929,9 @@ void ExceptionNotifications::DeliverFirstChanceNotification() _ASSERTE(oThrowable != NULL); ExceptionNotifications::DeliverNotification(FirstChanceExceptionHandler, &oThrowable +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , pCurTES->GetCurrentExceptionTracker()->GetCorruptionSeverity() +#endif // FEATURE_CORRUPTING_EXCEPTIONS ); GCPROTECT_END(); diff --git a/src/coreclr/src/vm/excep.h b/src/coreclr/src/vm/excep.h index 5818de7..6057c55 100644 --- a/src/coreclr/src/vm/excep.h +++ b/src/coreclr/src/vm/excep.h @@ -268,7 +268,9 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowNonLocalized(RuntimeExceptionKind reKind, //========================================================================== VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , CorruptionSeverity severity = NotCorrupting +#endif // FEATURE_CORRUPTING_EXCEPTIONS ); //========================================================================== @@ -814,6 +816,7 @@ LONG ReflectionInvocationExceptionFilter( EXCEPTION_POINTERS *pExceptionInfo, // the pExceptionInfo passed to a filter function. PVOID pParam); +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // ----------------------------------------------------------------------- // Support for Corrupted State Exceptions // ----------------------------------------------------------------------- @@ -849,6 +852,7 @@ public: void static ResetLastActiveCorruptionSeverityPostCatchHandler(Thread *pThread); }; +#endif // FEATURE_CORRUPTING_EXCEPTIONS #ifndef DACCESS_COMPILE // Switches to the previous AppDomain on the thread. See implementation for detailed comments. @@ -903,12 +907,16 @@ private: 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 ); public: @@ -916,10 +924,14 @@ public: void static DeliverNotification(ExceptionNotificationHandlerType notificationType, OBJECTREF *pThrowable +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , CorruptionSeverity severity +#endif // FEATURE_CORRUPTING_EXCEPTIONS ); +#ifdef FEATURE_CORRUPTING_EXCEPTIONS BOOL static CanDelegateBeInvokedForException(OBJECTREF *pDelegate, CorruptionSeverity severity); +#endif // FEATURE_CORRUPTING_EXCEPTIONS #endif // FEATURE_EXCEPTION_NOTIFICATIONS public: diff --git a/src/coreclr/src/vm/exceptionhandling.cpp b/src/coreclr/src/vm/exceptionhandling.cpp index e48c648..63192a2 100644 --- a/src/coreclr/src/vm/exceptionhandling.cpp +++ b/src/coreclr/src/vm/exceptionhandling.cpp @@ -949,6 +949,7 @@ 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)) { @@ -963,6 +964,7 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord CEHelper::ShouldTreatActiveExceptionAsNonCorrupting()); } } +#endif // FEATURE_CORRUPTING_EXCEPTIONS { // Switch to COOP mode since we are going to work @@ -2378,6 +2380,7 @@ 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; { @@ -2394,6 +2397,7 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame( 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. @@ -2618,6 +2622,7 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame( 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) @@ -2631,6 +2636,7 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame( EHCount = 0; } else +#endif // FEATURE_CORRUPTING_EXCEPTIONS { EHCount = pJitMan->InitializeEHEnumeration(MethToken, &EnumState); } @@ -3884,6 +3890,7 @@ ExceptionTracker* ExceptionTracker::GetOrCreateTracker( } } +#ifdef FEATURE_CORRUPTING_EXCEPTIONS if (fCreateNewTracker) { // Exception tracker should be in the 2nd pass right now @@ -3895,6 +3902,7 @@ ExceptionTracker* ExceptionTracker::GetOrCreateTracker( // See comment in CEHelper::SetupCorruptionSeverityForActiveExceptionInUnwindPass for details CEHelper::SetupCorruptionSeverityForActiveExceptionInUnwindPass(pThread, pTracker, FALSE, pExceptionRecord->ExceptionCode); } +#endif // FEATURE_CORRUPTING_EXCEPTIONS } _ASSERTE(pTracker->m_pLimitFrame >= pThread->GetFrame()); @@ -4659,6 +4667,7 @@ 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) { @@ -4670,6 +4679,7 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHar 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 f10ddef..e324d28 100644 --- a/src/coreclr/src/vm/exceptionhandling.h +++ b/src/coreclr/src/vm/exceptionhandling.h @@ -80,8 +80,10 @@ public: m_WatsonBucketTracker.Init(); #endif // !FEATURE_PAL +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // Initialize the default exception severity to NotCorrupting m_CorruptionSeverity = NotSet; +#endif // FEATURE_CORRUPTING_EXCEPTIONS #ifdef FEATURE_EXCEPTION_NOTIFICATIONS // By default, mark the tracker as not having delivered the first @@ -140,8 +142,10 @@ public: m_WatsonBucketTracker.Init(); #endif // !FEATURE_PAL +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // Initialize the default exception severity to NotCorrupting m_CorruptionSeverity = NotSet; +#endif // FEATURE_CORRUPTING_EXCEPTIONS #ifdef FEATURE_EXCEPTION_NOTIFICATIONS // By default, mark the tracker as not having delivered the first @@ -593,6 +597,7 @@ public: } #endif // !FEATURE_PAL +#ifdef FEATURE_CORRUPTING_EXCEPTIONS private: CorruptionSeverity m_CorruptionSeverity; public: @@ -609,6 +614,7 @@ public: m_CorruptionSeverity = severityToSet; } +#endif // FEATURE_CORRUPTING_EXCEPTIONS #ifdef FEATURE_EXCEPTION_NOTIFICATIONS private: diff --git a/src/coreclr/src/vm/exceptmacros.h b/src/coreclr/src/vm/exceptmacros.h index f1c7e56..2af064c 100644 --- a/src/coreclr/src/vm/exceptmacros.h +++ b/src/coreclr/src/vm/exceptmacros.h @@ -254,6 +254,7 @@ extern LONG InternalUnhandledExceptionFilter_Worker(PEXCEPTION_POINTERS pExcepti // Installs a handler to unwind exception frames, but not catch the exception //========================================================================== +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // ----------------------------------------------------------------------- // Support for Corrupted State Exceptions // ----------------------------------------------------------------------- @@ -273,9 +274,12 @@ enum CorruptionSeverity #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); diff --git a/src/coreclr/src/vm/exinfo.cpp b/src/coreclr/src/vm/exinfo.cpp index 9e79111..1ae011e 100644 --- a/src/coreclr/src/vm/exinfo.cpp +++ b/src/coreclr/src/vm/exinfo.cpp @@ -113,8 +113,10 @@ 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 #ifdef FEATURE_EXCEPTION_NOTIFICATIONS // By default, mark the tracker as not having delivered the first diff --git a/src/coreclr/src/vm/exinfo.h b/src/coreclr/src/vm/exinfo.h index dcf1ce5..2a8030f 100644 --- a/src/coreclr/src/vm/exinfo.h +++ b/src/coreclr/src/vm/exinfo.h @@ -90,6 +90,7 @@ public: } #endif +#ifdef FEATURE_CORRUPTING_EXCEPTIONS private: CorruptionSeverity m_CorruptionSeverity; public: @@ -106,6 +107,7 @@ public: m_CorruptionSeverity = severityToSet; } +#endif // FEATURE_CORRUPTING_EXCEPTIONS #ifdef FEATURE_EXCEPTION_NOTIFICATIONS private: diff --git a/src/coreclr/src/vm/exstate.cpp b/src/coreclr/src/vm/exstate.cpp index 331fe06..29c7a06 100644 --- a/src/coreclr/src/vm/exstate.cpp +++ b/src/coreclr/src/vm/exstate.cpp @@ -44,9 +44,11 @@ ThreadExceptionState::ThreadExceptionState() m_UEWatsonBucketTracker.Init(); #endif // !FEATURE_PAL +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // Initialize the default exception severity to NotCorrupting m_LastActiveExceptionCorruptionSeverity = NotSet; m_fCanReflectionTargetHandleException = FALSE; +#endif // FEATURE_CORRUPTING_EXCEPTIONS } diff --git a/src/coreclr/src/vm/exstate.h b/src/coreclr/src/vm/exstate.h index 5b92fed..50e71ed 100644 --- a/src/coreclr/src/vm/exstate.h +++ b/src/coreclr/src/vm/exstate.h @@ -171,6 +171,7 @@ public: } #endif +#ifdef FEATURE_CORRUPTING_EXCEPTIONS private: CorruptionSeverity m_LastActiveExceptionCorruptionSeverity; BOOL m_fCanReflectionTargetHandleException; @@ -218,6 +219,7 @@ public: 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 1e45485..2c9ddb4 100644 --- a/src/coreclr/src/vm/frames.h +++ b/src/coreclr/src/vm/frames.h @@ -838,7 +838,9 @@ private: friend class TailCallFrame; friend class AppDomain; friend VOID RealCOMPlusThrow(OBJECTREF +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , CorruptionSeverity severity +#endif // FEATURE_CORRUPTING_EXCEPTIONS ); friend FCDECL0(VOID, JIT_StressGC); #ifdef _DEBUG diff --git a/src/coreclr/src/vm/i386/excepx86.cpp b/src/coreclr/src/vm/i386/excepx86.cpp index 8d17696..7c93963 100644 --- a/src/coreclr/src/vm/i386/excepx86.cpp +++ b/src/coreclr/src/vm/i386/excepx86.cpp @@ -1084,6 +1084,7 @@ CPFH_RealFirstPassHandler( // ExceptionContinueSearch, etc. GCPROTECT_BEGIN(throwable); throwable = pThread->GetThrowable(); +#ifdef FEATURE_CORRUPTING_EXCEPTIONS { BEGIN_SO_INTOLERANT_CODE(GetThread()); // Setup the state in current exception tracker indicating the corruption severity @@ -1092,6 +1093,7 @@ CPFH_RealFirstPassHandler( // ExceptionContinueSearch, etc. CEHelper::ShouldTreatActiveExceptionAsNonCorrupting()); END_SO_INTOLERANT_CODE; } +#endif // FEATURE_CORRUPTING_EXCEPTIONS // Check if we are dealing with AV or not and if we are, // ensure that this is a real AV and not managed AV exception @@ -2451,6 +2453,7 @@ 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 @@ -2462,6 +2465,7 @@ StackWalkAction COMPlusThrowCallback( // SWA value // 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) @@ -2496,6 +2500,7 @@ StackWalkAction COMPlusThrowCallback( // SWA value 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) @@ -2509,6 +2514,7 @@ StackWalkAction COMPlusThrowCallback( // SWA value EHCount = 0; } else +#endif // FEATURE_CORRUPTING_EXCEPTIONS { EHCount = pJitManager->InitializeEHEnumeration(pCf->GetMethodToken(), &pEnumState); } @@ -2794,6 +2800,7 @@ 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. @@ -2843,6 +2850,7 @@ StackWalkAction COMPlusUnwindCallback (CrawlFrame *pCf, ThrowCallbackType *pData } fCanMethodHandleException = CEHelper::CanMethodHandleException(currentSeverity, pFuncWithCEAttribute, FALSE); } +#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", @@ -2871,6 +2879,7 @@ StackWalkAction COMPlusUnwindCallback (CrawlFrame *pCf, ThrowCallbackType *pData 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)); @@ -2882,6 +2891,7 @@ StackWalkAction COMPlusUnwindCallback (CrawlFrame *pCf, ThrowCallbackType *pData EHCount = 0; } else +#endif // FEATURE_CORRUPTING_EXCEPTIONS { EHCount = pJitManager->InitializeEHEnumeration(pCf->GetMethodToken(), &pEnumState); } diff --git a/src/coreclr/src/vm/jithelpers.cpp b/src/coreclr/src/vm/jithelpers.cpp index c1b306f..6d4fd89 100644 --- a/src/coreclr/src/vm/jithelpers.cpp +++ b/src/coreclr/src/vm/jithelpers.cpp @@ -5427,6 +5427,7 @@ 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 @@ -5441,6 +5442,7 @@ HCIMPL1(void, IL_Throw, Object* obj) ThreadExceptionState *pExState = GetThread()->GetExceptionState(); pExState->SetLastActiveExceptionCorruptionSeverity(NotSet); } +#endif // FEATURE_CORRUPTING_EXCEPTIONS RaiseTheExceptionInternalOnly(oref, FALSE); diff --git a/src/coreclr/src/vm/listlock.cpp b/src/coreclr/src/vm/listlock.cpp index ce6f878..450e85a 100644 --- a/src/coreclr/src/vm/listlock.cpp +++ b/src/coreclr/src/vm/listlock.cpp @@ -27,8 +27,10 @@ ListLockEntry::ListLockEntry(ListLock *pList, void *pData, const char *descripti m_hrResultCode(S_FALSE), m_hInitException(NULL), m_pLoaderAllocator(NULL) +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , m_CorruptionSeverity(NotCorrupting) +#endif // FEATURE_CORRUPTING_EXCEPTIONS { WRAPPER_NO_CONTRACT; } diff --git a/src/coreclr/src/vm/listlock.h b/src/coreclr/src/vm/listlock.h index 2f4f967..e16741a 100644 --- a/src/coreclr/src/vm/listlock.h +++ b/src/coreclr/src/vm/listlock.h @@ -49,8 +49,10 @@ 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 ListLockEntry(ListLock *pList, void *pData, const char *description = NULL); diff --git a/src/coreclr/src/vm/methodtable.cpp b/src/coreclr/src/vm/methodtable.cpp index 00059b6..44f047e 100644 --- a/src/coreclr/src/vm/methodtable.cpp +++ b/src/coreclr/src/vm/methodtable.cpp @@ -3362,6 +3362,7 @@ BOOL MethodTable::RunClassInitEx(OBJECTREF *pThrowable) *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. // @@ -3392,6 +3393,7 @@ BOOL MethodTable::RunClassInitEx(OBJECTREF *pThrowable) { LOG((LF_EH, LL_INFO100, "MethodTable::RunClassInitEx - Exception already has corruption severity set.\n")); } +#endif // FEATURE_CORRUPTING_EXCEPTIONS } EX_END_CATCH(SwallowAllExceptions) @@ -3534,7 +3536,9 @@ void MethodTable::DoRunClassInitThrowing() // COMPlusThrow(gc.pThrowable +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , pEntry->m_CorruptionSeverity +#endif // FEATURE_CORRUPTING_EXCEPTIONS ); } @@ -3625,6 +3629,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. @@ -3632,9 +3637,12 @@ void MethodTable::DoRunClassInitThrowing() // 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 ); } diff --git a/src/coreclr/src/vm/namespace.h b/src/coreclr/src/vm/namespace.h index eb69aa9..e679fb5 100644 --- a/src/coreclr/src/vm/namespace.h +++ b/src/coreclr/src/vm/namespace.h @@ -74,7 +74,9 @@ #define g_WindowsFoundationDiagNS "Windows.Foundation.Diagnostics" +#if defined(FEATURE_CORRUPTING_EXCEPTIONS) || defined(FEATURE_EXCEPTION_NOTIFICATIONS) #define g_ExceptionServicesNS g_RuntimeNS ".ExceptionServices" +#endif // defined(FEATURE_CORRUPTING_EXCEPTION) || defined(FEATURE_EXCEPTION_NOTIFICATIONS) #if defined(FEATURE_HOST_ASSEMBLY_RESOLVER) #define g_LoaderNS g_RuntimeNS ".Loader" diff --git a/src/coreclr/src/vm/reflectioninvocation.cpp b/src/coreclr/src/vm/reflectioninvocation.cpp index c94fa8a..6311bdf 100644 --- a/src/coreclr/src/vm/reflectioninvocation.cpp +++ b/src/coreclr/src/vm/reflectioninvocation.cpp @@ -1121,12 +1121,14 @@ void DECLSPEC_NORETURN ThrowInvokeMethodException(MethodDesc * pMethod, OBJECTRE } #endif // _DEBUG && !FEATURE_PAL +#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); @@ -1182,7 +1184,9 @@ 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 ); GCPROTECT_END(); @@ -1497,9 +1501,11 @@ FCIMPL4(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) { diff --git a/src/coreclr/src/vm/stdinterfaces_wrapper.cpp b/src/coreclr/src/vm/stdinterfaces_wrapper.cpp index c5248ac..c33c330 100644 --- a/src/coreclr/src/vm/stdinterfaces_wrapper.cpp +++ b/src/coreclr/src/vm/stdinterfaces_wrapper.cpp @@ -1357,6 +1357,7 @@ HRESULT __stdcall Dispatch_Invoke_Wrapper(IDispatch* pDisp, DISPID dispidMember, { HRESULT hrRetVal = S_OK; +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // SetupForComCallHR uses "SO_INTOLERANT_CODE_NOTHROW" to setup the SO-Intolerant transition // for COM Interop. However, "SO_INTOLERANT_CODE_NOTHROW" expects that no exception can escape // through this boundary but all it does is (in addition to checking that no exception has escaped it) @@ -1367,6 +1368,9 @@ HRESULT __stdcall Dispatch_Invoke_Wrapper(IDispatch* pDisp, DISPID dispidMember, // SO_INTOLERANT_CODE_NOTHROW and yet allow for CEs to escape through. Since there will be a corresponding // END_SO_INTOLERANT_CODE, the call is splitted into two parts: the Begin and End (see below). BeginSetupForComCallHRWithEscapingCorruptingExceptions(); +#else // !FEATURE_CORRUPTING_EXCEPTIONS + SetupForComCallHR(); +#endif // FEATURE_CORRUPTING_EXCEPTIONS CONTRACTL @@ -1387,7 +1391,9 @@ HRESULT __stdcall Dispatch_Invoke_Wrapper(IDispatch* pDisp, DISPID dispidMember, pvarResult, pexcepinfo, puArgErr, &hrRetVal}; Dispatch_Invoke_CallBack(&args); +#ifdef FEATURE_CORRUPTING_EXCEPTIONS EndSetupForComCallHRWithEscapingCorruptingExceptions(); +#endif // FEATURE_CORRUPTING_EXCEPTIONS return hrRetVal; } diff --git a/src/coreclr/src/vm/threads.cpp b/src/coreclr/src/vm/threads.cpp index 1d03701..3c90c87 100644 --- a/src/coreclr/src/vm/threads.cpp +++ b/src/coreclr/src/vm/threads.cpp @@ -5400,6 +5400,7 @@ void Thread::SyncManagedExceptionState(bool fIsDebuggerThread) 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. @@ -5407,6 +5408,7 @@ void Thread::SyncManagedExceptionState(bool fIsDebuggerThread) { CEHelper::ResetLastActiveCorruptionSeverityPostCatchHandler(this); } +#endif // FEATURE_CORRUPTING_EXCEPTIONS } @@ -9123,12 +9125,14 @@ void DECLSPEC_NORETURN Thread::RaiseCrossContextException(Exception* pExOrig, Co ORBLOBREF orBlob = NULL; // Get the corruption severity for the exception caught at AppDomain transition boundary. +#ifdef FEATURE_CORRUPTING_EXCEPTIONS CorruptionSeverity severity = GetThread()->GetExceptionState()->GetLastActiveExceptionCorruptionSeverity(); if (severity == NotSet) { // No severity set at this point implies the exception was not corrupting severity = NotCorrupting; } +#endif // FEATURE_CORRUPTING_EXCEPTIONS #ifdef FEATURE_TESTHOOKS ADID adid=GetAppDomain()->GetId(); @@ -9245,7 +9249,9 @@ void DECLSPEC_NORETURN Thread::RaiseCrossContextException(Exception* pExOrig, Co // ... and throw it. VALIDATEOBJECTREF(gc.pMarshaledThrowable); COMPlusThrow(gc.pMarshaledThrowable +#ifdef FEATURE_CORRUPTING_EXCEPTIONS , severity +#endif // FEATURE_CORRUPTING_EXCEPTIONS ); GCPROTECT_END(); diff --git a/src/coreclr/src/vm/util.hpp b/src/coreclr/src/vm/util.hpp index 945e6db..4a213b7 100644 --- a/src/coreclr/src/vm/util.hpp +++ b/src/coreclr/src/vm/util.hpp @@ -899,6 +899,7 @@ ComCallHostNotificationHR() InternalSetupForComCall(HOST_E_CLRNOTAVAILABLE, E_OUTOFMEMORY, COR_E_STACKOVERFLOW, false) \ ComCallHostNotificationHR() +#ifdef FEATURE_CORRUPTING_EXCEPTIONS // Since Corrupting exceptions can escape COM interop boundaries, // these macros will be used to setup the initial SO-Intolerant transition. @@ -929,6 +930,7 @@ if (FAILED(__hr)) \ return __hr; \ } \ +#endif // FEATURE_CORRUPTING_EXCEPTIONS #define SetupForComCallDWORD() \ InternalSetupForComCall(-1, -1, -1, true) \ -- 2.7.4