Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/x86/include/asm/cfi.h
50031 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, %eax
75
* jne.32,pn foo+3
76
* foo:
77
* nopl -42(%rax) # was endbr64
78
* ... code here ...
79
* ret
80
*
81
* direct caller:
82
* call foo / call foo+4
83
*
84
* indirect caller:
85
* lea foo(%rip), %r11
86
* ...
87
* movl $0x12345678, %eax
88
* lea -0x10(%r11), %r11
89
* nop5
90
* call *%r11
91
*
92
*/
93
enum cfi_mode {
94
CFI_AUTO, /* FineIBT if hardware has IBT, otherwise kCFI */
95
CFI_OFF, /* Taditional / IBT depending on .config */
96
CFI_KCFI, /* Optionally CALL_PADDING, IBT, RETPOLINE */
97
CFI_FINEIBT, /* see arch/x86/kernel/alternative.c */
98
};
99
100
extern enum cfi_mode cfi_mode;
101
102
#ifdef CONFIG_FINEIBT_BHI
103
extern bool cfi_bhi;
104
#else
105
#define cfi_bhi (0)
106
#endif
107
108
typedef u8 bhi_thunk[32];
109
extern bhi_thunk __bhi_args[];
110
extern bhi_thunk __bhi_args_end[];
111
112
struct pt_regs;
113
114
#ifdef CONFIG_CFI
115
enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
116
#define __bpfcall
117
118
static inline int cfi_get_offset(void)
119
{
120
switch (cfi_mode) {
121
case CFI_FINEIBT:
122
return 16;
123
case CFI_KCFI:
124
if (IS_ENABLED(CONFIG_CALL_PADDING))
125
return 16;
126
return 5;
127
default:
128
return 0;
129
}
130
}
131
#define cfi_get_offset cfi_get_offset
132
133
extern u32 cfi_get_func_hash(void *func);
134
#define cfi_get_func_hash cfi_get_func_hash
135
136
extern int cfi_get_func_arity(void *func);
137
138
#ifdef CONFIG_FINEIBT
139
extern bool decode_fineibt_insn(struct pt_regs *regs, unsigned long *target, u32 *type);
140
#else
141
static inline bool
142
decode_fineibt_insn(struct pt_regs *regs, unsigned long *target, u32 *type)
143
{
144
return false;
145
}
146
147
#endif
148
149
#else
150
static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
151
{
152
return BUG_TRAP_TYPE_NONE;
153
}
154
static inline int cfi_get_func_arity(void *func)
155
{
156
return 0;
157
}
158
#endif /* CONFIG_CFI */
159
160
#if HAS_KERNEL_IBT == 1
161
#define CFI_NOSEAL(x) asm(IBT_NOSEAL(__stringify(x)))
162
#endif
163
164
#endif /* _ASM_X86_CFI_H */
165
166