Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFadi Hanna <fadim@microsoft.com>2018-08-09 00:00:20 +0300
committerFadi Hanna <fadim@microsoft.com>2018-08-09 00:00:20 +0300
commitd3edd098d9cdcf6162c25dca02cf5cf3c6da8562 (patch)
treeaacd3fa0d6b01b8ba69ab3973e4406afa89b9baf /src/Native
parent684bb89d4abeaf71a291414d0b960c2a333c4428 (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.S1
-rw-r--r--src/Native/Runtime/amd64/ExceptionHandling.asm1
-rw-r--r--src/Native/Runtime/arm/ExceptionHandling.S1
-rw-r--r--src/Native/Runtime/arm/ExceptionHandling.asm1
-rw-r--r--src/Native/Runtime/arm64/ExceptionHandling.asm1
-rw-r--r--src/Native/Runtime/i386/ExceptionHandling.asm1
-rw-r--r--src/Native/Runtime/thread.h4
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
{