Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 168 lines 3.1 kB view raw
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 */