mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-05-14 21:38:46 +02:00
9591fdb061
Pull more x86 updates from Borislav Petkov: - Remove a bunch of asm implementing condition flags testing in KVM's emulator in favor of int3_emulate_jcc() which is written in C - Replace KVM fastops with C-based stubs which avoids problems with the fastop infra related to latter not adhering to the C ABI due to their special calling convention and, more importantly, bypassing compiler control-flow integrity checking because they're written in asm - Remove wrongly used static branches and other ugliness accumulated over time in hyperv's hypercall implementation with a proper static function call to the correct hypervisor call variant - Add some fixes and modifications to allow running FRED-enabled kernels in KVM even on non-FRED hardware - Add kCFI improvements like validating indirect calls and prepare for enabling kCFI with GCC. Add cmdline params documentation and other code cleanups - Use the single-byte 0xd6 insn as the official #UD single-byte undefined opcode instruction as agreed upon by both x86 vendors - Other smaller cleanups and touchups all over the place * tag 'x86_core_for_v6.18_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits) x86,retpoline: Optimize patch_retpoline() x86,ibt: Use UDB instead of 0xEA x86/cfi: Remove __noinitretpoline and __noretpoline x86/cfi: Add "debug" option to "cfi=" bootparam x86/cfi: Standardize on common "CFI:" prefix for CFI reports x86/cfi: Document the "cfi=" bootparam options x86/traps: Clarify KCFI instruction layout compiler_types.h: Move __nocfi out of compiler-specific header objtool: Validate kCFI calls x86/fred: KVM: VMX: Always use FRED for IRQs when CONFIG_X86_FRED=y x86/fred: Play nice with invoking asm_fred_entry_from_kvm() on non-FRED hardware x86/fred: Install system vector handlers even if FRED isn't fully enabled x86/hyperv: Use direct call to hypercall-page x86/hyperv: Clean up hv_do_hypercall() KVM: x86: Remove fastops KVM: x86: Convert em_salc() to C KVM: x86: Introduce EM_ASM_3WCL KVM: x86: Introduce EM_ASM_1SRC2 KVM: x86: Introduce EM_ASM_2CL KVM: x86: Introduce EM_ASM_2W ...
165 lines
2.9 KiB
C
165 lines
2.9 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _ASM_X86_CFI_H
|
|
#define _ASM_X86_CFI_H
|
|
|
|
/*
|
|
* Clang Control Flow Integrity (CFI) support.
|
|
*
|
|
* Copyright (C) 2022 Google LLC
|
|
*/
|
|
#include <linux/bug.h>
|
|
#include <asm/ibt.h>
|
|
|
|
/*
|
|
* An overview of the various calling conventions...
|
|
*
|
|
* Traditional:
|
|
*
|
|
* foo:
|
|
* ... code here ...
|
|
* ret
|
|
*
|
|
* direct caller:
|
|
* call foo
|
|
*
|
|
* indirect caller:
|
|
* lea foo(%rip), %r11
|
|
* ...
|
|
* call *%r11
|
|
*
|
|
*
|
|
* IBT:
|
|
*
|
|
* foo:
|
|
* endbr64
|
|
* ... code here ...
|
|
* ret
|
|
*
|
|
* direct caller:
|
|
* call foo / call foo+4
|
|
*
|
|
* indirect caller:
|
|
* lea foo(%rip), %r11
|
|
* ...
|
|
* call *%r11
|
|
*
|
|
*
|
|
* kCFI:
|
|
*
|
|
* __cfi_foo:
|
|
* movl $0x12345678, %eax
|
|
* # 11 nops when CONFIG_CALL_PADDING
|
|
* foo:
|
|
* endbr64 # when IBT
|
|
* ... code here ...
|
|
* ret
|
|
*
|
|
* direct call:
|
|
* call foo # / call foo+4 when IBT
|
|
*
|
|
* indirect call:
|
|
* lea foo(%rip), %r11
|
|
* ...
|
|
* movl $(-0x12345678), %r10d
|
|
* addl -4(%r11), %r10d # -15 when CONFIG_CALL_PADDING
|
|
* jz 1f
|
|
* ud2
|
|
* 1:call *%r11
|
|
*
|
|
*
|
|
* FineIBT (builds as kCFI + CALL_PADDING + IBT + RETPOLINE and runtime patches into):
|
|
*
|
|
* __cfi_foo:
|
|
* endbr64
|
|
* subl 0x12345678, %eax
|
|
* jne.32,pn foo+3
|
|
* foo:
|
|
* nopl -42(%rax) # was endbr64
|
|
* ... code here ...
|
|
* ret
|
|
*
|
|
* direct caller:
|
|
* call foo / call foo+4
|
|
*
|
|
* indirect caller:
|
|
* lea foo(%rip), %r11
|
|
* ...
|
|
* movl $0x12345678, %eax
|
|
* lea -0x10(%r11), %r11
|
|
* nop5
|
|
* call *%r11
|
|
*
|
|
*/
|
|
enum cfi_mode {
|
|
CFI_AUTO, /* FineIBT if hardware has IBT, otherwise kCFI */
|
|
CFI_OFF, /* Taditional / IBT depending on .config */
|
|
CFI_KCFI, /* Optionally CALL_PADDING, IBT, RETPOLINE */
|
|
CFI_FINEIBT, /* see arch/x86/kernel/alternative.c */
|
|
};
|
|
|
|
extern enum cfi_mode cfi_mode;
|
|
|
|
#ifdef CONFIG_FINEIBT_BHI
|
|
extern bool cfi_bhi;
|
|
#else
|
|
#define cfi_bhi (0)
|
|
#endif
|
|
|
|
typedef u8 bhi_thunk[32];
|
|
extern bhi_thunk __bhi_args[];
|
|
extern bhi_thunk __bhi_args_end[];
|
|
|
|
struct pt_regs;
|
|
|
|
#ifdef CONFIG_CFI
|
|
enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
|
|
#define __bpfcall
|
|
|
|
static inline int cfi_get_offset(void)
|
|
{
|
|
switch (cfi_mode) {
|
|
case CFI_FINEIBT:
|
|
return 16;
|
|
case CFI_KCFI:
|
|
if (IS_ENABLED(CONFIG_CALL_PADDING))
|
|
return 16;
|
|
return 5;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
#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
|
|
extern bool decode_fineibt_insn(struct pt_regs *regs, unsigned long *target, u32 *type);
|
|
#else
|
|
static inline bool
|
|
decode_fineibt_insn(struct pt_regs *regs, unsigned long *target, u32 *type)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
#endif
|
|
|
|
#else
|
|
static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
|
|
{
|
|
return BUG_TRAP_TYPE_NONE;
|
|
}
|
|
static inline int cfi_get_func_arity(void *func)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif /* CONFIG_CFI */
|
|
|
|
#if HAS_KERNEL_IBT == 1
|
|
#define CFI_NOSEAL(x) asm(IBT_NOSEAL(__stringify(x)))
|
|
#endif
|
|
|
|
#endif /* _ASM_X86_CFI_H */
|