diff options
author | Fadi Hanna <fadim@microsoft.com> | 2018-08-09 00:00:20 +0300 |
---|---|---|
committer | Fadi Hanna <fadim@microsoft.com> | 2018-08-09 00:00:20 +0300 |
commit | d3edd098d9cdcf6162c25dca02cf5cf3c6da8562 (patch) | |
tree | aacd3fa0d6b01b8ba69ab3973e4406afa89b9baf /src/Native | |
parent | 684bb89d4abeaf71a291414d0b960c2a333c4428 (diff) |
Fix for a GC hole bug with exception rethrowing code (Bug 659148).
The issue is that the RhpRethrow stubs do not initialize the values of m_kind for the ExInfo objects they allocate on stack. Depending on the kind of garbage that gets assigned to m_kind, the stack iterator either takes the code path of reporting the gcroots of the RhpRethrow callsite, or takes the code path with the RemapHardwareFaultToGCSafePoint (if m_kind ends up getting a HW exception flag).
The piece of code that initializes the m_kind field of the ExInfo object on rethrows is in ExceptionHandling.cs, and there’s a window of opportunity where GC collection can happen before m_kind gets initialized correctly.
The bug needs the following conditions to occur:
1) Garbage value in ExInfo.m_kind before initialization causes the stack iterator to take one code path, then after initialization take the other code path.
2) GC collection happens in the middle, before m_kind gets properly initialized
3) Gc roots reported in each of the 2 different code paths are different
4) The GC collection in step #2 causes a relocation of a reference object of interest.
The fix is to just initialize the field to something deterministic that makes sense (zero in that case). This would cause the stack iterator to use the gcroots reporting of the RhpRethrow callsite, until the field is initialized to a more meaningful value (ex: in case of a rethrow of a HW exception) where we would apply the correct algorithm to determine a more correct gcroots reporting point to use based on where execution is headed (ex: use the gcroots reporting point of a finally block if the rethrow is for a HW exception, and in a catch block)
[tfs-changeset: 1709684]
Diffstat (limited to 'src/Native')
-rw-r--r-- | src/Native/Runtime/amd64/ExceptionHandling.S | 1 | ||||
-rw-r--r-- | src/Native/Runtime/amd64/ExceptionHandling.asm | 1 | ||||
-rw-r--r-- | src/Native/Runtime/arm/ExceptionHandling.S | 1 | ||||
-rw-r--r-- | src/Native/Runtime/arm/ExceptionHandling.asm | 1 | ||||
-rw-r--r-- | src/Native/Runtime/arm64/ExceptionHandling.asm | 1 | ||||
-rw-r--r-- | src/Native/Runtime/i386/ExceptionHandling.asm | 1 | ||||
-rw-r--r-- | src/Native/Runtime/thread.h | 4 |
7 files changed, 9 insertions, 1 deletions
diff --git a/src/Native/Runtime/amd64/ExceptionHandling.S b/src/Native/Runtime/amd64/ExceptionHandling.S index fcf4dfbda..fa80c26ad 100644 --- a/src/Native/Runtime/amd64/ExceptionHandling.S +++ b/src/Native/Runtime/amd64/ExceptionHandling.S @@ -207,6 +207,7 @@ NESTED_ENTRY RhpRethrow, _TEXT, NoHandler mov [rsi + OFFSETOF__ExInfo__m_exception], rdx // init the exception object to null mov byte ptr [rsi + OFFSETOF__ExInfo__m_passNumber], 1 // init to the first pass mov dword ptr [rsi + OFFSETOF__ExInfo__m_idxCurClause], 0xFFFFFFFF + mov byte ptr [rsi + OFFSETOF__ExInfo__m_kind], 0 // init to a deterministic value (ExKind.None) // link the ExInfo into the thread's ExInfo chain diff --git a/src/Native/Runtime/amd64/ExceptionHandling.asm b/src/Native/Runtime/amd64/ExceptionHandling.asm index 566dad71f..b8727fc84 100644 --- a/src/Native/Runtime/amd64/ExceptionHandling.asm +++ b/src/Native/Runtime/amd64/ExceptionHandling.asm @@ -254,6 +254,7 @@ NESTED_ENTRY RhpRethrow, _TEXT mov [rdx + OFFSETOF__ExInfo__m_exception], r8 ;; init the exception object to null mov byte ptr [rdx + OFFSETOF__ExInfo__m_passNumber], 1 ;; init to the first pass mov dword ptr [rdx + OFFSETOF__ExInfo__m_idxCurClause], 0FFFFFFFFh + mov byte ptr [rdx + OFFSETOF__ExInfo__m_kind], 0 ;; init to a deterministic value (ExKind.None) ;; link the ExInfo into the thread's ExInfo chain diff --git a/src/Native/Runtime/arm/ExceptionHandling.S b/src/Native/Runtime/arm/ExceptionHandling.S index 19642c47d..3037905be 100644 --- a/src/Native/Runtime/arm/ExceptionHandling.S +++ b/src/Native/Runtime/arm/ExceptionHandling.S @@ -206,6 +206,7 @@ NESTED_ENTRY RhpRethrow, _TEXT, NoHandler mov r3, #0 str r3, [r1, #OFFSETOF__ExInfo__m_exception] // init the exception object to null + strb r3, [r1, #OFFSETOF__ExInfo__m_kind] // init to a deterministic value (ExKind.None) mov r3, #0xFFFFFFFF str r3, [r1, #OFFSETOF__ExInfo__m_idxCurClause] diff --git a/src/Native/Runtime/arm/ExceptionHandling.asm b/src/Native/Runtime/arm/ExceptionHandling.asm index bf21df089..39c29992a 100644 --- a/src/Native/Runtime/arm/ExceptionHandling.asm +++ b/src/Native/Runtime/arm/ExceptionHandling.asm @@ -211,6 +211,7 @@ NotHijacked add r1, sp, #rsp_offsetof_ExInfo ;; r1 <- ExInfo* mov r3, #0 str r3, [r1, #OFFSETOF__ExInfo__m_exception] ;; pExInfo->m_exception = null + strb r3, [r1, #OFFSETOF__ExInfo__m_kind] ;; init to a deterministic value (ExKind.None) mov r3, #1 strb r3, [r1, #OFFSETOF__ExInfo__m_passNumber] ;; pExInfo->m_passNumber = 1 mov r3, #0xFFFFFFFF diff --git a/src/Native/Runtime/arm64/ExceptionHandling.asm b/src/Native/Runtime/arm64/ExceptionHandling.asm index 35843afee..40d80ffa2 100644 --- a/src/Native/Runtime/arm64/ExceptionHandling.asm +++ b/src/Native/Runtime/arm64/ExceptionHandling.asm @@ -360,6 +360,7 @@ NotHijacked add x1, sp, #rsp_offsetof_ExInfo ;; x1 <- ExInfo* str xzr, [x1, #OFFSETOF__ExInfo__m_exception] ;; pExInfo->m_exception = null + strb xzr, [x1, #OFFSETOF__ExInfo__m_kind] ;; init to a deterministic value (ExKind.None) mov w3, #1 strb w3, [x1, #OFFSETOF__ExInfo__m_passNumber] ;; pExInfo->m_passNumber = 1 mov w3, #0xFFFFFFFF diff --git a/src/Native/Runtime/i386/ExceptionHandling.asm b/src/Native/Runtime/i386/ExceptionHandling.asm index 270cb2330..1981279ab 100644 --- a/src/Native/Runtime/i386/ExceptionHandling.asm +++ b/src/Native/Runtime/i386/ExceptionHandling.asm @@ -207,6 +207,7 @@ FASTCALL_FUNC RhpRethrow, 0 mov [edx + OFFSETOF__ExInfo__m_exception], esi ;; init the exception object to null mov byte ptr [edx + OFFSETOF__ExInfo__m_passNumber], 1 ;; init to the first pass mov dword ptr [edx + OFFSETOF__ExInfo__m_idxCurClause], 0FFFFFFFFh + mov byte ptr [edx + OFFSETOF__ExInfo__m_kind], 0 ;; init to a deterministic value (ExKind.None) ;; link the ExInfo into the thread's ExInfo chain mov ecx, [eax + OFFSETOF__Thread__m_pExInfoStackHead] ;; ecx <- currently active ExInfo diff --git a/src/Native/Runtime/thread.h b/src/Native/Runtime/thread.h index c3934c823..b2143c75d 100644 --- a/src/Native/Runtime/thread.h +++ b/src/Native/Runtime/thread.h @@ -46,7 +46,9 @@ struct ExInfo; typedef DPTR(ExInfo) PTR_ExInfo; -// also defined in ExceptionHandling.cs, layouts must match +// Also defined in ExceptionHandling.cs, layouts must match. +// When adding new fields to this struct, ensure they get properly initialized in the exception handling +// assembly stubs struct ExInfo { |