projects/linux·commit 70010521

Merge tag 'x86_core_for_5.18_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

70010521 · Linus Torvalds <[email protected]> · 2022-03-27 10:17:23 -07:00

Pull x86 CET-IBT (Control-Flow-Integrity) support from Peter Zijlstra:
 "Add support for Intel CET-IBT, available since Tigerlake (11th gen),
  which is a coarse grained, hardware based, forward edge
  Control-Flow-Integrity mechanism where any indirect CALL/JMP must
  target an ENDBR instruction or suffer #CP.

  Additionally, since Alderlake (12th gen)/Sapphire-Rapids, speculation
  is limited to 2 instructions (and typically fewer) on branch targets
  not starting with ENDBR. CET-IBT also limits speculation of the next
  sequential instruction after the indirect CALL/JMP [1].

  CET-IBT is fundamentally incompatible with retpolines, but provides,
  as described above, speculation limits itself"

[1] https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/branch-history-injection.html

* tag 'x86_core_for_5.18_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (53 commits)
  kvm/emulate: Fix SETcc emulation for ENDBR
  x86/Kconfig: Only allow CONFIG_X86_KERNEL_IBT with ld.lld >= 14.0.0
  x86/Kconfig: Only enable CONFIG_CC_HAS_IBT for clang >= 14.0.0
  kbuild: Fixup the IBT kbuild changes
  x86/Kconfig: Do not allow CONFIG_X86_X32_ABI=y with llvm-objcopy
  x86: Remove toolchain check for X32 ABI capability
  x86/alternative: Use .ibt_endbr_seal to seal indirect calls
  objtool: Find unused ENDBR instructions
  objtool: Validate IBT assumptions
  objtool: Add IBT/ENDBR decoding
  objtool: Read the NOENDBR annotation
  x86: Annotate idtentry_df()
  x86,objtool: Move the ASM_REACHABLE annotation to objtool.h
  x86: Annotate call_on_stack()
  objtool: Rework ASM_REACHABLE
  x86: Mark __invalid_creds() __noreturn
  exit: Mark do_group_exit() __noreturn
  x86: Mark stop_this_cpu() __noreturn
  objtool: Ignore extra-symbol code
  objtool: Rename --duplicate to --lto
  ...
Commit
7001052160d172f6de06adeffde24dde9935ece8
Parents
f0228146 · 3986f65d

Merge commit. Changes below are compared with the first parent: f0228146.

Changes

95 files changed · +1454 −326

FileStatusAddDelContent
arch/powerpc/include/asm/livepatch.hmodified+0−11View file
arch/powerpc/kernel/kprobes.cmodified+21−13View file
arch/um/kernel/um_arch.cmodified+4−0View file
arch/x86/Kconfigmodified+37−6View file
arch/x86/Makefilemodified+14−18View file
arch/x86/crypto/crc32c-pcl-intel-asm_64.Smodified+3−0View file
arch/x86/entry/entry_64.Smodified+27−4View file
arch/x86/entry/entry_64_compat.Smodified+5−0View file
arch/x86/entry/syscalls/Makefilemodified+1−1View file
arch/x86/include/asm/alternative.hmodified+1−0View file
arch/x86/include/asm/bug.hmodified+1−0View file
arch/x86/include/asm/cpu.hmodified+4−0View file
arch/x86/include/asm/cpufeatures.hmodified+1−0View file
arch/x86/include/asm/efi.hmodified+7−2View file
arch/x86/include/asm/ibt.hadded+105−0View file
arch/x86/include/asm/idtentry.hmodified+16−9View file
arch/x86/include/asm/irq_stack.hmodified+3−1View file
arch/x86/include/asm/irqflags.hmodified+0−5View file
arch/x86/include/asm/linkage.hmodified+31−0View file
arch/x86/include/asm/msr-index.hmodified+19−1View file
arch/x86/include/asm/paravirt.hmodified+1−0View file
arch/x86/include/asm/paravirt_types.hmodified+0−1View file
arch/x86/include/asm/processor.hmodified+1−1View file
arch/x86/include/asm/qspinlock_paravirt.hmodified+3−0View file
arch/x86/include/asm/segment.hmodified+3−2View file
arch/x86/include/asm/setup.hmodified+2−1View file
arch/x86/include/asm/syscall_wrapper.hmodified+3−3View file
arch/x86/include/asm/text-patching.hmodified+23−7View file
arch/x86/include/asm/traps.hmodified+2−0View file
arch/x86/include/asm/vdso.hmodified+1−1View file
arch/x86/include/uapi/asm/processor-flags.hmodified+2−0View file
arch/x86/kernel/alternative.cmodified+52−14View file
arch/x86/kernel/apm_32.cmodified+7−0View file
arch/x86/kernel/cpu/common.cmodified+58−1View file
arch/x86/kernel/ftrace.cmodified+2−7View file
arch/x86/kernel/ftrace_64.Smodified+24−4View file
arch/x86/kernel/head_64.Smodified+12−2View file
arch/x86/kernel/idt.cmodified+7−2View file
arch/x86/kernel/kprobes/core.cmodified+20−9View file
arch/x86/kernel/kvm.cmodified+2−1View file
arch/x86/kernel/machine_kexec_64.cmodified+3−1View file
arch/x86/kernel/module.cmodified+7−1View file
arch/x86/kernel/paravirt.cmodified+5−24View file
arch/x86/kernel/process.cmodified+1−1View file
arch/x86/kernel/process_64.cmodified+1−1View file
arch/x86/kernel/relocate_kernel_64.Smodified+10−0View file
arch/x86/kernel/traps.cmodified+75−0View file
arch/x86/kernel/vmlinux.lds.Smodified+9−0View file
arch/x86/kvm/emulate.cmodified+10−6View file
arch/x86/lib/error-inject.cmodified+2−0View file
arch/x86/lib/retpoline.Smodified+1−0View file
arch/x86/net/bpf_jit_comp.cmodified+24−2View file
arch/x86/platform/efi/Makefilemodified+0−1View file
arch/x86/platform/efi/efi_thunk_64.Smodified+4−2View file
arch/x86/xen/enlighten_pv.cmodified+9−1View file
arch/x86/xen/xen-asm.Smodified+10−0View file
arch/x86/xen/xen-head.Smodified+7−2View file
fs/fuse/ioctl.cmodified+1−1View file
fs/xfs/xfs_ioctl32.cmodified+1−1View file
include/asm-generic/vmlinux.lds.hmodified+4−0View file
include/linux/cfi.hmodified+10−1View file
include/linux/compiler.hmodified+0−7View file
include/linux/cred.hmodified+1−1View file
include/linux/kprobes.hmodified+2−1View file
include/linux/objtool.hmodified+32−0View file
include/linux/sched/task.hmodified+1−1View file
kernel/bpf/trampoline.cmodified+4−16View file
kernel/cred.cmodified+1−1View file
kernel/exit.cmodified+1−1View file
kernel/kprobes.cmodified+54−20View file
kernel/livepatch/patch.cmodified+2−17View file
kernel/trace/ftrace.cmodified+40−8View file
samples/ftrace/ftrace-direct-modify.cmodified+5−0View file
samples/ftrace/ftrace-direct-multi-modify.cmodified+7−3View file
samples/ftrace/ftrace-direct-multi.cmodified+4−1View file
samples/ftrace/ftrace-direct-too.cmodified+3−0View file
samples/ftrace/ftrace-direct.cmodified+3−0View file
scripts/Makefile.buildmodified+14−13View file
scripts/Makefile.libmodified+2−2View file
scripts/link-vmlinux.shmodified+9−3View file
scripts/mod/modpost.cmodified+6−6View file
sound/core/control_compat.cmodified+8−8View file
sound/core/pcm_compat.cmodified+10−10View file
tools/include/linux/objtool.hmodified+32−0View file
tools/objtool/arch/x86/decode.cmodified+29−5View file
tools/objtool/builtin-check.cmodified+5−2View file
tools/objtool/check.cmodified+376−24View file
tools/objtool/elf.cmodified+63−0View file
tools/objtool/include/objtool/arch.hmodified+1−0View file
tools/objtool/include/objtool/builtin.hmodified+2−1View file
tools/objtool/include/objtool/check.hmodified+10−3View file
tools/objtool/include/objtool/elf.hmodified+1−0View file
tools/objtool/include/objtool/objtool.hmodified+4−0View file
tools/objtool/include/objtool/warn.hmodified+2−0View file
tools/objtool/objtool.cmodified+1−0View file

Only the first 600 diff lines are shown. Download the complete patch.

arch/powerpc/include/asm/livepatch.h

View file
diff --git a/arch/powerpc/include/asm/livepatch.h b/arch/powerpc/include/asm/livepatch.h
index 6f10de6..fd65931 100644
--- a/arch/powerpc/include/asm/livepatch.h
+++ b/arch/powerpc/include/asm/livepatch.h
@@ -17,17 +17,6 @@ static inline void klp_arch_set_pc(struct ftrace_regs *fregs, unsigned long ip)
ftrace_instruction_pointer_set(fregs, ip);
}
-#define klp_get_ftrace_location klp_get_ftrace_location
-static inline unsigned long klp_get_ftrace_location(unsigned long faddr)
-{
- /*
- * Live patch works on PPC32 and only with -mprofile-kernel on PPC64. In
- * both cases, the ftrace location is always within the first 16 bytes.
- */
- return ftrace_location_range(faddr, faddr + 16);
-}
-#endif /* CONFIG_LIVEPATCH */
-
#ifdef CONFIG_LIVEPATCH_64
static inline void klp_init_thread_info(struct task_struct *p)
{

arch/powerpc/kernel/kprobes.c

View file
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 9a492fd..7dae0b0 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -105,6 +105,27 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset)
return addr;
}
+static bool arch_kprobe_on_func_entry(unsigned long offset)
+{
+#ifdef PPC64_ELF_ABI_v2
+#ifdef CONFIG_KPROBES_ON_FTRACE
+ return offset <= 16;
+#else
+ return offset <= 8;
+#endif
+#else
+ return !offset;
+#endif
+}
+
+/* XXX try and fold the magic of kprobe_lookup_name() in this */
+kprobe_opcode_t *arch_adjust_kprobe_addr(unsigned long addr, unsigned long offset,
+ bool *on_func_entry)
+{
+ *on_func_entry = arch_kprobe_on_func_entry(offset);
+ return (kprobe_opcode_t *)(addr + offset);
+}
+
void *alloc_insn_page(void)
{
void *page;
@@ -218,19 +239,6 @@ static nokprobe_inline void set_current_kprobe(struct kprobe *p, struct pt_regs
kcb->kprobe_saved_msr = regs->msr;
}
-bool arch_kprobe_on_func_entry(unsigned long offset)
-{
-#ifdef PPC64_ELF_ABI_v2
-#ifdef CONFIG_KPROBES_ON_FTRACE
- return offset <= 16;
-#else
- return offset <= 8;
-#endif
-#else
- return !offset;
-#endif
-}
-
void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs)
{
ri->ret_addr = (kprobe_opcode_t *)regs->link;

arch/um/kernel/um_arch.c

View file
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index abceeab..0760e24 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -424,6 +424,10 @@ void __init check_bugs(void)
os_check_bugs();
}
+void apply_ibt_endbr(s32 *start, s32 *end)
+{
+}
+
void apply_retpolines(s32 *start, s32 *end)
{
}

arch/x86/Kconfig

View file
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 10e4c33..7340d9f 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1842,6 +1842,36 @@ config X86_UMIP
specific cases in protected and virtual-8086 modes. Emulated
results are dummy.
+config CC_HAS_IBT
+ # GCC >= 9 and binutils >= 2.29
+ # Retpoline check to work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93654
+ # Clang/LLVM >= 14
+ # https://github.com/llvm/llvm-project/commit/e0b89df2e0f0130881bf6c39bf31d7f6aac00e0f
+ # https://github.com/llvm/llvm-project/commit/dfcf69770bc522b9e411c66454934a37c1f35332
+ def_bool ((CC_IS_GCC && $(cc-option, -fcf-protection=branch -mindirect-branch-register)) || \
+ (CC_IS_CLANG && CLANG_VERSION >= 140000)) && \
+ $(as-instr,endbr64)
+
+config X86_KERNEL_IBT
+ prompt "Indirect Branch Tracking"
+ bool
+ depends on X86_64 && CC_HAS_IBT && STACK_VALIDATION
+ # https://github.com/llvm/llvm-project/commit/9d7001eba9c4cb311e03cd8cdc231f9e579f2d0f
+ depends on !LD_IS_LLD || LLD_VERSION >= 140000
+ help
+ Build the kernel with support for Indirect Branch Tracking, a
+ hardware support course-grain forward-edge Control Flow Integrity
+ protection. It enforces that all indirect calls must land on
+ an ENDBR instruction, as such, the compiler will instrument the
+ code with them to make this happen.
+
+ In addition to building the kernel with IBT, seal all functions that
+ are not indirect call targets, avoiding them ever becomming one.
+
+ This requires LTO like objtool runs and will slow down the build. It
+ does significantly reduce the number of ENDBR instructions in the
+ kernel image.
+
config X86_INTEL_MEMORY_PROTECTION_KEYS
prompt "Memory Protection Keys"
def_bool y
@@ -2815,19 +2845,20 @@ config IA32_AOUT
help
Support old a.out binaries in the 32bit emulation.
-config X86_X32
+config X86_X32_ABI
bool "x32 ABI for 64-bit mode"
depends on X86_64
+ # llvm-objcopy does not convert x86_64 .note.gnu.property or
+ # compressed debug sections to x86_x32 properly:
+ # https://github.com/ClangBuiltLinux/linux/issues/514
+ # https://github.com/ClangBuiltLinux/linux/issues/1141
+ depends on $(success,$(OBJCOPY) --version | head -n1 | grep -qv llvm)
help
Include code to run binaries for the x32 native 32-bit ABI
for 64-bit processors. An x32 process gets access to the
full 64-bit register file and wide data path while leaving
pointers at 32 bits for smaller memory footprint.
- You will need a recent binutils (2.22 or later) with
- elf32_x86_64 support enabled to compile a kernel with this
- option set.
-
config COMPAT_32
def_bool y
depends on IA32_EMULATION || X86_32
@@ -2836,7 +2867,7 @@ config COMPAT_32
config COMPAT
def_bool y
- depends on IA32_EMULATION || X86_X32
+ depends on IA32_EMULATION || X86_X32_ABI
if COMPAT
config COMPAT_FOR_U64_ALIGNMENT

arch/x86/Makefile

View file
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index e84cdd4..63d50f6 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -36,7 +36,7 @@ endif
# How to compile the 16-bit code. Note we always compile for -march=i386;
# that way we can complain to the user if the CPU is insufficient.
-REALMODE_CFLAGS := -m16 -g -Os -DDISABLE_BRANCH_PROFILING \
+REALMODE_CFLAGS := -m16 -g -Os -DDISABLE_BRANCH_PROFILING -D__DISABLE_EXPORTS \
-Wall -Wstrict-prototypes -march=i386 -mregparm=3 \
-fno-strict-aliasing -fomit-frame-pointer -fno-pic \
-mno-mmx -mno-sse $(call cc-option,-fcf-protection=none)
@@ -62,8 +62,20 @@ export BITS
#
KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx
-# Intel CET isn't enabled in the kernel
+ifeq ($(CONFIG_X86_KERNEL_IBT),y)
+#
+# Kernel IBT has S_CET.NOTRACK_EN=0, as such the compilers must not generate
+# NOTRACK prefixes. Current generation compilers unconditionally employ NOTRACK
+# for jump-tables, as such, disable jump-tables for now.
+#
+# (jump-tables are implicitly disabled by RETPOLINE)
+#
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104816
+#
+KBUILD_CFLAGS += $(call cc-option,-fcf-protection=branch -fno-jump-tables)
+else
KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none)
+endif
ifeq ($(CONFIG_X86_32),y)
BITS := 32
@@ -140,22 +152,6 @@ else
KBUILD_CFLAGS += -mcmodel=kernel
endif
-ifdef CONFIG_X86_X32
- x32_ld_ok := $(call try-run,\
- /bin/echo -e '1: .quad 1b' | \
- $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" - && \
- $(OBJCOPY) -O elf32-x86-64 "$$TMP" "$$TMP.o" && \
- $(LD) -m elf32_x86_64 "$$TMP.o" -o "$$TMP",y,n)
- ifeq ($(x32_ld_ok),y)
- CONFIG_X86_X32_ABI := y
- KBUILD_AFLAGS += -DCONFIG_X86_X32_ABI
- KBUILD_CFLAGS += -DCONFIG_X86_X32_ABI
- else
- $(warning CONFIG_X86_X32 enabled but no binutils support)
- endif
-endif
-export CONFIG_X86_X32_ABI
-
#
# If the function graph tracer is used with mcount instead of fentry,
# '-maccumulate-outgoing-args' is needed to prevent a GCC bug

arch/x86/crypto/crc32c-pcl-intel-asm_64.S

View file
diff --git a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
index 80c0d22..ec35915 100644
--- a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
+++ b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
@@ -195,6 +195,7 @@ crc_array:
.altmacro
LABEL crc_ %i
.noaltmacro
+ ENDBR
crc32q -i*8(block_0), crc_init
crc32q -i*8(block_1), crc1
crc32q -i*8(block_2), crc2
@@ -204,6 +205,7 @@ LABEL crc_ %i
.altmacro
LABEL crc_ %i
.noaltmacro
+ ENDBR
crc32q -i*8(block_0), crc_init
crc32q -i*8(block_1), crc1
# SKIP crc32 -i*8(block_2), crc2 ; Don't do this one yet
@@ -237,6 +239,7 @@ LABEL crc_ %i
################################################################
LABEL crc_ 0
+ ENDBR
mov tmp, len
cmp $128*24, tmp
jae full_block

arch/x86/entry/entry_64.S

View file
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 466df3e..4faac48 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -86,6 +86,7 @@
SYM_CODE_START(entry_SYSCALL_64)
UNWIND_HINT_EMPTY
+ ENDBR
swapgs
/* tss.sp2 is scratch space. */
@@ -94,6 +95,7 @@ SYM_CODE_START(entry_SYSCALL_64)
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
SYM_INNER_LABEL(entry_SYSCALL_64_safe_stack, SYM_L_GLOBAL)
+ ANNOTATE_NOENDBR
/* Construct struct pt_regs on stack */
pushq $__USER_DS /* pt_regs->ss */
@@ -276,6 +278,7 @@ SYM_FUNC_END(__switch_to_asm)
.pushsection .text, "ax"
SYM_CODE_START(ret_from_fork)
UNWIND_HINT_EMPTY
+ ANNOTATE_NOENDBR // copy_thread
movq %rax, %rdi
call schedule_tail /* rdi: 'prev' task parameter */
@@ -350,6 +353,7 @@ SYM_CODE_END(ret_from_fork)
.macro idtentry vector asmsym cfunc has_error_code:req
SYM_CODE_START(\asmsym)
UNWIND_HINT_IRET_REGS offset=\has_error_code*8
+ ENDBR
ASM_CLAC
.if \has_error_code == 0
@@ -417,6 +421,7 @@ SYM_CODE_END(\asmsym)
.macro idtentry_mce_db vector asmsym cfunc
SYM_CODE_START(\asmsym)
UNWIND_HINT_IRET_REGS
+ ENDBR
ASM_CLAC
pushq $-1 /* ORIG_RAX: no syscall to restart */
@@ -472,6 +477,7 @@ SYM_CODE_END(\asmsym)
.macro idtentry_vc vector asmsym cfunc
SYM_CODE_START(\asmsym)
UNWIND_HINT_IRET_REGS
+ ENDBR
ASM_CLAC
/*
@@ -533,6 +539,7 @@ SYM_CODE_END(\asmsym)
.macro idtentry_df vector asmsym cfunc
SYM_CODE_START(\asmsym)
UNWIND_HINT_IRET_REGS offset=8
+ ENDBR
ASM_CLAC
/* paranoid_entry returns GS information for paranoid_exit in EBX. */
@@ -544,6 +551,9 @@ SYM_CODE_START(\asmsym)
movq $-1, ORIG_RAX(%rsp) /* no syscall to restart */
call \cfunc
+ /* For some configurations \cfunc ends up being a noreturn. */
+ REACHABLE
+
jmp paranoid_exit
_ASM_NOKPROBE(\asmsym)
@@ -564,6 +574,7 @@ __irqentry_text_start:
.align 16
.globl __irqentry_text_end
__irqentry_text_end:
+ ANNOTATE_NOENDBR
SYM_CODE_START_LOCAL(common_interrupt_return)
SYM_INNER_LABEL(swapgs_restore_regs_and_return_to_usermode, SYM_L_GLOBAL)
@@ -608,8 +619,8 @@ SYM_INNER_LABEL(swapgs_restore_regs_and_return_to_usermode, SYM_L_GLOBAL)
/* Restore RDI. */
popq %rdi
- SWAPGS
- INTERRUPT_RETURN
+ swapgs
+ jmp .Lnative_iret
SYM_INNER_LABEL(restore_regs_and_return_to_kernel, SYM_L_GLOBAL)
@@ -626,9 +637,14 @@ SYM_INNER_LABEL(restore_regs_and_return_to_kernel, SYM_L_GLOBAL)
* ARCH_HAS_MEMBARRIER_SYNC_CORE rely on IRET core serialization
* when returning from IPI handler.
*/
- INTERRUPT_RETURN
+#ifdef CONFIG_XEN_PV
+SYM_INNER_LABEL(early_xen_iret_patch, SYM_L_GLOBAL)
+ ANNOTATE_NOENDBR
+ .byte 0xe9
+ .long .Lnative_iret - (. + 4)
+#endif
-SYM_INNER_LABEL_ALIGN(native_iret, SYM_L_GLOBAL)
+.Lnative_iret:
UNWIND_HINT_IRET_REGS
/*
* Are we returning to a stack segment from the LDT? Note: in
@@ -640,6 +656,7 @@ SYM_INNER_LABEL_ALIGN(native_iret, SYM_L_GLOBAL)
#endif
SYM_INNER_LABEL(native_irq_return_iret, SYM_L_GLOBAL)
+ ANNOTATE_NOENDBR // exc_double_fault
/*
* This may fault. Non-paranoid faults on return to userspace are
* handled by fixup_bad_iret. These include #SS, #GP, and #NP.
@@ -734,6 +751,7 @@ SYM_FUNC_START(asm_load_gs_index)
FRAME_BEGIN
swapgs
.Lgs_change:
+ ANNOTATE_NOENDBR // error_entry
movl %edi, %gs
2: ALTERNATIVE "", "mfence", X86_BUG_SWAPGS_FENCE
swapgs
@@ -804,6 +822,7 @@ SYM_CODE_END(exc_xen_hypervisor_callback)
*/
SYM_CODE_START(xen_failsafe_callback)
UNWIND_HINT_EMPTY
+ ENDBR
movl %ds, %ecx
cmpw %cx, 0x10(%rsp)
jne 1f
@@ -1063,6 +1082,7 @@ SYM_CODE_END(error_return)
*/
SYM_CODE_START(asm_exc_nmi)
UNWIND_HINT_IRET_REGS
+ ENDBR
/*
* We allow breakpoints in NMIs. If a breakpoint occurs, then
@@ -1310,6 +1330,7 @@ first_nmi:
#endif
repeat_nmi:
+ ANNOTATE_NOENDBR // this code
/*
* If there was a nested NMI, the first NMI's iret will return
* here. But NMIs are still enabled and we can take another
@@ -1338,6 +1359,7 @@ repeat_nmi:
.endr
subq $(5*8), %rsp
end_repeat_nmi:
+ ANNOTATE_NOENDBR // this code
/*
* Everything below this point can be preempted by a nested NMI.
@@ -1421,6 +1443,7 @@ SYM_CODE_END(asm_exc_nmi)
*/
SYM_CODE_START(ignore_sysret)
UNWIND_HINT_EMPTY
+ ENDBR
mov $-ENOSYS, %eax
sysretl
SYM_CODE_END(ignore_sysret)

arch/x86/entry/entry_64_compat.S

View file
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
index 0051cf5..4fdb007 100644
--- a/arch/x86/entry/entry_64_compat.S
+++ b/arch/x86/entry/entry_64_compat.S
@@ -48,6 +48,7 @@
*/
SYM_CODE_START(entry_SYSENTER_compat)
UNWIND_HINT_EMPTY
+ ENDBR
/* Interrupts are off on entry. */
SWAPGS
@@ -147,6 +148,7 @@ SYM_INNER_LABEL(entry_SYSENTER_compat_after_hwframe, SYM_L_GLOBAL)
popfq
jmp .Lsysenter_flags_fixed
SYM_INNER_LABEL(__end_entry_SYSENTER_compat, SYM_L_GLOBAL)
+ ANNOTATE_NOENDBR // is_sysenter_singlestep
SYM_CODE_END(entry_SYSENTER_compat)
/*
@@ -198,6 +200,7 @@ SYM_CODE_END(entry_SYSENTER_compat)
*/
SYM_CODE_START(entry_SYSCALL_compat)
UNWIND_HINT_EMPTY
+ ENDBR
/* Interrupts are off on entry. */
swapgs
@@ -211,6 +214,7 @@ SYM_CODE_START(entry_SYSCALL_compat)
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
SYM_INNER_LABEL(entry_SYSCALL_compat_safe_stack, SYM_L_GLOBAL)
+ ANNOTATE_NOENDBR
/* Construct struct pt_regs on stack */
pushq $__USER32_DS /* pt_regs->ss */
@@ -340,6 +344,7 @@ SYM_CODE_END(entry_SYSCALL_compat)
*/
SYM_CODE_START(entry_INT80_compat)
UNWIND_HINT_EMPTY
+ ENDBR
/*
* Interrupts are off on entry.
*/

arch/x86/entry/syscalls/Makefile

View file
diff --git a/arch/x86/entry/syscalls/Makefile b/arch/x86/entry/syscalls/Makefile
index 5b3efed..7f3886e 100644
--- a/arch/x86/entry/syscalls/Makefile
+++ b/arch/x86/entry/syscalls/Makefile
@@ -67,7 +67,7 @@ uapisyshdr-y += unistd_32.h unistd_64.h unistd_x32.h
syshdr-y += syscalls_32.h
syshdr-$(CONFIG_X86_64) += unistd_32_ia32.h unistd_64_x32.h
syshdr-$(CONFIG_X86_64) += syscalls_64.h
-syshdr-$(CONFIG_X86_X32) += syscalls_x32.h
+syshdr-$(CONFIG_X86_X32_ABI) += syscalls_x32.h
syshdr-$(CONFIG_XEN) += xen-hypercalls.h
uapisyshdr-y := $(addprefix $(uapi)/, $(uapisyshdr-y))

arch/x86/include/asm/alternative.h

View file
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index 58eee64..9b10c8c 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -76,6 +76,7 @@ extern int alternatives_patched;
extern void alternative_instructions(void);
extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
extern void apply_retpolines(s32 *start, s32 *end);
+extern void apply_ibt_endbr(s32 *start, s32 *end);
struct module;

arch/x86/include/asm/bug.h

View file
diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h
index bab883c..4d20a29 100644
--- a/arch/x86/include/asm/bug.h
+++ b/arch/x86/include/asm/bug.h
@@ -4,6 +4,7 @@
#include <linux/stringify.h>
#include <linux/instrumentation.h>
+#include <linux/objtool.h>
/*
* Despite that some emulators terminate on UD2, we use it for WARN().

arch/x86/include/asm/cpu.h

View file
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index 33d41e3..86e5e4e 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -7,6 +7,7 @@
#include <linux/topology.h>
#include <linux/nodemask.h>
#include <linux/percpu.h>
+#include <asm/ibt.h>
#ifdef CONFIG_SMP
@@ -72,4 +73,7 @@ void init_ia32_feat_ctl(struct cpuinfo_x86 *c);
#else
static inline void init_ia32_feat_ctl(struct cpuinfo_x86 *c) {}
#endif
+
+extern __noendbr void cet_disable(void);
+
#endif /* _ASM_X86_CPU_H */

arch/x86/include/asm/cpufeatures.h

View file
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 3edf05e..73e643a 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -388,6 +388,7 @@
#define X86_FEATURE_TSXLDTRK (18*32+16) /* TSX Suspend Load Address Tracking */
#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
#define X86_FEATURE_ARCH_LBR (18*32+19) /* Intel ARCH LBR */
+#define X86_FEATURE_IBT (18*32+20) /* Indirect Branch Tracking */
#define X86_FEATURE_AMX_BF16 (18*32+22) /* AMX bf16 Support */
#define X86_FEATURE_AVX512_FP16 (18*32+23) /* AVX512 FP16 */
#define X86_FEATURE_AMX_TILE (18*32+24) /* AMX tile Support */

arch/x86/include/asm/efi.h

View file
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 03cb127..98938a6 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -7,6 +7,7 @@
#include <asm/tlb.h>
#include <asm/nospec-branch.h>
#include <asm/mmu_context.h>
+#include <asm/ibt.h>
#include <linux/build_bug.h>
#include <linux/kernel.h>
#include <linux/pgtable.h>
@@ -120,8 +121,12 @@ extern asmlinkage u64 __efi_call(void *fp, ...);
efi_enter_mm(); \
})
-#define arch_efi_call_virt(p, f, args...) \
- efi_call((void *)p->f, args) \
+#define arch_efi_call_virt(p, f, args...) ({ \
+ u64 ret, ibt = ibt_save(); \
+ ret = efi_call((void *)p->f, args); \
+ ibt_restore(ibt); \
+ ret; \
+})
#define arch_efi_call_virt_teardown() \
({ \

arch/x86/include/asm/ibt.h

View file
diff --git a/arch/x86/include/asm/ibt.h b/arch/x86/include/asm/ibt.h
new file mode 100644
index 0000000..689880e
--- /dev/null
+++ b/arch/x86/include/asm/ibt.h
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_X86_IBT_H
+#define _ASM_X86_IBT_H
+
+#include <linux/types.h>
+
+/*
+ * The rules for enabling IBT are:
+ *
+ * - CC_HAS_IBT: the toolchain supports it
+ * - X86_KERNEL_IBT: it is selected in Kconfig
+ * - !__DISABLE_EXPORTS: this is regular kernel code
+ *
+ * Esp. that latter one is a bit non-obvious, but some code like compressed,
+ * purgatory, realmode etc.. is built with custom CFLAGS that do not include
+ * -fcf-protection=branch and things will go *bang*.
+ *
+ * When all the above are satisfied, HAS_KERNEL_IBT will be 1, otherwise 0.
+ */
+#if defined(CONFIG_X86_KERNEL_IBT) && !defined(__DISABLE_EXPORTS)
+
+#define HAS_KERNEL_IBT 1
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_X86_64
+#define ASM_ENDBR "endbr64\n\t"
+#else
+#define ASM_ENDBR "endbr32\n\t"
+#endif
+
+#define __noendbr __attribute__((nocf_check))
+
+static inline __attribute_const__ u32 gen_endbr(void)
+{
+ u32 endbr;
+
+ /*
+ * Generate ENDBR64 in a way that is sure to not result in
+ * an ENDBR64 instruction as immediate.
+ */

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/idtentry.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/irq_stack.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/irqflags.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/linkage.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/msr-index.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/paravirt.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/paravirt_types.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/processor.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/qspinlock_paravirt.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/segment.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/setup.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/syscall_wrapper.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/text-patching.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/traps.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/asm/vdso.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/include/uapi/asm/processor-flags.h

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/alternative.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/apm_32.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/cpu/common.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/ftrace.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/ftrace_64.S

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/head_64.S

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/idt.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/kprobes/core.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/kvm.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/machine_kexec_64.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/module.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/paravirt.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/process.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/process_64.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/relocate_kernel_64.S

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/traps.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/kernel/vmlinux.lds.S

View file

This diff is incomplete. Download the complete patch.

arch/x86/kvm/emulate.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/lib/error-inject.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/lib/retpoline.S

View file

This diff is incomplete. Download the complete patch.

arch/x86/net/bpf_jit_comp.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/platform/efi/Makefile

View file

This diff is incomplete. Download the complete patch.

arch/x86/platform/efi/efi_thunk_64.S

View file

This diff is incomplete. Download the complete patch.

arch/x86/xen/enlighten_pv.c

View file

This diff is incomplete. Download the complete patch.

arch/x86/xen/xen-asm.S

View file

This diff is incomplete. Download the complete patch.

arch/x86/xen/xen-head.S

View file

This diff is incomplete. Download the complete patch.

fs/fuse/ioctl.c

View file

This diff is incomplete. Download the complete patch.

fs/xfs/xfs_ioctl32.c

View file

This diff is incomplete. Download the complete patch.

include/asm-generic/vmlinux.lds.h

View file

This diff is incomplete. Download the complete patch.

include/linux/cfi.h

View file

This diff is incomplete. Download the complete patch.

include/linux/compiler.h

View file

This diff is incomplete. Download the complete patch.

include/linux/cred.h

View file

This diff is incomplete. Download the complete patch.

include/linux/kprobes.h

View file

This diff is incomplete. Download the complete patch.

include/linux/objtool.h

View file

This diff is incomplete. Download the complete patch.

include/linux/sched/task.h

View file

This diff is incomplete. Download the complete patch.

kernel/bpf/trampoline.c

View file

This diff is incomplete. Download the complete patch.

kernel/cred.c

View file

This diff is incomplete. Download the complete patch.

kernel/exit.c

View file

This diff is incomplete. Download the complete patch.

kernel/kprobes.c

View file

This diff is incomplete. Download the complete patch.

kernel/livepatch/patch.c

View file

This diff is incomplete. Download the complete patch.

kernel/trace/ftrace.c

View file

This diff is incomplete. Download the complete patch.

samples/ftrace/ftrace-direct-modify.c

View file

This diff is incomplete. Download the complete patch.

samples/ftrace/ftrace-direct-multi-modify.c

View file

This diff is incomplete. Download the complete patch.

samples/ftrace/ftrace-direct-multi.c

View file

This diff is incomplete. Download the complete patch.

samples/ftrace/ftrace-direct-too.c

View file

This diff is incomplete. Download the complete patch.

samples/ftrace/ftrace-direct.c

View file

This diff is incomplete. Download the complete patch.

scripts/Makefile.build

View file

This diff is incomplete. Download the complete patch.

scripts/Makefile.lib

View file

This diff is incomplete. Download the complete patch.

scripts/link-vmlinux.sh

View file

This diff is incomplete. Download the complete patch.

scripts/mod/modpost.c

View file

This diff is incomplete. Download the complete patch.

sound/core/control_compat.c

View file

This diff is incomplete. Download the complete patch.

sound/core/pcm_compat.c

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/objtool.h

View file

This diff is incomplete. Download the complete patch.

tools/objtool/arch/x86/decode.c

View file

This diff is incomplete. Download the complete patch.

tools/objtool/builtin-check.c

View file

This diff is incomplete. Download the complete patch.

tools/objtool/check.c

View file

This diff is incomplete. Download the complete patch.

tools/objtool/elf.c

View file

This diff is incomplete. Download the complete patch.

tools/objtool/include/objtool/arch.h

View file

This diff is incomplete. Download the complete patch.

tools/objtool/include/objtool/builtin.h

View file

This diff is incomplete. Download the complete patch.

tools/objtool/include/objtool/check.h

View file

This diff is incomplete. Download the complete patch.

tools/objtool/include/objtool/elf.h

View file

This diff is incomplete. Download the complete patch.

tools/objtool/include/objtool/objtool.h

View file

This diff is incomplete. Download the complete patch.

tools/objtool/include/objtool/warn.h

View file

This diff is incomplete. Download the complete patch.

tools/objtool/objtool.c

View file

This diff is incomplete. Download the complete patch.