Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  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, %r10d
 75 *   jz   foo
 76 *   ud2
 77 *   nop
 78 * foo:
 79 *   osp nop3			# was endbr64
 80 *   ... code here ...
 81 *   ret
 82 *
 83 * direct caller:
 84 *   call foo / call foo+4
 85 *
 86 * indirect caller:
 87 *   lea foo(%rip), %r11
 88 *   ...
 89 *   movl $0x12345678, %r10d
 90 *   subl $16, %r11
 91 *   nop4
 92 *   call *%r11
 93 *
 94 */
 95enum cfi_mode {
 96	CFI_DEFAULT,	/* FineIBT if hardware has IBT, otherwise kCFI */
 97	CFI_OFF,	/* Taditional / IBT depending on .config */
 98	CFI_KCFI,	/* Optionally CALL_PADDING, IBT, RETPOLINE */
 99	CFI_FINEIBT,	/* see arch/x86/kernel/alternative.c */
100};
101
102extern enum cfi_mode cfi_mode;
103
104struct pt_regs;
105
106#ifdef CONFIG_CFI_CLANG
107enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
108#define __bpfcall
109extern u32 cfi_bpf_hash;
110extern u32 cfi_bpf_subprog_hash;
111
112static inline int cfi_get_offset(void)
113{
114	switch (cfi_mode) {
115	case CFI_FINEIBT:
116		return 16;
117	case CFI_KCFI:
118		if (IS_ENABLED(CONFIG_CALL_PADDING))
119			return 16;
120		return 5;
121	default:
122		return 0;
123	}
124}
125#define cfi_get_offset cfi_get_offset
126
127extern u32 cfi_get_func_hash(void *func);
128
129#else
130static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
131{
132	return BUG_TRAP_TYPE_NONE;
133}
134#define cfi_bpf_hash 0U
135#define cfi_bpf_subprog_hash 0U
136static inline u32 cfi_get_func_hash(void *func)
137{
138	return 0;
139}
140#endif /* CONFIG_CFI_CLANG */
141
142#if HAS_KERNEL_IBT == 1
143#define CFI_NOSEAL(x)	asm(IBT_NOSEAL(__stringify(x)))
144#endif
145
146#endif /* _ASM_X86_CFI_H */