• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * This file has no copyright assigned and is placed in the Public Domain.
3  * This file is part of the mingw-w64 runtime package.
4  * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5  */
6 
7 #ifndef WIN32_LEAN_AND_MEAN
8 #define WIN32_LEAN_AND_MEAN
9 #endif
10 #define WIN32_NO_STATUS
11 #include <stdlib.h>	/* abort () */
12 #include <windows.h>
13 #undef  WIN32_NO_STATUS
14 #include <ntstatus.h>	/* STATUS macros */
15 #ifdef _WIN64
16 #include <intrin.h>
17 #endif
18 
19 #ifdef _WIN64
20 #define DEFAULT_SECURITY_COOKIE 0x00002B992DDFA232ll
21 #else
22 #define DEFAULT_SECURITY_COOKIE 0xBB40E64E
23 #endif
24 
25 /* Externals.  */
26 
27 typedef LONG NTSTATUS;	/* same as in ntdef.h / winternl.h */
28 
29 #define UNW_FLAG_NHANDLER   0x0
30 
31 typedef union
32 {
33   unsigned __int64 ft_scalar;
34   FILETIME ft_struct;
35 } FT;
36 
37 static EXCEPTION_RECORD GS_ExceptionRecord;
38 static CONTEXT GS_ContextRecord;
39 
40 static const EXCEPTION_POINTERS GS_ExceptionPointers = {
41   &GS_ExceptionRecord,&GS_ContextRecord
42 };
43 
44 DECLSPEC_SELECTANY UINT_PTR __security_cookie = DEFAULT_SECURITY_COOKIE;
45 DECLSPEC_SELECTANY UINT_PTR __security_cookie_complement = ~(DEFAULT_SECURITY_COOKIE);
46 
47 void __cdecl __security_init_cookie (void);
48 
49 void __cdecl
__security_init_cookie(void)50 __security_init_cookie (void)
51 {
52   UINT_PTR cookie;
53   FT systime = { 0, };
54   LARGE_INTEGER perfctr;
55 
56   if (__security_cookie != DEFAULT_SECURITY_COOKIE)
57     {
58       __security_cookie_complement = ~__security_cookie;
59       return;
60     }
61 
62   GetSystemTimeAsFileTime (&systime.ft_struct);
63 #ifdef _WIN64
64   cookie = systime.ft_scalar;
65 #else
66   cookie = systime.ft_struct.dwLowDateTime;
67   cookie ^= systime.ft_struct.dwHighDateTime;
68 #endif
69 
70   cookie ^= GetCurrentProcessId ();
71   cookie ^= GetCurrentThreadId ();
72   cookie ^= GetTickCount ();
73 
74   QueryPerformanceCounter (&perfctr);
75 #ifdef _WIN64
76   cookie ^= perfctr.QuadPart;
77 #else
78   cookie ^= perfctr.LowPart;
79   cookie ^= perfctr.HighPart;
80 #endif
81 
82 #ifdef _WIN64
83   cookie &= 0x0000ffffffffffffll;
84 #endif
85 
86   if (cookie == DEFAULT_SECURITY_COOKIE)
87     cookie = DEFAULT_SECURITY_COOKIE + 1;
88   __security_cookie = cookie;
89   __security_cookie_complement = ~cookie;
90 }
91 
92 
93 #if defined(__GNUC__) /* wrap msvc intrinsics onto gcc builtins */
94 #undef  _ReturnAddress
95 #undef  _AddressOfReturnAddress
96 #define _ReturnAddress()		__builtin_return_address(0)
97 #define _AddressOfReturnAddress()	__builtin_frame_address (0)
98 #endif /* __GNUC__ */
99 
100 __declspec(noreturn) void __cdecl __report_gsfailure (ULONG_PTR);
101 
102 #define UNUSED_PARAM(x) { x = x; }
103 __declspec(noreturn) void __cdecl
__report_gsfailure(ULONG_PTR StackCookie)104 __report_gsfailure (ULONG_PTR StackCookie)
105 {
106   volatile UINT_PTR cookie[2] __MINGW_ATTRIB_UNUSED;
107 #if defined(_WIN64) && !defined(__aarch64__)
108   ULONG64 controlPC, imgBase, establisherFrame;
109   PRUNTIME_FUNCTION fctEntry;
110   PVOID hndData;
111 
112   RtlCaptureContext (&GS_ContextRecord);
113   controlPC = GS_ContextRecord.Rip;
114   fctEntry = RtlLookupFunctionEntry (controlPC, &imgBase, NULL);
115   if (fctEntry != NULL)
116     {
117       RtlVirtualUnwind (UNW_FLAG_NHANDLER, imgBase, controlPC, fctEntry,
118 			&GS_ContextRecord, &hndData, &establisherFrame, NULL);
119     }
120   else
121 #endif /* _WIN64 */
122     {
123 #if defined(__x86_64__) || defined(_AMD64_)
124       GS_ContextRecord.Rip = (ULONGLONG) _ReturnAddress();
125       GS_ContextRecord.Rsp = (ULONGLONG) _AddressOfReturnAddress() + 8;
126 #elif defined(__i386__) || defined(_X86_)
127       GS_ContextRecord.Eip = (DWORD) _ReturnAddress();
128       GS_ContextRecord.Esp = (DWORD) _AddressOfReturnAddress() + 4;
129 #elif defined(__arm__) || defined(_ARM_)
130       GS_ContextRecord.Pc = (DWORD) _ReturnAddress();
131       GS_ContextRecord.Sp = (DWORD) _AddressOfReturnAddress() + 4;
132 #endif /* _WIN64 */
133     }
134 
135 #if defined(__x86_64__) || defined(_AMD64_)
136   GS_ExceptionRecord.ExceptionAddress = (PVOID) GS_ContextRecord.Rip;
137   GS_ContextRecord.Rcx = StackCookie;
138 #elif defined(__i386__) || defined(_X86_)
139   GS_ExceptionRecord.ExceptionAddress = (PVOID) GS_ContextRecord.Eip;
140   GS_ContextRecord.Ecx = StackCookie;
141 #elif defined(__arm__) || defined(_ARM_)
142   GS_ExceptionRecord.ExceptionAddress = (PVOID) GS_ContextRecord.Pc;
143   UNUSED_PARAM(StackCookie);
144 #endif /* _WIN64 */
145   GS_ExceptionRecord.ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
146   GS_ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
147   cookie[0] = __security_cookie;
148   cookie[1] = __security_cookie_complement;
149   SetUnhandledExceptionFilter (NULL);
150   UnhandledExceptionFilter ((EXCEPTION_POINTERS *) &GS_ExceptionPointers);
151   TerminateProcess (GetCurrentProcess (), STATUS_STACK_BUFFER_OVERRUN);
152   abort();
153 }
154 
155