summaryrefslogtreecommitdiff
path: root/packaging/0028-Do-not-allocate-exception-for-signal-from-non-manage.patch
blob: e313dab7646c90ffa2ca3605edaaaa788e8f88d8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
From 88c5af565882264c129816bdba94fed25c83f2de Mon Sep 17 00:00:00 2001
From: Mikhail Labiuk <m.labiuk@samsung.com>
Date: Mon, 19 Feb 2018 18:56:15 +0300
Subject: [PATCH 28/47] Do not allocate exception for signal from non managed
 code

If the signal occurs in not managed code we cannot use heap.
We should call signal-safe functions only from signal handler.

Create exception object on stack for checking source of signal.
If signal is from managed code we can use memory allocation to create
persistent exception on heap as copy of volatile exception on stack.

If signal from unmanaged code we do nothing and call base signal handler.

fix https://github.com/dotnet/coreclr/issues/16338
---
 src/pal/inc/pal.h                |  5 ++++-
 src/pal/src/exception/seh.cpp    | 23 +++++++++++++++++++++++
 src/pal/src/exception/signal.cpp | 30 +++++++++++++++---------------
 3 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h
index 0a00b67..e3bfa40 100644
--- a/src/pal/inc/pal.h
+++ b/src/pal/inc/pal.h
@@ -3888,6 +3888,8 @@ PAL_BindResources(IN LPCSTR lpDomain);
 
 #define EXCEPTION_IS_SIGNAL 0x100
 
+#define EXCEPTION_ON_STACK 0x400
+
 #define EXCEPTION_MAXIMUM_PARAMETERS 15
 
 // Index in the ExceptionInformation array where we will keep the reference
@@ -5814,7 +5816,8 @@ private:
 
     void FreeRecords()
     {
-        if (ExceptionPointers.ExceptionRecord != NULL)
+        if (ExceptionPointers.ExceptionRecord != NULL &&
+            ! (ExceptionPointers.ExceptionRecord->ExceptionFlags | EXCEPTION_ON_STACK) )
         {
             PAL_FreeExceptionRecords(ExceptionPointers.ExceptionRecord, ExceptionPointers.ContextRecord);
             ExceptionPointers.ExceptionRecord = NULL;
diff --git a/src/pal/src/exception/seh.cpp b/src/pal/src/exception/seh.cpp
index 0574fad..a7d4ad9 100644
--- a/src/pal/src/exception/seh.cpp
+++ b/src/pal/src/exception/seh.cpp
@@ -232,6 +232,23 @@ void ThrowExceptionHelper(PAL_SEHException* ex)
     throw std::move(*ex);
 }
 
+static PAL_SEHException copyPAL_SEHException(PAL_SEHException* src)
+{
+    CONTEXT* contextRecord = src->GetContextRecord();
+    EXCEPTION_RECORD* exceptionRecord = src->GetExceptionRecord();
+
+    CONTEXT* contextRecordCopy;
+    EXCEPTION_RECORD* exceptionRecordCopy;
+    AllocateExceptionRecords(&exceptionRecordCopy, &contextRecordCopy);
+
+    *exceptionRecordCopy = *exceptionRecord;
+    exceptionRecordCopy->ExceptionFlags &= ~EXCEPTION_ON_STACK;
+    *contextRecordCopy = *contextRecord;
+    return PAL_SEHException(exceptionRecordCopy, contextRecordCopy);
+} 
+
+
+
 /*++
 Function:
     SEHProcessException
@@ -279,6 +296,9 @@ SEHProcessException(PAL_SEHException* exception)
                         PROCAbort();
                     }
                 }
+                
+                if(exceptionRecord->ExceptionFlags | EXCEPTION_ON_STACK)
+                    *exception = copyPAL_SEHException(exception);
 
                 if (g_hardwareExceptionHandler(exception))
                 {
@@ -292,6 +312,9 @@ SEHProcessException(PAL_SEHException* exception)
 
         if (CatchHardwareExceptionHolder::IsEnabled())
         {
+            if(exceptionRecord->ExceptionFlags | EXCEPTION_ON_STACK)
+                *exception = copyPAL_SEHException(exception);
+
             PAL_ThrowExceptionFromContext(exception->GetContextRecord(), exception);
         }
     }
diff --git a/src/pal/src/exception/signal.cpp b/src/pal/src/exception/signal.cpp
index bf48619..d42ba38 100644
--- a/src/pal/src/exception/signal.cpp
+++ b/src/pal/src/exception/signal.cpp
@@ -801,32 +801,32 @@ static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext
 {
     sigset_t signal_set;
     CONTEXT signalContextRecord;
-    CONTEXT *contextRecord;
-    EXCEPTION_RECORD *exceptionRecord;
+    CONTEXT contextRecord;
+    EXCEPTION_RECORD exceptionRecord;
     native_context_t *ucontext;
 
     ucontext = (native_context_t *)sigcontext;
     g_common_signal_handler_context_locvar_offset = (int)((char*)&signalContextRecord - (char*)__builtin_frame_address(0));
 
-    AllocateExceptionRecords(&exceptionRecord, &contextRecord);
+    //AllocateExceptionRecords(&exceptionRecord, &contextRecord);
 
-    exceptionRecord->ExceptionCode = CONTEXTGetExceptionCodeForSignal(siginfo, ucontext);
-    exceptionRecord->ExceptionFlags = EXCEPTION_IS_SIGNAL;
-    exceptionRecord->ExceptionRecord = NULL;
-    exceptionRecord->ExceptionAddress = GetNativeContextPC(ucontext);
-    exceptionRecord->NumberParameters = numParams;
+    exceptionRecord.ExceptionCode = CONTEXTGetExceptionCodeForSignal(siginfo, ucontext);
+    exceptionRecord.ExceptionFlags = EXCEPTION_IS_SIGNAL | EXCEPTION_ON_STACK;
+    exceptionRecord.ExceptionRecord = NULL;
+    exceptionRecord.ExceptionAddress = GetNativeContextPC(ucontext);
+    exceptionRecord.NumberParameters = numParams;
 
     va_list params;
     va_start(params, numParams);
 
     for (int i = 0; i < numParams; i++)
     {
-        exceptionRecord->ExceptionInformation[i] = va_arg(params, size_t);
+        exceptionRecord.ExceptionInformation[i] = va_arg(params, size_t);
     }
 
     // Pre-populate context with data from current frame, because ucontext doesn't have some data (e.g. SS register)
     // which is required for restoring context
-    RtlCaptureContext(contextRecord);
+    RtlCaptureContext(&contextRecord);
 
     ULONG contextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT;
 
@@ -837,7 +837,7 @@ static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext
     // Fill context record with required information. from pal.h:
     // On non-Win32 platforms, the CONTEXT pointer in the
     // PEXCEPTION_POINTERS will contain at least the CONTEXT_CONTROL registers.
-    CONTEXTFromNativeContext(ucontext, contextRecord, contextFlags);
+    CONTEXTFromNativeContext(ucontext, &contextRecord, contextFlags);
 
     /* Unmask signal so we can receive it again */
     sigemptyset(&signal_set);
@@ -848,17 +848,17 @@ static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext
         ASSERT("pthread_sigmask failed; error number is %d\n", sigmaskRet);
     }
 
-    contextRecord->ContextFlags |= CONTEXT_EXCEPTION_ACTIVE;
+    contextRecord.ContextFlags |= CONTEXT_EXCEPTION_ACTIVE;
 
-    memcpy_s(&signalContextRecord, sizeof(CONTEXT), contextRecord, sizeof(CONTEXT));
+    memcpy_s(&signalContextRecord, sizeof(CONTEXT), &contextRecord, sizeof(CONTEXT));
 
     // The exception object takes ownership of the exceptionRecord and contextRecord
-    PAL_SEHException exception(exceptionRecord, contextRecord);
+    PAL_SEHException exception(&exceptionRecord, &contextRecord);
 
     if (SEHProcessException(&exception))
     {
         // Exception handling may have modified the context, so update it.
-        CONTEXTToNativeContext(contextRecord, ucontext);
+        CONTEXTToNativeContext(&contextRecord, ucontext);
         return true;
     }
 
-- 
2.7.4