Author: jgardou
Date: Tue Aug 26 21:35:21 2014
New Revision: 63958
URL: http://svn.reactos.org/svn/reactos?rev=63958&view=rev
Log:
[PSEH3]
- Do not try to dereference potentially invalid pointers.
The FrameRegister->ExceptionPointers pointer is only valid in the context of the filter function. Indeed, the PSEH3 exception handler allocates it on the stack, and when control gets back to the __excep { } coder, ebp and esp were already restored to their original values, so whatever can happen to those pointers.
Investigation and debugging mastered by Thomas Faber, whose efforts were shamelessly stolen by me to improve my commit statistics.
CORE-8469 #comment patch committed, you may want to commit your testcase though :-p
Modified:
trunk/reactos/include/reactos/libs/pseh/pseh3.h
trunk/reactos/lib/pseh/i386/pseh3.c
trunk/reactos/lib/pseh/i386/pseh3_asmdef.h
Modified: trunk/reactos/include/reactos/libs/pseh/pseh3.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/pseh/…
==============================================================================
--- trunk/reactos/include/reactos/libs/pseh/pseh3.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/libs/pseh/pseh3.h [iso-8859-1] Tue Aug 26 21:35:21 2014
@@ -63,6 +63,9 @@
/* Except handler stores pointer to exception pointers here */
PSEH3$_EXCEPTION_POINTERS volatile ExceptionPointers;
+
+ /* Except handle stores the exception code here */
+ unsigned long ExceptionCode;
/* Registers that we need to save */
unsigned long Esp;
@@ -252,14 +255,14 @@
/* Since we cannot use nested functions, we declare these globally as macros */
#define _abnormal_termination() (_SEH3$_TrylevelFrame.ExceptionPointers != 0)
-#define _exception_code() (_SEH3$_TrylevelFrame.ExceptionPointers->ExceptionRecord->ExceptionCode)
+#define _exception_code() (_SEH3$_TrylevelFrame.ExceptionCode)
#define _exception_info() (_SEH3$_TrylevelFrame.ExceptionPointers)
#else /* __cplusplus || __clang__ */
#define _SEH3$_DECLARE_EXCEPT_INTRINSICS() \
inline __attribute__((always_inline, gnu_inline)) \
- unsigned long _exception_code() { return _SEH3$_TrylevelFrame.ExceptionPointers->ExceptionRecord->ExceptionCode; }
+ unsigned long _exception_code() { return _SEH3$_TrylevelFrame.ExceptionCode; }
/* On GCC the filter function is a nested function with __fastcall calling
convention. The eax register contains a base address the function uses
@@ -284,7 +287,7 @@
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wshadow\"") \
inline __attribute__((always_inline, gnu_inline)) \
- unsigned long _exception_code() { return _SEH3$_TrylevelFrame.ExceptionPointers->ExceptionRecord->ExceptionCode; } \
+ unsigned long _exception_code() { return _SEH3$_TrylevelFrame.ExceptionCode; } \
inline __attribute__((always_inline, gnu_inline)) \
void * _exception_info() { return _SEH3$_TrylevelFrame.ExceptionPointers; } \
_Pragma("GCC diagnostic pop") \
Modified: trunk/reactos/lib/pseh/i386/pseh3.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/pseh/i386/pseh3.c?rev=…
==============================================================================
--- trunk/reactos/lib/pseh/i386/pseh3.c [iso-8859-1] (original)
+++ trunk/reactos/lib/pseh/i386/pseh3.c [iso-8859-1] Tue Aug 26 21:35:21 2014
@@ -197,8 +197,8 @@
{
asm volatile (
/* Load the registers */
- "movl 20(%%ecx), %%esp\n\t"
- "movl 24(%%ecx), %%ebp\n\t"
+ "movl 24(%%ecx), %%esp\n\t"
+ "movl 28(%%ecx), %%ebp\n\t"
/* Stack pointer is 4 off from the call to __SEH3$_RegisterFrame */
"addl $4, %%esp\n\t"
@@ -215,8 +215,8 @@
{
asm volatile (
/* Load the registers */
- "movl 20(%%ecx), %%esp\n\t"
- "movl 24(%%ecx), %%ebp\n\t"
+ "movl 24(%%ecx), %%esp\n\t"
+ "movl 28(%%ecx), %%ebp\n\t"
/* Stack pointer is 4 off from the call to __SEH3$_RegisterFrame */
"addl $4, %%esp\n\t"
@@ -274,8 +274,9 @@
/* Check if we have an exception handler */
if (CurrentFrame->ScopeTable->Target != NULL)
{
- /* Set exception pointers for this frame */
+ /* Set exception pointers and code for this frame */
CurrentFrame->ExceptionPointers = &ExceptionPointers;
+ CurrentFrame->ExceptionCode = ExceptionRecord->ExceptionCode;
/* Get the filter result */
FilterResult = _SEH3$_GetFilterResult(CurrentFrame);
@@ -316,8 +317,9 @@
/* Check if this is an unwind frame */
if (CurrentFrame->ScopeTable->Target == NULL)
{
- /* Set exception pointers for this frame */
+ /* Set exception pointers and code for this frame */
CurrentFrame->ExceptionPointers = &ExceptionPointers;
+ CurrentFrame->ExceptionCode = ExceptionRecord->ExceptionCode;
/* Call the finally function */
_SEH3$_CallFinally(CurrentFrame);
Modified: trunk/reactos/lib/pseh/i386/pseh3_asmdef.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/pseh/i386/pseh3_asmdef…
==============================================================================
--- trunk/reactos/lib/pseh/i386/pseh3_asmdef.h [iso-8859-1] (original)
+++ trunk/reactos/lib/pseh/i386/pseh3_asmdef.h [iso-8859-1] Tue Aug 26 21:35:21 2014
@@ -5,12 +5,13 @@
#define SEH3_REGISTRATION_FRAME_EndOfChain 8
#define SEH3_REGISTRATION_FRAME_ScopeTable 12
#define SEH3_REGISTRATION_FRAME_ExceptionPointers 16
-#define SEH3_REGISTRATION_FRAME_Esp 20
-#define SEH3_REGISTRATION_FRAME_Ebp 24
-#define SEH3_REGISTRATION_FRAME_AllocaFrame 28
-#define SEH3_REGISTRATION_FRAME_Ebx 32
-#define SEH3_REGISTRATION_FRAME_Esi 36
-#define SEH3_REGISTRATION_FRAME_Edi 40
+#define SEH3_REGISTRATION_FRAME_ExceptionCode 20
+#define SEH3_REGISTRATION_FRAME_Esp 24
+#define SEH3_REGISTRATION_FRAME_Ebp 28
+#define SEH3_REGISTRATION_FRAME_AllocaFrame 32
+#define SEH3_REGISTRATION_FRAME_Ebx 36
+#define SEH3_REGISTRATION_FRAME_Esi 40
+#define SEH3_REGISTRATION_FRAME_Edi 44
#define SEH3_SCOPE_TABLE_Target 0
#define SEH3_SCOPE_TABLE_Filter 4