[PSEH3]
authorJérôme Gardou <jerome.gardou@reactos.org>
Tue, 26 Aug 2014 21:35:21 +0000 (21:35 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Tue, 26 Aug 2014 21:35:21 +0000 (21:35 +0000)
 - 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

svn path=/trunk/; revision=63958

reactos/include/reactos/libs/pseh/pseh3.h
reactos/lib/pseh/i386/pseh3.c
reactos/lib/pseh/i386/pseh3_asmdef.h

index fee3b63..457d7d9 100644 (file)
@@ -64,6 +64,9 @@ typedef struct _SEH3$_REGISTRATION_FRAME
     /* Except handler stores pointer to exception pointers here */
     PSEH3$_EXCEPTION_POINTERS volatile ExceptionPointers;
 
     /* 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;
     unsigned long Ebp;
     /* Registers that we need to save */
     unsigned long Esp;
     unsigned long Ebp;
@@ -252,14 +255,14 @@ _SEH3$_AutoCleanup(
 
 /* Since we cannot use nested functions, we declare these globally as macros */
 #define _abnormal_termination() (_SEH3$_TrylevelFrame.ExceptionPointers != 0)
 
 /* 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)) \
 #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
 
 /* 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 @@ _SEH3$_AutoCleanup(
 _Pragma("GCC diagnostic push") \
 _Pragma("GCC diagnostic ignored \"-Wshadow\"") \
         inline __attribute__((always_inline, gnu_inline)) \
 _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") \
         inline __attribute__((always_inline, gnu_inline)) \
         void * _exception_info() { return _SEH3$_TrylevelFrame.ExceptionPointers; } \
 _Pragma("GCC diagnostic pop") \
index 9f20415..8a3be57 100644 (file)
@@ -197,8 +197,8 @@ _SEH3$_JumpToTarget(
     {
         asm volatile (
             /* Load the registers */
     {
         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"
 
             /* Stack pointer is 4 off from the call to __SEH3$_RegisterFrame */
             "addl $4, %%esp\n\t"
@@ -215,8 +215,8 @@ _SEH3$_JumpToTarget(
     {
         asm volatile (
             /* Load the registers */
     {
         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"
 
             /* Stack pointer is 4 off from the call to __SEH3$_RegisterFrame */
             "addl $4, %%esp\n\t"
@@ -274,8 +274,9 @@ _SEH3$_except_handler(
             /* Check if we have an exception handler */
             if (CurrentFrame->ScopeTable->Target != NULL)
             {
             /* 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->ExceptionPointers = &ExceptionPointers;
+                CurrentFrame->ExceptionCode = ExceptionRecord->ExceptionCode;
 
                 /* Get the filter result */
                 FilterResult = _SEH3$_GetFilterResult(CurrentFrame);
 
                 /* Get the filter result */
                 FilterResult = _SEH3$_GetFilterResult(CurrentFrame);
@@ -316,8 +317,9 @@ _SEH3$_except_handler(
         /* Check if this is an unwind frame */
         if (CurrentFrame->ScopeTable->Target == NULL)
         {
         /* 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->ExceptionPointers = &ExceptionPointers;
+            CurrentFrame->ExceptionCode = ExceptionRecord->ExceptionCode;
 
             /* Call the finally function */
             _SEH3$_CallFinally(CurrentFrame);
 
             /* Call the finally function */
             _SEH3$_CallFinally(CurrentFrame);
index 87d126f..74f7c83 100644 (file)
@@ -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_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
 
 #define SEH3_SCOPE_TABLE_Target 0
 #define SEH3_SCOPE_TABLE_Filter 4