Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/x86/include/asm/cfi.h
26481 views
1
/* SPDX-License-Identifier: GPL-2.0 */
2
#ifndef _ASM_X86_CFI_H
3
#define _ASM_X86_CFI_H
4
5
/*
6
* Clang Control Flow Integrity (CFI) support.
7
*
8
* Copyright (C) 2022 Google LLC
9
*/
10
#include <linux/bug.h>
11
#include <asm/ibt.h>
12
13
/*
14
* An overview of the various calling conventions...
15
*
16
* Traditional:
17
*
18
* foo:
19
* ... code here ...
20
* ret
21
*
22
* direct caller:
23
* call foo
24
*
25
* indirect caller:
26
* lea foo(%rip), %r11
27
* ...
28
* call *%r11
29
*
30
*
31
* IBT:
32
*
33
* foo:
34
* endbr64
35
* ... code here ...
36
* ret
37
*
38
* direct caller:
39
* call foo / call foo+4
40
*
41
* indirect caller:
42
* lea foo(%rip), %r11
43
* ...
44
* call *%r11
45
*
46
*
47
* kCFI:
48
*
49
* __cfi_foo:
50
* movl $0x12345678, %eax
51
* # 11 nops when CONFIG_CALL_PADDING
52
* foo:
53
* endbr64 # when IBT
54
* ... code here ...
55
* ret
56
*
57
* direct call:
58
* call foo # / call foo+4 when IBT
59
*
60
* indirect call:
61
* lea foo(%rip), %r11
62
* ...
63
* movl $(-0x12345678), %r10d
64
* addl -4(%r11), %r10d # -15 when CONFIG_CALL_PADDING
65
* jz 1f
66
* ud2
67
* 1:call *%r11
68
*
69
*
70
* FineIBT (builds as kCFI + CALL_PADDING + IBT + RETPOLINE and runtime patches into):
71
*
72
* __cfi_foo:
73
* endbr64
74
* subl 0x12345678, %r10d
75
* jz foo
76
* ud2
77
* nop
78
* foo:
79
* osp nop3 # was endbr64
80
* ... code here ...
81
* ret
82
*
83
* direct caller:
84
* call foo / call foo+4
85
*
86
* indirect caller:
87
* lea foo(%rip), %r11
88
* ...
89
* movl $0x12345678, %r10d
90
* subl $16, %r11
91
* nop4
92
* call *%r11
93
*
94
*/
95
enum cfi_mode {
96
CFI_AUTO, /* FineIBT if hardware has IBT, otherwise kCFI */
97
CFI_OFF, /* Taditional / IBT depending on .config */
98
CFI_KCFI, /* Optionally CALL_PADDING, IBT, RETPOLINE */
99
CFI_FINEIBT, /* see arch/x86/kernel/alternative.c */
100
};
101
102
extern enum cfi_mode cfi_mode;
103
104
#ifdef CONFIG_FINEIBT_BHI
105
extern bool cfi_bhi;
106
#else
107
#define cfi_bhi (0)
108
#endif
109
110
typedef u8 bhi_thunk[32];
111
extern bhi_thunk __bhi_args[];
112
extern bhi_thunk __bhi_args_end[];
113
114
struct pt_regs;
115
116
#ifdef CONFIG_CFI_CLANG
117
enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
118
#define __bpfcall
119
120
static inline int cfi_get_offset(void)
121
{
122
switch (cfi_mode) {
123
case CFI_FINEIBT:
124
return 16;
125
case CFI_KCFI:
126
if (IS_ENABLED(CONFIG_CALL_PADDING))
127
return 16;
128
return 5;
129
default:
130
return 0;
131
}
132
}
133
#define cfi_get_offset cfi_get_offset
134
135
extern u32 cfi_get_func_hash(void *func);
136
#define cfi_get_func_hash cfi_get_func_hash
137
138
extern int cfi_get_func_arity(void *func);
139
140
#ifdef CONFIG_FINEIBT
141
extern bool decode_fineibt_insn(struct pt_regs *regs, unsigned long *target, u32 *type);
142
#else
143
static inline bool
144
decode_fineibt_insn(struct pt_regs *regs, unsigned long *target, u32 *type)
145
{
146
return false;
147
}
148
149
#endif
150
151
#else
152
static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
153
{
154
return BUG_TRAP_TYPE_NONE;
155
}
156
static inline int cfi_get_func_arity(void *func)
157
{
158
return 0;
159
}
160
#endif /* CONFIG_CFI_CLANG */
161
162
#if HAS_KERNEL_IBT == 1
163
#define CFI_NOSEAL(x) asm(IBT_NOSEAL(__stringify(x)))
164
#endif
165
166
#endif /* _ASM_X86_CFI_H */
167
168