-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathjbcxrval.c
170 lines (118 loc) · 4.07 KB
/
jbcxrval.c
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
/*++
Copyright (c) Microsoft Corporation
Module Name:
jbcxrval.c
Abstract:
This module implements C support code for jump buffer and context record
validation.
Author:
Ken Johnson (kejohns) 27-Apr-2013
Environment:
Kernel mode only.
--*/
#include <vcruntime_internal.h>
#include <stdlib.h>
#if !(defined(NTOS_KERNEL_RUNTIME) && defined(_AMD64_))
#include "../misc/cfg_support.inc" // To inline _guard_icall_checks_enforced()
#if defined(_AMD64_)
#define JUMP_BUFFER_TO_STACK_POINTER(JumpBuffer) ((JumpBuffer)->Rsp)
#define JB_FRAME(jmpbuf) (((_JUMP_BUFFER*)jmpbuf)->Frame)
#elif defined(_ARM_)
#define JUMP_BUFFER_TO_STACK_POINTER(JumpBuffer) ((JumpBuffer)->Sp)
#define JB_FRAME(jmpbuf) (((_JUMP_BUFFER*)jmpbuf)->Frame)
#elif defined(_ARM64_)
#define JUMP_BUFFER_TO_STACK_POINTER(JumpBuffer) ((JumpBuffer)->Sp)
#define JB_FRAME(jmpbuf) (((_JUMP_BUFFER*)jmpbuf)->Frame)
#elif defined(_X86_)
#define JUMP_BUFFER_TO_STACK_POINTER(JumpBuffer) ((JumpBuffer)->Esp)
#else
#error Unsupported architecture.
#endif
#define CONTEXT_TO_STACK_POINTER(Context) JUMP_BUFFER_TO_STACK_POINTER(Context)
void
__except_validate_context_record (
_In_ PCONTEXT ContextRecord
)
/*++
Routine Description:
This function validates a context record for exception handling support.
Arguments:
ContextRecord - Supplies a pointer to the context record to validate.
Return Value:
None. If the context record was not valid, a fast fail event is raised if
CFG was enforced.
--*/
{
PVOID StackPointer;
PNT_TIB Tib;
//
// If guard ICall checks are enforced, then validate the stack extents of
// the context record and raise a fast fail exception if the extents are
// invalid. If checks are not enforced or the jump buffer was valid, then
// return.
//
if (_guard_icall_checks_enforced()) {
Tib = (PNT_TIB)NtCurrentTeb();
//
// HYB-TODO: Validate both chpe and guest context.
//
StackPointer = (PVOID)CONTEXT_TO_STACK_POINTER(ContextRecord);
if ((StackPointer < Tib->StackLimit) ||
(StackPointer > Tib->StackBase)) {
__fastfail(FAST_FAIL_INVALID_SET_OF_CONTEXT);
}
}
}
__forceinline
void
__except_validate_jump_buffer_common (
_In_ jmp_buf JumpBuffer,
_In_ PVOID (*ExceptGetJbSpRoutine)(jmp_buf)
)
/*++
Routine Description:
This function validates a jump buffer for exception handling support.
Arguments:
JumpBuffer - Supplies a pointer to the jump buffer to validate.
Return Value:
None. If the jump buffer was not valid, a fast fail event is raised if
CFG was enforced.
--*/
{
PVOID StackPointer;
PNT_TIB Tib;
//
// If guard ICall checks are enforced, then validate the stack extents of
// the jump buffer and raise a fast fail exception if the extents are
// invalid. If checks are not enforced or the jump buffer was valid, then
// return.
//
if (_guard_icall_checks_enforced()) {
Tib = (PNT_TIB)NtCurrentTeb();
#pragma prefast(suppress:26007, "JumpBuffer is really a _JUMP_BUFFER in disguise and not a jmp_buf. The code is correct.")
StackPointer = ExceptGetJbSpRoutine(JumpBuffer);
if ((StackPointer < Tib->StackLimit) ||
(StackPointer > Tib->StackBase)) {
__fastfail(FAST_FAIL_INVALID_SET_OF_CONTEXT);
}
#if defined(JB_FRAME)
if (JB_FRAME(JumpBuffer) == 0) {
__fastfail(FAST_FAIL_INVALID_SET_OF_CONTEXT);
}
#endif
}
}
__forceinline
static PVOID __except_get_jumpbuf_sp(jmp_buf JumpBuffer)
{
#pragma prefast(suppress:26007, "JumpBuffer is really a _JUMP_BUFFER in disguise and not a jmp_buf. The code is correct.")
return (PVOID)JUMP_BUFFER_TO_STACK_POINTER((_JUMP_BUFFER*)JumpBuffer);
}
void
__except_validate_jump_buffer (
_In_ jmp_buf JumpBuffer
)
{
__except_validate_jump_buffer_common(JumpBuffer, __except_get_jumpbuf_sp);
}
#endif