Skip to content

Commit f1befc8

Browse files
samitolvanenAlexei Starovoitov
authored andcommitted
cfi: Move BPF CFI types and helpers to generic code
Instead of duplicating the same code for each architecture, move the CFI type hash variables for BPF function types and related helper functions to generic CFI code, and allow architectures to override the function definitions if needed. Signed-off-by: Sami Tolvanen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 5ccaeed commit f1befc8

File tree

6 files changed

+56
-68
lines changed

6 files changed

+56
-68
lines changed

arch/riscv/include/asm/cfi.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,11 @@ struct pt_regs;
1414
#ifdef CONFIG_CFI_CLANG
1515
enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
1616
#define __bpfcall
17-
static inline int cfi_get_offset(void)
18-
{
19-
return 4;
20-
}
21-
22-
#define cfi_get_offset cfi_get_offset
23-
extern u32 cfi_bpf_hash;
24-
extern u32 cfi_bpf_subprog_hash;
25-
extern u32 cfi_get_func_hash(void *func);
2617
#else
2718
static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
2819
{
2920
return BUG_TRAP_TYPE_NONE;
3021
}
31-
32-
#define cfi_bpf_hash 0U
33-
#define cfi_bpf_subprog_hash 0U
34-
static inline u32 cfi_get_func_hash(void *func)
35-
{
36-
return 0;
37-
}
3822
#endif /* CONFIG_CFI_CLANG */
3923

4024
#endif /* _ASM_RISCV_CFI_H */

arch/riscv/kernel/cfi.c

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*
55
* Copyright (C) 2023 Google LLC
66
*/
7-
#include <linux/cfi_types.h>
87
#include <linux/cfi.h>
98
#include <asm/insn.h>
109

@@ -76,26 +75,3 @@ enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
7675

7776
return report_cfi_failure(regs, regs->epc, &target, type);
7877
}
79-
80-
#ifdef CONFIG_CFI_CLANG
81-
struct bpf_insn;
82-
83-
/* Must match bpf_func_t / DEFINE_BPF_PROG_RUN() */
84-
extern unsigned int __bpf_prog_runX(const void *ctx,
85-
const struct bpf_insn *insn);
86-
DEFINE_CFI_TYPE(cfi_bpf_hash, __bpf_prog_runX);
87-
88-
/* Must match bpf_callback_t */
89-
extern u64 __bpf_callback_fn(u64, u64, u64, u64, u64);
90-
DEFINE_CFI_TYPE(cfi_bpf_subprog_hash, __bpf_callback_fn);
91-
92-
u32 cfi_get_func_hash(void *func)
93-
{
94-
u32 hash;
95-
96-
if (get_kernel_nofault(hash, func - cfi_get_offset()))
97-
return 0;
98-
99-
return hash;
100-
}
101-
#endif

arch/x86/include/asm/cfi.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,6 @@ struct pt_regs;
116116
#ifdef CONFIG_CFI_CLANG
117117
enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
118118
#define __bpfcall
119-
extern u32 cfi_bpf_hash;
120-
extern u32 cfi_bpf_subprog_hash;
121119

122120
static inline int cfi_get_offset(void)
123121
{
@@ -135,6 +133,8 @@ static inline int cfi_get_offset(void)
135133
#define cfi_get_offset cfi_get_offset
136134

137135
extern u32 cfi_get_func_hash(void *func);
136+
#define cfi_get_func_hash cfi_get_func_hash
137+
138138
extern int cfi_get_func_arity(void *func);
139139

140140
#ifdef CONFIG_FINEIBT
@@ -153,12 +153,6 @@ static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
153153
{
154154
return BUG_TRAP_TYPE_NONE;
155155
}
156-
#define cfi_bpf_hash 0U
157-
#define cfi_bpf_subprog_hash 0U
158-
static inline u32 cfi_get_func_hash(void *func)
159-
{
160-
return 0;
161-
}
162156
static inline int cfi_get_func_arity(void *func)
163157
{
164158
return 0;

arch/x86/kernel/alternative.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#define pr_fmt(fmt) "SMP alternatives: " fmt
33

44
#include <linux/mmu_context.h>
5-
#include <linux/cfi_types.h>
65
#include <linux/perf_event.h>
76
#include <linux/vmalloc.h>
87
#include <linux/memory.h>
@@ -1185,17 +1184,6 @@ bool cfi_bhi __ro_after_init = false;
11851184
#endif
11861185

11871186
#ifdef CONFIG_CFI_CLANG
1188-
struct bpf_insn;
1189-
1190-
/* Must match bpf_func_t / DEFINE_BPF_PROG_RUN() */
1191-
extern unsigned int __bpf_prog_runX(const void *ctx,
1192-
const struct bpf_insn *insn);
1193-
DEFINE_CFI_TYPE(cfi_bpf_hash, __bpf_prog_runX);
1194-
1195-
/* Must match bpf_callback_t */
1196-
extern u64 __bpf_callback_fn(u64, u64, u64, u64, u64);
1197-
DEFINE_CFI_TYPE(cfi_bpf_subprog_hash, __bpf_callback_fn);
1198-
11991187
u32 cfi_get_func_hash(void *func)
12001188
{
12011189
u32 hash;

include/linux/cfi.h

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,9 @@
1111
#include <linux/module.h>
1212
#include <asm/cfi.h>
1313

14+
#ifdef CONFIG_CFI_CLANG
1415
extern bool cfi_warn;
1516

16-
#ifndef cfi_get_offset
17-
static inline int cfi_get_offset(void)
18-
{
19-
return 0;
20-
}
21-
#endif
22-
23-
#ifdef CONFIG_CFI_CLANG
2417
enum bug_trap_type report_cfi_failure(struct pt_regs *regs, unsigned long addr,
2518
unsigned long *target, u32 type);
2619

@@ -29,6 +22,44 @@ static inline enum bug_trap_type report_cfi_failure_noaddr(struct pt_regs *regs,
2922
{
3023
return report_cfi_failure(regs, addr, NULL, 0);
3124
}
25+
26+
#ifndef cfi_get_offset
27+
/*
28+
* Returns the CFI prefix offset. By default, the compiler emits only
29+
* a 4-byte CFI type hash before the function. If an architecture
30+
* uses -fpatchable-function-entry=N,M where M>0 to change the prefix
31+
* offset, they must override this function.
32+
*/
33+
static inline int cfi_get_offset(void)
34+
{
35+
return 4;
36+
}
37+
#endif
38+
39+
#ifndef cfi_get_func_hash
40+
static inline u32 cfi_get_func_hash(void *func)
41+
{
42+
u32 hash;
43+
44+
if (get_kernel_nofault(hash, func - cfi_get_offset()))
45+
return 0;
46+
47+
return hash;
48+
}
49+
#endif
50+
51+
/* CFI type hashes for BPF function types */
52+
extern u32 cfi_bpf_hash;
53+
extern u32 cfi_bpf_subprog_hash;
54+
55+
#else /* CONFIG_CFI_CLANG */
56+
57+
static inline int cfi_get_offset(void) { return 0; }
58+
static inline u32 cfi_get_func_hash(void *func) { return 0; }
59+
60+
#define cfi_bpf_hash 0U
61+
#define cfi_bpf_subprog_hash 0U
62+
3263
#endif /* CONFIG_CFI_CLANG */
3364

3465
#ifdef CONFIG_ARCH_USES_CFI_TRAPS

kernel/cfi.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* Copyright (C) 2022 Google LLC
66
*/
77

8+
#include <linux/bpf.h>
9+
#include <linux/cfi_types.h>
810
#include <linux/cfi.h>
911

1012
bool cfi_warn __ro_after_init = IS_ENABLED(CONFIG_CFI_PERMISSIVE);
@@ -27,6 +29,19 @@ enum bug_trap_type report_cfi_failure(struct pt_regs *regs, unsigned long addr,
2729
return BUG_TRAP_TYPE_BUG;
2830
}
2931

32+
/*
33+
* Declare two non-existent functions with types that match bpf_func_t and
34+
* bpf_callback_t pointers, and use DEFINE_CFI_TYPE to define type hash
35+
* variables for each function type. The cfi_bpf_* variables are used by
36+
* arch-specific BPF JIT implementations to ensure indirectly callable JIT
37+
* code has matching CFI type hashes.
38+
*/
39+
extern typeof(*(bpf_func_t)0) __bpf_prog_runX;
40+
DEFINE_CFI_TYPE(cfi_bpf_hash, __bpf_prog_runX);
41+
42+
extern typeof(*(bpf_callback_t)0) __bpf_callback_fn;
43+
DEFINE_CFI_TYPE(cfi_bpf_subprog_hash, __bpf_callback_fn);
44+
3045
#ifdef CONFIG_ARCH_USES_CFI_TRAPS
3146
static inline unsigned long trap_address(s32 *p)
3247
{

0 commit comments

Comments
 (0)