File Index
Files and directories
Sign in
FILE

cfi.h

File preview with syntax highlighting.

linux-6.19.14/arch/x86/include/asm/cfi.h C
  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 */
 93enum 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
100extern enum cfi_mode cfi_mode;
101
102#ifdef CONFIG_FINEIBT_BHI
103extern bool cfi_bhi;
104#else
105#define cfi_bhi (0)
106#endif
107
108typedef u8 bhi_thunk[32];
109extern bhi_thunk __bhi_args[];
110extern bhi_thunk __bhi_args_end[];
111
112struct pt_regs;
113
114#ifdef CONFIG_CALL_PADDING
115#define CFI_OFFSET (CONFIG_FUNCTION_PADDING_CFI+5)
116#else
117#define CFI_OFFSET 5
118#endif
119
120#ifdef CONFIG_CFI
121enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
122#define __bpfcall
123
124static inline int cfi_get_offset(void)
125{
126	switch (cfi_mode) {
127	case CFI_FINEIBT:
128		return /* fineibt_prefix_size */ 16;
129	case CFI_KCFI:
130		return CFI_OFFSET;
131	default:
132		return 0;
133	}
134}
135#define cfi_get_offset cfi_get_offset
136
137extern u32 cfi_get_func_hash(void *func);
138#define cfi_get_func_hash cfi_get_func_hash
139
140extern int cfi_get_func_arity(void *func);
141
142#ifdef CONFIG_FINEIBT
143extern bool decode_fineibt_insn(struct pt_regs *regs, unsigned long *target, u32 *type);
144#else
145static inline bool
146decode_fineibt_insn(struct pt_regs *regs, unsigned long *target, u32 *type)
147{
148	return false;
149}
150
151#endif
152
153#else
154static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
155{
156	return BUG_TRAP_TYPE_NONE;
157}
158static inline int cfi_get_func_arity(void *func)
159{
160	return 0;
161}
162#endif /* CONFIG_CFI */
163
164#if HAS_KERNEL_IBT == 1
165#define CFI_NOSEAL(x)	asm(IBT_NOSEAL(__stringify(x)))
166#endif
167
168#endif /* _ASM_X86_CFI_H */
~/ Read-only file preview.