From cc2df9ccf3183ab76fda534822660001a3018853 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Fri, 14 Jan 2022 17:07:20 +0100 Subject: [PATCH] Fix exception context leak in GC stress C The PAL_SEHException had the records allocated on stack, so the direct context restoration after the EH for GC stress C completed leaked those. --- .../pal/src/exception/machexception.cpp | 22 ++++++++++++++----- .../coreclr/GitHub_62058/test62058.cs | 2 +- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/coreclr/pal/src/exception/machexception.cpp b/src/coreclr/pal/src/exception/machexception.cpp index 5d3cd8846d952..eca89e0a204c6 100644 --- a/src/coreclr/pal/src/exception/machexception.cpp +++ b/src/coreclr/pal/src/exception/machexception.cpp @@ -373,19 +373,31 @@ void PAL_DispatchException(PCONTEXT pContext, PEXCEPTION_RECORD pExRecord, MachE g_hardware_exception_context_locvar_offset = (int)((char*)&contextRecord - (char*)__builtin_frame_address(0)); pContext->ContextFlags |= CONTEXT_EXCEPTION_ACTIVE; + bool continueExecution; + { + PAL_SEHException exception(pExRecord, pContext, true); - PAL_SEHException exception(pExRecord, pContext, true); + TRACE("PAL_DispatchException(EC %08x EA %p)\n", pExRecord->ExceptionCode, pExRecord->ExceptionAddress); - TRACE("PAL_DispatchException(EC %08x EA %p)\n", pExRecord->ExceptionCode, pExRecord->ExceptionAddress); + continueExecution = SEHProcessException(&exception); + if (continueExecution) + { + // Make a copy of the exception records so that we can free them before restoring the context + *pContext = *exception.ExceptionPointers.ContextRecord; + *pExRecord = *exception.ExceptionPointers.ExceptionRecord; + } + + // The exception records are destroyed by the PAL_SEHException destructor now. + } - if (SEHProcessException(&exception)) + if (continueExecution) { #if defined(HOST_ARM64) // RtlRestoreContext assembly corrupts X16 & X17, so it cannot be // used for GCStress=C restore - MachSetThreadContext(exception.ExceptionPointers.ContextRecord); + MachSetThreadContext(pContext); #else - RtlRestoreContext(exception.ExceptionPointers.ContextRecord, pExRecord); + RtlRestoreContext(pContext, pExRecord); #endif } diff --git a/src/tests/Regressions/coreclr/GitHub_62058/test62058.cs b/src/tests/Regressions/coreclr/GitHub_62058/test62058.cs index 3744007d9e45a..bffbf999e7396 100644 --- a/src/tests/Regressions/coreclr/GitHub_62058/test62058.cs +++ b/src/tests/Regressions/coreclr/GitHub_62058/test62058.cs @@ -41,7 +41,7 @@ public static void CatchRethrow(Action action) { Console.Out.WriteLine("catch"); Console.Out.Flush(); - throw new Exception("catch", e); // throw; doesn't work either + throw new Exception("catch", e); } }