Commit f1befc82 authored by Sami Tolvanen's avatar Sami Tolvanen Committed by Alexei Starovoitov
Browse files

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: default avatarSami Tolvanen <samitolvanen@google.com>
Link: https://lore.kernel.org/r/20250801001004.1859976-7-samitolvanen@google.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 5ccaeedb
Loading
Loading
Loading
Loading
+0 −16
Original line number Diff line number Diff line
@@ -14,27 +14,11 @@ struct pt_regs;
#ifdef CONFIG_CFI_CLANG
enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
#define __bpfcall
static inline int cfi_get_offset(void)
{
	return 4;
}

#define cfi_get_offset cfi_get_offset
extern u32 cfi_bpf_hash;
extern u32 cfi_bpf_subprog_hash;
extern u32 cfi_get_func_hash(void *func);
#else
static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
{
	return BUG_TRAP_TYPE_NONE;
}

#define cfi_bpf_hash 0U
#define cfi_bpf_subprog_hash 0U
static inline u32 cfi_get_func_hash(void *func)
{
	return 0;
}
#endif /* CONFIG_CFI_CLANG */

#endif /* _ASM_RISCV_CFI_H */
+0 −24
Original line number Diff line number Diff line
@@ -4,7 +4,6 @@
 *
 * Copyright (C) 2023 Google LLC
 */
#include <linux/cfi_types.h>
#include <linux/cfi.h>
#include <asm/insn.h>

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

	return report_cfi_failure(regs, regs->epc, &target, type);
}

#ifdef CONFIG_CFI_CLANG
struct bpf_insn;

/* Must match bpf_func_t / DEFINE_BPF_PROG_RUN() */
extern unsigned int __bpf_prog_runX(const void *ctx,
				    const struct bpf_insn *insn);
DEFINE_CFI_TYPE(cfi_bpf_hash, __bpf_prog_runX);

/* Must match bpf_callback_t */
extern u64 __bpf_callback_fn(u64, u64, u64, u64, u64);
DEFINE_CFI_TYPE(cfi_bpf_subprog_hash, __bpf_callback_fn);

u32 cfi_get_func_hash(void *func)
{
	u32 hash;

	if (get_kernel_nofault(hash, func - cfi_get_offset()))
		return 0;

	return hash;
}
#endif
+2 −8
Original line number Diff line number Diff line
@@ -116,8 +116,6 @@ struct pt_regs;
#ifdef CONFIG_CFI_CLANG
enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
#define __bpfcall
extern u32 cfi_bpf_hash;
extern u32 cfi_bpf_subprog_hash;

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

extern u32 cfi_get_func_hash(void *func);
#define cfi_get_func_hash cfi_get_func_hash

extern int cfi_get_func_arity(void *func);

#ifdef CONFIG_FINEIBT
@@ -153,12 +153,6 @@ static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
{
	return BUG_TRAP_TYPE_NONE;
}
#define cfi_bpf_hash 0U
#define cfi_bpf_subprog_hash 0U
static inline u32 cfi_get_func_hash(void *func)
{
	return 0;
}
static inline int cfi_get_func_arity(void *func)
{
	return 0;
+0 −12
Original line number Diff line number Diff line
@@ -2,7 +2,6 @@
#define pr_fmt(fmt) "SMP alternatives: " fmt

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

#ifdef CONFIG_CFI_CLANG
struct bpf_insn;

/* Must match bpf_func_t / DEFINE_BPF_PROG_RUN() */
extern unsigned int __bpf_prog_runX(const void *ctx,
				    const struct bpf_insn *insn);
DEFINE_CFI_TYPE(cfi_bpf_hash, __bpf_prog_runX);

/* Must match bpf_callback_t */
extern u64 __bpf_callback_fn(u64, u64, u64, u64, u64);
DEFINE_CFI_TYPE(cfi_bpf_subprog_hash, __bpf_callback_fn);

u32 cfi_get_func_hash(void *func)
{
	u32 hash;
+39 −8
Original line number Diff line number Diff line
@@ -11,16 +11,9 @@
#include <linux/module.h>
#include <asm/cfi.h>

#ifdef CONFIG_CFI_CLANG
extern bool cfi_warn;

#ifndef cfi_get_offset
static inline int cfi_get_offset(void)
{
	return 0;
}
#endif

#ifdef CONFIG_CFI_CLANG
enum bug_trap_type report_cfi_failure(struct pt_regs *regs, unsigned long addr,
				      unsigned long *target, u32 type);

@@ -29,6 +22,44 @@ static inline enum bug_trap_type report_cfi_failure_noaddr(struct pt_regs *regs,
{
	return report_cfi_failure(regs, addr, NULL, 0);
}

#ifndef cfi_get_offset
/*
 * Returns the CFI prefix offset. By default, the compiler emits only
 * a 4-byte CFI type hash before the function. If an architecture
 * uses -fpatchable-function-entry=N,M where M>0 to change the prefix
 * offset, they must override this function.
 */
static inline int cfi_get_offset(void)
{
	return 4;
}
#endif

#ifndef cfi_get_func_hash
static inline u32 cfi_get_func_hash(void *func)
{
	u32 hash;

	if (get_kernel_nofault(hash, func - cfi_get_offset()))
		return 0;

	return hash;
}
#endif

/* CFI type hashes for BPF function types */
extern u32 cfi_bpf_hash;
extern u32 cfi_bpf_subprog_hash;

#else /* CONFIG_CFI_CLANG */

static inline int cfi_get_offset(void) { return 0; }
static inline u32 cfi_get_func_hash(void *func) { return 0; }

#define cfi_bpf_hash 0U
#define cfi_bpf_subprog_hash 0U

#endif /* CONFIG_CFI_CLANG */

#ifdef CONFIG_ARCH_USES_CFI_TRAPS
Loading