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