History

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

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 ...

Linus Torvalds committed 4 years ago

Commit 70010522 parents f022814 3986f6595 files · +1454 −326Browse files

Unified · Split

95 files
  1. arch/powerpc/include/asm/livepatch.h +0 −11
  2. arch/powerpc/kernel/kprobes.c +21 −13
  3. arch/um/kernel/um_arch.c +4 −0
  4. arch/x86/Kconfig +37 −6
  5. arch/x86/Makefile +14 −18
  6. arch/x86/crypto/crc32c-pcl-intel-asm_64.S +3 −0
  7. arch/x86/entry/entry_64.S +27 −4
  8. arch/x86/entry/entry_64_compat.S +5 −0
  9. arch/x86/entry/syscalls/Makefile +1 −1
  10. arch/x86/include/asm/alternative.h +1 −0
  11. arch/x86/include/asm/bug.h +1 −0
  12. arch/x86/include/asm/cpu.h +4 −0
  13. arch/x86/include/asm/cpufeatures.h +1 −0
  14. arch/x86/include/asm/efi.h +7 −2
  15. arch/x86/include/asm/ibt.h +105 −0
  16. arch/x86/include/asm/idtentry.h +16 −9
  17. arch/x86/include/asm/irq_stack.h +3 −1
  18. arch/x86/include/asm/irqflags.h +0 −5
  19. arch/x86/include/asm/linkage.h +31 −0
  20. arch/x86/include/asm/msr-index.h +19 −1
  21. arch/x86/include/asm/paravirt.h +1 −0
  22. arch/x86/include/asm/paravirt_types.h +0 −1
  23. arch/x86/include/asm/processor.h +1 −1
  24. arch/x86/include/asm/qspinlock_paravirt.h +3 −0
  25. arch/x86/include/asm/segment.h +3 −2
  26. arch/x86/include/asm/setup.h +2 −1
  27. arch/x86/include/asm/syscall_wrapper.h +3 −3
  28. arch/x86/include/asm/text-patching.h +23 −7
  29. arch/x86/include/asm/traps.h +2 −0
  30. arch/x86/include/asm/vdso.h +1 −1
  31. arch/x86/include/uapi/asm/processor-flags.h +2 −0
  32. arch/x86/kernel/alternative.c +52 −14
  33. arch/x86/kernel/apm_32.c +7 −0
  34. arch/x86/kernel/cpu/common.c +58 −1
  35. arch/x86/kernel/ftrace.c +2 −7
  36. arch/x86/kernel/ftrace_64.S +24 −4
  37. arch/x86/kernel/head_64.S +12 −2
  38. arch/x86/kernel/idt.c +7 −2
  39. arch/x86/kernel/kprobes/core.c +20 −9
  40. arch/x86/kernel/kvm.c +2 −1
  41. arch/x86/kernel/machine_kexec_64.c +3 −1
  42. arch/x86/kernel/module.c +7 −1
  43. arch/x86/kernel/paravirt.c +5 −24
  44. arch/x86/kernel/process.c +1 −1
  45. arch/x86/kernel/process_64.c +1 −1
  46. arch/x86/kernel/relocate_kernel_64.S +10 −0
  47. arch/x86/kernel/traps.c +75 −0
  48. arch/x86/kernel/vmlinux.lds.S +9 −0
  49. arch/x86/kvm/emulate.c +10 −6
  50. arch/x86/lib/error-inject.c +2 −0
  51. arch/x86/lib/retpoline.S +1 −0
  52. arch/x86/net/bpf_jit_comp.c +24 −2
  53. arch/x86/platform/efi/Makefile +0 −1
  54. arch/x86/platform/efi/efi_thunk_64.S +4 −2
  55. arch/x86/xen/enlighten_pv.c +9 −1
  56. arch/x86/xen/xen-asm.S +10 −0
  57. arch/x86/xen/xen-head.S +7 −2
  58. fs/fuse/ioctl.c +1 −1
  59. fs/xfs/xfs_ioctl32.c +1 −1
  60. include/asm-generic/vmlinux.lds.h +4 −0
  61. include/linux/cfi.h +10 −1
  62. include/linux/compiler.h +0 −7
  63. include/linux/cred.h +1 −1
  64. include/linux/kprobes.h +2 −1
  65. include/linux/objtool.h +32 −0
  66. include/linux/sched/task.h +1 −1
  67. kernel/bpf/trampoline.c +4 −16
  68. kernel/cred.c +1 −1
  69. kernel/exit.c +1 −1
  70. kernel/kprobes.c +54 −20
  71. kernel/livepatch/patch.c +2 −17
  72. kernel/trace/ftrace.c +40 −8
  73. samples/ftrace/ftrace-direct-modify.c +5 −0
  74. samples/ftrace/ftrace-direct-multi-modify.c +7 −3
  75. samples/ftrace/ftrace-direct-multi.c +4 −1
  76. samples/ftrace/ftrace-direct-too.c +3 −0
  77. samples/ftrace/ftrace-direct.c +3 −0
  78. scripts/Makefile.build +14 −13
  79. scripts/Makefile.lib +2 −2
  80. scripts/link-vmlinux.sh +9 −3
  81. scripts/mod/modpost.c +6 −6
  82. sound/core/control_compat.c +8 −8
  83. sound/core/pcm_compat.c +10 −10
  84. tools/include/linux/objtool.h +32 −0
  85. tools/objtool/arch/x86/decode.c +29 −5
  86. tools/objtool/builtin-check.c +5 −2
  87. tools/objtool/check.c +376 −24
  88. tools/objtool/elf.c +63 −0
  89. tools/objtool/include/objtool/arch.h +1 −0
  90. tools/objtool/include/objtool/builtin.h +2 −1
  91. tools/objtool/include/objtool/check.h +10 −3
  92. tools/objtool/include/objtool/elf.h +1 −0
  93. tools/objtool/include/objtool/objtool.h +4 −0
  94. tools/objtool/include/objtool/warn.h +2 −0
  95. tools/objtool/objtool.c +1 −0
arch/powerpc/include/asm/livepatch.h+0−11
@@ -17,17 +17,6 @@ static inline void klp_arch_set_pc(struct ftrace_regs *fregs, unsigned long ip) · 16 unmodified lines
1717 ftrace_instruction_pointer_set(fregs, ip);
1818 }
1919
20−#define klp_get_ftrace_location klp_get_ftrace_location
21−static inline unsigned long klp_get_ftrace_location(unsigned long faddr)
22−{
23− /*
24− * Live patch works on PPC32 and only with -mprofile-kernel on PPC64. In
25− * both cases, the ftrace location is always within the first 16 bytes.
26− */
27− return ftrace_location_range(faddr, faddr + 16);
28−}
29−#endif /* CONFIG_LIVEPATCH */
30−
3120 #ifdef CONFIG_LIVEPATCH_64
3221 static inline void klp_init_thread_info(struct task_struct *p)
3322 {
arch/powerpc/kernel/kprobes.c+21−13
@@ -105,6 +105,27 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset) · 104 unmodified lines
105105 return addr;
106106 }
107107
108+static bool arch_kprobe_on_func_entry(unsigned long offset)
109+{
110+#ifdef PPC64_ELF_ABI_v2
111+#ifdef CONFIG_KPROBES_ON_FTRACE
112+ return offset <= 16;
113+#else
114+ return offset <= 8;
115+#endif
116+#else
117+ return !offset;
118+#endif
119+}
120+
121+/* XXX try and fold the magic of kprobe_lookup_name() in this */
122+kprobe_opcode_t *arch_adjust_kprobe_addr(unsigned long addr, unsigned long offset,
123+ bool *on_func_entry)
124+{
125+ *on_func_entry = arch_kprobe_on_func_entry(offset);
126+ return (kprobe_opcode_t *)(addr + offset);
127+}
128+
108129 void *alloc_insn_page(void)
109130 {
110131 void *page;
@@ -218,19 +239,6 @@ static nokprobe_inline void set_current_kprobe(struct kprobe *p, struct pt_regs · 107 unmodified lines
218239 kcb->kprobe_saved_msr = regs->msr;
219240 }
220241
221−bool arch_kprobe_on_func_entry(unsigned long offset)
222−{
223−#ifdef PPC64_ELF_ABI_v2
224−#ifdef CONFIG_KPROBES_ON_FTRACE
225− return offset <= 16;
226−#else
227− return offset <= 8;
228−#endif
229−#else
230− return !offset;
231−#endif
232−}
233−
234242 void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs)
235243 {
236244 ri->ret_addr = (kprobe_opcode_t *)regs->link;
arch/um/kernel/um_arch.c+4−0
@@ -424,6 +424,10 @@ void __init check_bugs(void) · 423 unmodified lines
424424 os_check_bugs();
425425 }
426426
427+void apply_ibt_endbr(s32 *start, s32 *end)
428+{
429+}
430+
427431 void apply_retpolines(s32 *start, s32 *end)
428432 {
429433 }
arch/x86/Kconfig+37−6
@@ -1842,6 +1842,36 @@ config X86_UMIP · 1841 unmodified lines
18421842 specific cases in protected and virtual-8086 modes. Emulated
18431843 results are dummy.
18441844
1845+config CC_HAS_IBT
1846+ # GCC >= 9 and binutils >= 2.29
1847+ # Retpoline check to work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93654
1848+ # Clang/LLVM >= 14
1849+ # https://github.com/llvm/llvm-project/commit/e0b89df2e0f0130881bf6c39bf31d7f6aac00e0f
1850+ # https://github.com/llvm/llvm-project/commit/dfcf69770bc522b9e411c66454934a37c1f35332
1851+ def_bool ((CC_IS_GCC && $(cc-option, -fcf-protection=branch -mindirect-branch-register)) || \
1852+ (CC_IS_CLANG && CLANG_VERSION >= 140000)) && \
1853+ $(as-instr,endbr64)
1854+
1855+config X86_KERNEL_IBT
1856+ prompt "Indirect Branch Tracking"
1857+ bool
1858+ depends on X86_64 && CC_HAS_IBT && STACK_VALIDATION
1859+ # https://github.com/llvm/llvm-project/commit/9d7001eba9c4cb311e03cd8cdc231f9e579f2d0f
1860+ depends on !LD_IS_LLD || LLD_VERSION >= 140000
1861+ help
1862+ Build the kernel with support for Indirect Branch Tracking, a
1863+ hardware support course-grain forward-edge Control Flow Integrity
1864+ protection. It enforces that all indirect calls must land on
1865+ an ENDBR instruction, as such, the compiler will instrument the
1866+ code with them to make this happen.
1867+
1868+ In addition to building the kernel with IBT, seal all functions that
1869+ are not indirect call targets, avoiding them ever becomming one.
1870+
1871+ This requires LTO like objtool runs and will slow down the build. It
1872+ does significantly reduce the number of ENDBR instructions in the
1873+ kernel image.
1874+
18451875 config X86_INTEL_MEMORY_PROTECTION_KEYS
18461876 prompt "Memory Protection Keys"
18471877 def_bool y
@@ -2815,19 +2845,20 @@ config IA32_AOUT · 967 unmodified lines
28152845 help
28162846 Support old a.out binaries in the 32bit emulation.
28172847
2818−config X86_X32
2848+config X86_X32_ABI
28192849 bool "x32 ABI for 64-bit mode"
28202850 depends on X86_64
2851+ # llvm-objcopy does not convert x86_64 .note.gnu.property or
2852+ # compressed debug sections to x86_x32 properly:
2853+ # https://github.com/ClangBuiltLinux/linux/issues/514
2854+ # https://github.com/ClangBuiltLinux/linux/issues/1141
2855+ depends on $(success,$(OBJCOPY) --version | head -n1 | grep -qv llvm)
28212856 help
28222857 Include code to run binaries for the x32 native 32-bit ABI
28232858 for 64-bit processors. An x32 process gets access to the
28242859 full 64-bit register file and wide data path while leaving
28252860 pointers at 32 bits for smaller memory footprint.
28262861
2827− You will need a recent binutils (2.22 or later) with
2828− elf32_x86_64 support enabled to compile a kernel with this
2829− option set.
2830−
28312862 config COMPAT_32
28322863 def_bool y
28332864 depends on IA32_EMULATION || X86_32
@@ -2836,7 +2867,7 @@ config COMPAT_32 · 2 unmodified lines
28362867
28372868 config COMPAT
28382869 def_bool y
2839− depends on IA32_EMULATION || X86_X32
2870+ depends on IA32_EMULATION || X86_X32_ABI
28402871
28412872 if COMPAT
28422873 config COMPAT_FOR_U64_ALIGNMENT
arch/x86/Makefile+14−18
@@ -36,7 +36,7 @@ endif · 35 unmodified lines
3636
3737 # How to compile the 16-bit code. Note we always compile for -march=i386;
3838 # that way we can complain to the user if the CPU is insufficient.
39−REALMODE_CFLAGS := -m16 -g -Os -DDISABLE_BRANCH_PROFILING \
39+REALMODE_CFLAGS := -m16 -g -Os -DDISABLE_BRANCH_PROFILING -D__DISABLE_EXPORTS \
4040 -Wall -Wstrict-prototypes -march=i386 -mregparm=3 \
4141 -fno-strict-aliasing -fomit-frame-pointer -fno-pic \
4242 -mno-mmx -mno-sse $(call cc-option,-fcf-protection=none)
@@ -62,8 +62,20 @@ export BITS · 19 unmodified lines
6262 #
6363 KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx
6464
65−# Intel CET isn't enabled in the kernel
65+ifeq ($(CONFIG_X86_KERNEL_IBT),y)
66+#
67+# Kernel IBT has S_CET.NOTRACK_EN=0, as such the compilers must not generate
68+# NOTRACK prefixes. Current generation compilers unconditionally employ NOTRACK
69+# for jump-tables, as such, disable jump-tables for now.
70+#
71+# (jump-tables are implicitly disabled by RETPOLINE)
72+#
73+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104816
74+#
75+KBUILD_CFLAGS += $(call cc-option,-fcf-protection=branch -fno-jump-tables)
76+else
6677 KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none)
78+endif
6779
6880 ifeq ($(CONFIG_X86_32),y)
6981 BITS := 32
@@ -140,22 +152,6 @@ else · 70 unmodified lines
140152 KBUILD_CFLAGS += -mcmodel=kernel
141153 endif
142154
143−ifdef CONFIG_X86_X32
144− x32_ld_ok := $(call try-run,\
145− /bin/echo -e '1: .quad 1b' | \
146− $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" - && \
147− $(OBJCOPY) -O elf32-x86-64 "$$TMP" "$$TMP.o" && \
148− $(LD) -m elf32_x86_64 "$$TMP.o" -o "$$TMP",y,n)
149− ifeq ($(x32_ld_ok),y)
150− CONFIG_X86_X32_ABI := y
151− KBUILD_AFLAGS += -DCONFIG_X86_X32_ABI
152− KBUILD_CFLAGS += -DCONFIG_X86_X32_ABI
153− else
154− $(warning CONFIG_X86_X32 enabled but no binutils support)
155− endif
156−endif
157−export CONFIG_X86_X32_ABI
158−
159155 #
160156 # If the function graph tracer is used with mcount instead of fentry,
161157 # '-maccumulate-outgoing-args' is needed to prevent a GCC bug
arch/x86/crypto/crc32c-pcl-intel-asm_64.S+3−0
@@ -195,6 +195,7 @@ crc_array: · 194 unmodified lines
195195 .altmacro
196196 LABEL crc_ %i
197197 .noaltmacro
198+ ENDBR
198199 crc32q -i*8(block_0), crc_init
199200 crc32q -i*8(block_1), crc1
200201 crc32q -i*8(block_2), crc2
@@ -204,6 +205,7 @@ LABEL crc_ %i · 3 unmodified lines
204205 .altmacro
205206 LABEL crc_ %i
206207 .noaltmacro
208+ ENDBR
207209 crc32q -i*8(block_0), crc_init
208210 crc32q -i*8(block_1), crc1
209211 # SKIP crc32 -i*8(block_2), crc2 ; Don't do this one yet
@@ -237,6 +239,7 @@ LABEL crc_ %i · 27 unmodified lines
237239 ################################################################
238240
239241 LABEL crc_ 0
242+ ENDBR
240243 mov tmp, len
241244 cmp $128*24, tmp
242245 jae full_block
arch/x86/entry/entry_64.S+27−4
@@ -86,6 +86,7 @@ · 85 unmodified lines
8686
8787 SYM_CODE_START(entry_SYSCALL_64)
8888 UNWIND_HINT_EMPTY
89+ ENDBR
8990
9091 swapgs
9192 /* tss.sp2 is scratch space. */
@@ -94,6 +95,7 @@ SYM_CODE_START(entry_SYSCALL_64) · 2 unmodified lines
9495 movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
9596
9697 SYM_INNER_LABEL(entry_SYSCALL_64_safe_stack, SYM_L_GLOBAL)
98+ ANNOTATE_NOENDBR
9799
98100 /* Construct struct pt_regs on stack */
99101 pushq $__USER_DS /* pt_regs->ss */
@@ -276,6 +278,7 @@ SYM_FUNC_END(__switch_to_asm) · 176 unmodified lines
276278 .pushsection .text, "ax"
277279 SYM_CODE_START(ret_from_fork)
278280 UNWIND_HINT_EMPTY
281+ ANNOTATE_NOENDBR // copy_thread
279282 movq %rax, %rdi
280283 call schedule_tail /* rdi: 'prev' task parameter */
281284
@@ -350,6 +353,7 @@ SYM_CODE_END(ret_from_fork) · 68 unmodified lines
350353 .macro idtentry vector asmsym cfunc has_error_code:req
351354 SYM_CODE_START(\asmsym)
352355 UNWIND_HINT_IRET_REGS offset=\has_error_code*8
356+ ENDBR
353357 ASM_CLAC
354358
355359 .if \has_error_code == 0
@@ -417,6 +421,7 @@ SYM_CODE_END(\asmsym) · 61 unmodified lines
417421 .macro idtentry_mce_db vector asmsym cfunc
418422 SYM_CODE_START(\asmsym)
419423 UNWIND_HINT_IRET_REGS
424+ ENDBR
420425 ASM_CLAC
421426
422427 pushq $-1 /* ORIG_RAX: no syscall to restart */
@@ -472,6 +477,7 @@ SYM_CODE_END(\asmsym) · 49 unmodified lines
472477 .macro idtentry_vc vector asmsym cfunc
473478 SYM_CODE_START(\asmsym)
474479 UNWIND_HINT_IRET_REGS
480+ ENDBR
475481 ASM_CLAC
476482
477483 /*
@@ -533,6 +539,7 @@ SYM_CODE_END(\asmsym) · 55 unmodified lines
533539 .macro idtentry_df vector asmsym cfunc
534540 SYM_CODE_START(\asmsym)
535541 UNWIND_HINT_IRET_REGS offset=8
542+ ENDBR
536543 ASM_CLAC
537544
538545 /* paranoid_entry returns GS information for paranoid_exit in EBX. */
@@ -544,6 +551,9 @@ SYM_CODE_START(\asmsym) · 5 unmodified lines
544551 movq $-1, ORIG_RAX(%rsp) /* no syscall to restart */
545552 call \cfunc
546553
554+ /* For some configurations \cfunc ends up being a noreturn. */
555+ REACHABLE
556+
547557 jmp paranoid_exit
548558
549559 _ASM_NOKPROBE(\asmsym)
@@ -564,6 +574,7 @@ __irqentry_text_start: · 14 unmodified lines
564574 .align 16
565575 .globl __irqentry_text_end
566576 __irqentry_text_end:
577+ ANNOTATE_NOENDBR
567578
568579 SYM_CODE_START_LOCAL(common_interrupt_return)
569580 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) · 38 unmodified lines
608619
609620 /* Restore RDI. */
610621 popq %rdi
611− SWAPGS
612− INTERRUPT_RETURN
622+ swapgs
623+ jmp .Lnative_iret
613624
614625
615626 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) · 10 unmodified lines
626637 * ARCH_HAS_MEMBARRIER_SYNC_CORE rely on IRET core serialization
627638 * when returning from IPI handler.
628639 */
629− INTERRUPT_RETURN
640+#ifdef CONFIG_XEN_PV
641+SYM_INNER_LABEL(early_xen_iret_patch, SYM_L_GLOBAL)
642+ ANNOTATE_NOENDBR
643+ .byte 0xe9
644+ .long .Lnative_iret - (. + 4)
645+#endif
630646
631−SYM_INNER_LABEL_ALIGN(native_iret, SYM_L_GLOBAL)
647+.Lnative_iret:
632648 UNWIND_HINT_IRET_REGS
633649 /*
634650 * 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) · 5 unmodified lines
640656 #endif
641657
642658 SYM_INNER_LABEL(native_irq_return_iret, SYM_L_GLOBAL)
659+ ANNOTATE_NOENDBR // exc_double_fault
643660 /*
644661 * This may fault. Non-paranoid faults on return to userspace are
645662 * handled by fixup_bad_iret. These include #SS, #GP, and #NP.
@@ -734,6 +751,7 @@ SYM_FUNC_START(asm_load_gs_index) · 88 unmodified lines
734751 FRAME_BEGIN
735752 swapgs
736753 .Lgs_change:
754+ ANNOTATE_NOENDBR // error_entry
737755 movl %edi, %gs
738756 2: ALTERNATIVE "", "mfence", X86_BUG_SWAPGS_FENCE
739757 swapgs
@@ -804,6 +822,7 @@ SYM_CODE_END(exc_xen_hypervisor_callback) · 64 unmodified lines
804822 */
805823 SYM_CODE_START(xen_failsafe_callback)
806824 UNWIND_HINT_EMPTY
825+ ENDBR
807826 movl %ds, %ecx
808827 cmpw %cx, 0x10(%rsp)
809828 jne 1f
@@ -1063,6 +1082,7 @@ SYM_CODE_END(error_return) · 253 unmodified lines
10631082 */
10641083 SYM_CODE_START(asm_exc_nmi)
10651084 UNWIND_HINT_IRET_REGS
1085+ ENDBR
10661086
10671087 /*
10681088 * We allow breakpoints in NMIs. If a breakpoint occurs, then
@@ -1310,6 +1330,7 @@ first_nmi: · 241 unmodified lines
13101330 #endif
13111331
13121332 repeat_nmi:
1333+ ANNOTATE_NOENDBR // this code
13131334 /*
13141335 * If there was a nested NMI, the first NMI's iret will return
13151336 * here. But NMIs are still enabled and we can take another
@@ -1338,6 +1359,7 @@ repeat_nmi: · 22 unmodified lines
13381359 .endr
13391360 subq $(5*8), %rsp
13401361 end_repeat_nmi:
1362+ ANNOTATE_NOENDBR // this code
13411363
13421364 /*
13431365 * Everything below this point can be preempted by a nested NMI.
@@ -1421,6 +1443,7 @@ SYM_CODE_END(asm_exc_nmi) · 77 unmodified lines
14211443 */
14221444 SYM_CODE_START(ignore_sysret)
14231445 UNWIND_HINT_EMPTY
1446+ ENDBR
14241447 mov $-ENOSYS, %eax
14251448 sysretl
14261449 SYM_CODE_END(ignore_sysret)
arch/x86/entry/entry_64_compat.S+5−0
@@ -48,6 +48,7 @@ · 47 unmodified lines
4848 */
4949 SYM_CODE_START(entry_SYSENTER_compat)
5050 UNWIND_HINT_EMPTY
51+ ENDBR
5152 /* Interrupts are off on entry. */
5253 SWAPGS
5354
@@ -147,6 +148,7 @@ SYM_INNER_LABEL(entry_SYSENTER_compat_after_hwframe, SYM_L_GLOBAL) · 93 unmodified lines
147148 popfq
148149 jmp .Lsysenter_flags_fixed
149150 SYM_INNER_LABEL(__end_entry_SYSENTER_compat, SYM_L_GLOBAL)
151+ ANNOTATE_NOENDBR // is_sysenter_singlestep
150152 SYM_CODE_END(entry_SYSENTER_compat)
151153
152154 /*
@@ -198,6 +200,7 @@ SYM_CODE_END(entry_SYSENTER_compat) · 45 unmodified lines
198200 */
199201 SYM_CODE_START(entry_SYSCALL_compat)
200202 UNWIND_HINT_EMPTY
203+ ENDBR
201204 /* Interrupts are off on entry. */
202205 swapgs
203206
@@ -211,6 +214,7 @@ SYM_CODE_START(entry_SYSCALL_compat) · 7 unmodified lines
211214 movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
212215
213216 SYM_INNER_LABEL(entry_SYSCALL_compat_safe_stack, SYM_L_GLOBAL)
217+ ANNOTATE_NOENDBR
214218
215219 /* Construct struct pt_regs on stack */
216220 pushq $__USER32_DS /* pt_regs->ss */
@@ -340,6 +344,7 @@ SYM_CODE_END(entry_SYSCALL_compat) · 123 unmodified lines
340344 */
341345 SYM_CODE_START(entry_INT80_compat)
342346 UNWIND_HINT_EMPTY
347+ ENDBR
343348 /*
344349 * Interrupts are off on entry.
345350 */
arch/x86/entry/syscalls/Makefile+1−1
@@ -67,7 +67,7 @@ uapisyshdr-y += unistd_32.h unistd_64.h unistd_x32.h · 66 unmodified lines
6767 syshdr-y += syscalls_32.h
6868 syshdr-$(CONFIG_X86_64) += unistd_32_ia32.h unistd_64_x32.h
6969 syshdr-$(CONFIG_X86_64) += syscalls_64.h
70−syshdr-$(CONFIG_X86_X32) += syscalls_x32.h
70+syshdr-$(CONFIG_X86_X32_ABI) += syscalls_x32.h
7171 syshdr-$(CONFIG_XEN) += xen-hypercalls.h
7272
7373 uapisyshdr-y := $(addprefix $(uapi)/, $(uapisyshdr-y))
arch/x86/include/asm/alternative.h+1−0
@@ -76,6 +76,7 @@ extern int alternatives_patched; · 75 unmodified lines
7676 extern void alternative_instructions(void);
7777 extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
7878 extern void apply_retpolines(s32 *start, s32 *end);
79+extern void apply_ibt_endbr(s32 *start, s32 *end);
7980
8081 struct module;
8182
arch/x86/include/asm/bug.h+1−0
@@ -4,6 +4,7 @@ · 3 unmodified lines
44
55 #include <linux/stringify.h>
66 #include <linux/instrumentation.h>
7+#include <linux/objtool.h>
78
89 /*
910 * Despite that some emulators terminate on UD2, we use it for WARN().
arch/x86/include/asm/cpu.h+4−0
@@ -7,6 +7,7 @@ · 6 unmodified lines
77 #include <linux/topology.h>
88 #include <linux/nodemask.h>
99 #include <linux/percpu.h>
10+#include <asm/ibt.h>
1011
1112 #ifdef CONFIG_SMP
1213
@@ -72,4 +73,7 @@ void init_ia32_feat_ctl(struct cpuinfo_x86 *c); · 59 unmodified lines
7273 #else
7374 static inline void init_ia32_feat_ctl(struct cpuinfo_x86 *c) {}
7475 #endif
76+
77+extern __noendbr void cet_disable(void);
78+
7579 #endif /* _ASM_X86_CPU_H */
arch/x86/include/asm/cpufeatures.h+1−0
@@ -388,6 +388,7 @@ · 387 unmodified lines
388388 #define X86_FEATURE_TSXLDTRK (18*32+16) /* TSX Suspend Load Address Tracking */
389389 #define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
390390 #define X86_FEATURE_ARCH_LBR (18*32+19) /* Intel ARCH LBR */
391+#define X86_FEATURE_IBT (18*32+20) /* Indirect Branch Tracking */
391392 #define X86_FEATURE_AMX_BF16 (18*32+22) /* AMX bf16 Support */
392393 #define X86_FEATURE_AVX512_FP16 (18*32+23) /* AVX512 FP16 */
393394 #define X86_FEATURE_AMX_TILE (18*32+24) /* AMX tile Support */
arch/x86/include/asm/efi.h+7−2
@@ -7,6 +7,7 @@ · 6 unmodified lines
77 #include <asm/tlb.h>
88 #include <asm/nospec-branch.h>
99 #include <asm/mmu_context.h>
10+#include <asm/ibt.h>
1011 #include <linux/build_bug.h>
1112 #include <linux/kernel.h>
1213 #include <linux/pgtable.h>
@@ -120,8 +121,12 @@ extern asmlinkage u64 __efi_call(void *fp, ...); · 107 unmodified lines
120121 efi_enter_mm(); \
121122 })
122123
123−#define arch_efi_call_virt(p, f, args...) \
124− efi_call((void *)p->f, args) \
124+#define arch_efi_call_virt(p, f, args...) ({ \
125+ u64 ret, ibt = ibt_save(); \
126+ ret = efi_call((void *)p->f, args); \
127+ ibt_restore(ibt); \
128+ ret; \
129+})
125130
126131 #define arch_efi_call_virt_teardown() \
127132 ({ \
arch/x86/include/asm/ibt.h+105−0
@@ -0,0 +1,105 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+#ifndef _ASM_X86_IBT_H
3+#define _ASM_X86_IBT_H
4+
5+#include <linux/types.h>
6+
7+/*
8+ * The rules for enabling IBT are:
9+ *
10+ * - CC_HAS_IBT: the toolchain supports it
11+ * - X86_KERNEL_IBT: it is selected in Kconfig
12+ * - !__DISABLE_EXPORTS: this is regular kernel code
13+ *
14+ * Esp. that latter one is a bit non-obvious, but some code like compressed,
15+ * purgatory, realmode etc.. is built with custom CFLAGS that do not include
16+ * -fcf-protection=branch and things will go *bang*.
17+ *
18+ * When all the above are satisfied, HAS_KERNEL_IBT will be 1, otherwise 0.
19+ */
20+#if defined(CONFIG_X86_KERNEL_IBT) && !defined(__DISABLE_EXPORTS)
21+
22+#define HAS_KERNEL_IBT 1
23+
24+#ifndef __ASSEMBLY__
25+
26+#ifdef CONFIG_X86_64
27+#define ASM_ENDBR "endbr64\n\t"
28+#else
29+#define ASM_ENDBR "endbr32\n\t"
30+#endif
31+
32+#define __noendbr __attribute__((nocf_check))
33+
34+static inline __attribute_const__ u32 gen_endbr(void)
35+{
36+ u32 endbr;
37+
38+ /*
39+ * Generate ENDBR64 in a way that is sure to not result in
40+ * an ENDBR64 instruction as immediate.
41+ */
42+ asm ( "mov $~0xfa1e0ff3, %[endbr]\n\t"
43+ "not %[endbr]\n\t"
44+ : [endbr] "=&r" (endbr) );
45+
46+ return endbr;
47+}
48+
49+static inline __attribute_const__ u32 gen_endbr_poison(void)
50+{
51+ /*
52+ * 4 byte NOP that isn't NOP4 (in fact it is OSP NOP3), such that it
53+ * will be unique to (former) ENDBR sites.
54+ */
55+ return 0x001f0f66; /* osp nopl (%rax) */
56+}
57+
58+static inline bool is_endbr(u32 val)
59+{
60+ if (val == gen_endbr_poison())
61+ return true;
62+
63+ val &= ~0x01000000U; /* ENDBR32 -> ENDBR64 */
64+ return val == gen_endbr();
65+}
66+
67+extern __noendbr u64 ibt_save(void);
68+extern __noendbr void ibt_restore(u64 save);
69+
70+#else /* __ASSEMBLY__ */
71+
72+#ifdef CONFIG_X86_64
73+#define ENDBR endbr64
74+#else
75+#define ENDBR endbr32
76+#endif
77+
78+#endif /* __ASSEMBLY__ */
79+
80+#else /* !IBT */
81+
82+#define HAS_KERNEL_IBT 0
83+
84+#ifndef __ASSEMBLY__
85+
86+#define ASM_ENDBR
87+
88+#define __noendbr
89+
90+static inline bool is_endbr(u32 val) { return false; }
91+
92+static inline u64 ibt_save(void) { return 0; }
93+static inline void ibt_restore(u64 save) { }
94+
95+#else /* __ASSEMBLY__ */
96+
97+#define ENDBR
98+
99+#endif /* __ASSEMBLY__ */
100+
101+#endif /* CONFIG_X86_KERNEL_IBT */
102+
103+#define ENDBR_INSN_SIZE (4*HAS_KERNEL_IBT)
104+
105+#endif /* _ASM_X86_IBT_H */
arch/x86/include/asm/idtentry.h+16−9
@@ -5,6 +5,8 @@ · 4 unmodified lines
55 /* Interrupts/Exceptions */
66 #include <asm/trapnr.h>
77
8+#define IDT_ALIGN (8 * (1 + HAS_KERNEL_IBT))
9+
810 #ifndef __ASSEMBLY__
911 #include <linux/entry-common.h>
1012 #include <linux/hardirq.h>
@@ -480,7 +482,7 @@ __visible noinstr void func(struct pt_regs *regs, \ · 469 unmodified lines
480482
481483 /*
482484 * ASM code to emit the common vector entry stubs where each stub is
483− * packed into 8 bytes.
485+ * packed into IDT_ALIGN bytes.
484486 *
485487 * Note, that the 'pushq imm8' is emitted via '.byte 0x6a, vector' because
486488 * GCC treats the local vector variable as unsigned int and would expand
@@ -492,33 +494,33 @@ __visible noinstr void func(struct pt_regs *regs, \ · 5 unmodified lines
492494 * point is to mask off the bits above bit 7 because the push is sign
493495 * extending.
494496 */
495− .align 8
497+ .align IDT_ALIGN
496498 SYM_CODE_START(irq_entries_start)
497499 vector=FIRST_EXTERNAL_VECTOR
498500 .rept NR_EXTERNAL_VECTORS
499501 UNWIND_HINT_IRET_REGS
500502 0 :
503+ ENDBR
501504 .byte 0x6a, vector
502505 jmp asm_common_interrupt
503− nop
504− /* Ensure that the above is 8 bytes max */
505− . = 0b + 8
506+ /* Ensure that the above is IDT_ALIGN bytes max */
507+ .fill 0b + IDT_ALIGN - ., 1, 0xcc
506508 vector = vector+1
507509 .endr
508510 SYM_CODE_END(irq_entries_start)
509511
510512 #ifdef CONFIG_X86_LOCAL_APIC
511− .align 8
513+ .align IDT_ALIGN
512514 SYM_CODE_START(spurious_entries_start)
513515 vector=FIRST_SYSTEM_VECTOR
514516 .rept NR_SYSTEM_VECTORS
515517 UNWIND_HINT_IRET_REGS
516518 0 :
519+ ENDBR
517520 .byte 0x6a, vector
518521 jmp asm_spurious_interrupt
519− nop
520− /* Ensure that the above is 8 bytes max */
521− . = 0b + 8
522+ /* Ensure that the above is IDT_ALIGN bytes max */
523+ .fill 0b + IDT_ALIGN - ., 1, 0xcc
522524 vector = vector+1
523525 .endr
524526 SYM_CODE_END(spurious_entries_start)
@@ -615,6 +617,11 @@ DECLARE_IDTENTRY_DF(X86_TRAP_DF, exc_double_fault); · 90 unmodified lines
615617 DECLARE_IDTENTRY_RAW_ERRORCODE(X86_TRAP_DF, xenpv_exc_double_fault);
616618 #endif
617619
620+/* #CP */
621+#ifdef CONFIG_X86_KERNEL_IBT
622+DECLARE_IDTENTRY_ERRORCODE(X86_TRAP_CP, exc_control_protection);
623+#endif
624+
618625 /* #VC */
619626 #ifdef CONFIG_AMD_MEM_ENCRYPT
620627 DECLARE_IDTENTRY_VC(X86_TRAP_VC, exc_vmm_communication);
arch/x86/include/asm/irq_stack.h+3−1
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 #define _ASM_X86_IRQ_STACK_H
44
55 #include <linux/ptrace.h>
6+#include <linux/objtool.h>
67
78 #include <asm/processor.h>
89
@@ -99,7 +100,8 @@ · 90 unmodified lines
99100 }
100101
101102 #define ASM_CALL_ARG0 \
102− "call %P[__func] \n"
103+ "call %P[__func] \n" \
104+ ASM_REACHABLE
103105
104106 #define ASM_CALL_ARG1 \
105107 "movq %[arg1], %%rdi \n" \
arch/x86/include/asm/irqflags.h+0−5
@@ -141,13 +141,8 @@ static __always_inline void arch_local_irq_restore(unsigned long flags) · 140 unmodified lines
141141 #ifdef CONFIG_X86_64
142142 #ifdef CONFIG_XEN_PV
143143 #define SWAPGS ALTERNATIVE "swapgs", "", X86_FEATURE_XENPV
144−#define INTERRUPT_RETURN \
145− ANNOTATE_RETPOLINE_SAFE; \
146− ALTERNATIVE_TERNARY("jmp *paravirt_iret(%rip);", \
147− X86_FEATURE_XENPV, "jmp xen_iret;", "jmp native_iret;")
148144 #else
149145 #define SWAPGS swapgs
150−#define INTERRUPT_RETURN jmp native_iret
151146 #endif
152147 #endif
153148 #endif /* !__ASSEMBLY__ */
arch/x86/include/asm/linkage.h+31−0
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 #define _ASM_X86_LINKAGE_H
44
55 #include <linux/stringify.h>
6+#include <asm/ibt.h>
67
78 #undef notrace
89 #define notrace __attribute__((no_instrument_function))
@@ -34,5 +35,35 @@ · 25 unmodified lines
3435
3536 #endif /* __ASSEMBLY__ */
3637
38+/* SYM_FUNC_START -- use for global functions */
39+#define SYM_FUNC_START(name) \
40+ SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN) \
41+ ENDBR
42+
43+/* SYM_FUNC_START_NOALIGN -- use for global functions, w/o alignment */
44+#define SYM_FUNC_START_NOALIGN(name) \
45+ SYM_START(name, SYM_L_GLOBAL, SYM_A_NONE) \
46+ ENDBR
47+
48+/* SYM_FUNC_START_LOCAL -- use for local functions */
49+#define SYM_FUNC_START_LOCAL(name) \
50+ SYM_START(name, SYM_L_LOCAL, SYM_A_ALIGN) \
51+ ENDBR
52+
53+/* SYM_FUNC_START_LOCAL_NOALIGN -- use for local functions, w/o alignment */
54+#define SYM_FUNC_START_LOCAL_NOALIGN(name) \
55+ SYM_START(name, SYM_L_LOCAL, SYM_A_NONE) \
56+ ENDBR
57+
58+/* SYM_FUNC_START_WEAK -- use for weak functions */
59+#define SYM_FUNC_START_WEAK(name) \
60+ SYM_START(name, SYM_L_WEAK, SYM_A_ALIGN) \
61+ ENDBR
62+
63+/* SYM_FUNC_START_WEAK_NOALIGN -- use for weak functions, w/o alignment */
64+#define SYM_FUNC_START_WEAK_NOALIGN(name) \
65+ SYM_START(name, SYM_L_WEAK, SYM_A_NONE) \
66+ ENDBR
67+
3768 #endif /* _ASM_X86_LINKAGE_H */
3869
arch/x86/include/asm/msr-index.h+19−1
@@ -362,11 +362,29 @@ · 361 unmodified lines
362362 #define MSR_ATOM_CORE_TURBO_RATIOS 0x0000066c
363363 #define MSR_ATOM_CORE_TURBO_VIDS 0x0000066d
364364
365−
366365 #define MSR_CORE_PERF_LIMIT_REASONS 0x00000690
367366 #define MSR_GFX_PERF_LIMIT_REASONS 0x000006B0
368367 #define MSR_RING_PERF_LIMIT_REASONS 0x000006B1
369368
369+/* Control-flow Enforcement Technology MSRs */
370+#define MSR_IA32_U_CET 0x000006a0 /* user mode cet */
371+#define MSR_IA32_S_CET 0x000006a2 /* kernel mode cet */
372+#define CET_SHSTK_EN BIT_ULL(0)
373+#define CET_WRSS_EN BIT_ULL(1)
374+#define CET_ENDBR_EN BIT_ULL(2)
375+#define CET_LEG_IW_EN BIT_ULL(3)
376+#define CET_NO_TRACK_EN BIT_ULL(4)
377+#define CET_SUPPRESS_DISABLE BIT_ULL(5)
378+#define CET_RESERVED (BIT_ULL(6) | BIT_ULL(7) | BIT_ULL(8) | BIT_ULL(9))
379+#define CET_SUPPRESS BIT_ULL(10)
380+#define CET_WAIT_ENDBR BIT_ULL(11)
381+
382+#define MSR_IA32_PL0_SSP 0x000006a4 /* ring-0 shadow stack pointer */
383+#define MSR_IA32_PL1_SSP 0x000006a5 /* ring-1 shadow stack pointer */
384+#define MSR_IA32_PL2_SSP 0x000006a6 /* ring-2 shadow stack pointer */
385+#define MSR_IA32_PL3_SSP 0x000006a7 /* ring-3 shadow stack pointer */
386+#define MSR_IA32_INT_SSP_TAB 0x000006a8 /* exception shadow stack table */
387+
370388 /* Hardware P state interface */
371389 #define MSR_PPERF 0x0000064e
372390 #define MSR_PERF_LIMIT_REASONS 0x0000064f
arch/x86/include/asm/paravirt.h+1−0
@@ -666,6 +666,7 @@ bool __raw_callee_save___native_vcpu_is_preempted(long cpu); · 665 unmodified lines
666666 ".globl " PV_THUNK_NAME(func) ";" \
667667 ".type " PV_THUNK_NAME(func) ", @function;" \
668668 PV_THUNK_NAME(func) ":" \
669+ ASM_ENDBR \
669670 FRAME_BEGIN \
670671 PV_SAVE_ALL_CALLER_REGS \
671672 "call " #func ";" \
arch/x86/include/asm/paravirt_types.h+0−1
@@ -272,7 +272,6 @@ struct paravirt_patch_template { · 271 unmodified lines
272272
273273 extern struct pv_info pv_info;
274274 extern struct paravirt_patch_template pv_ops;
275−extern void (*paravirt_iret)(void);
276275
277276 #define PARAVIRT_PATCH(x) \
278277 (offsetof(struct paravirt_patch_template, x) / sizeof(void *))
arch/x86/include/asm/processor.h+1−1
@@ -837,7 +837,7 @@ bool xen_set_default_idle(void); · 836 unmodified lines
837837 #define xen_set_default_idle 0
838838 #endif
839839
840−void stop_this_cpu(void *dummy);
840+void __noreturn stop_this_cpu(void *dummy);
841841 void microcode_check(void);
842842
843843 enum l1tf_mitigations {
arch/x86/include/asm/qspinlock_paravirt.h+3−0
@@ -2,6 +2,8 @@ · 1 unmodified line
22 #ifndef __ASM_QSPINLOCK_PARAVIRT_H
33 #define __ASM_QSPINLOCK_PARAVIRT_H
44
5+#include <asm/ibt.h>
6+
57 /*
68 * For x86-64, PV_CALLEE_SAVE_REGS_THUNK() saves and restores 8 64-bit
79 * registers. For i386, however, only 1 32-bit register needs to be saved
@@ -39,6 +41,7 @@ asm (".pushsection .text;" · 31 unmodified lines
3941 ".type " PV_UNLOCK ", @function;"
4042 ".align 4,0x90;"
4143 PV_UNLOCK ": "
44+ ASM_ENDBR
4245 FRAME_BEGIN
4346 "push %rdx;"
4447 "mov $0x1,%eax;"
arch/x86/include/asm/segment.h+3−2
@@ -4,6 +4,7 @@ · 3 unmodified lines
44
55 #include <linux/const.h>
66 #include <asm/alternative.h>
7+#include <asm/ibt.h>
78
89 /*
910 * Constructor for a conventional segment GDT (or LDT) entry.
@@ -275,7 +276,7 @@ static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node) · 265 unmodified lines
275276 * vector has no error code (two bytes), a 'push $vector_number' (two
276277 * bytes), and a jump to the common entry code (up to five bytes).
277278 */
278−#define EARLY_IDT_HANDLER_SIZE 9
279+#define EARLY_IDT_HANDLER_SIZE (9 + ENDBR_INSN_SIZE)
279280
280281 /*
281282 * xen_early_idt_handler_array is for Xen pv guests: for each entry in
@@ -283,7 +284,7 @@ static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node) · 1 unmodified line
283284 * pop %rcx; pop %r11; jmp early_idt_handler_array[i]; summing up to
284285 * max 8 bytes.
285286 */
286−#define XEN_EARLY_IDT_HANDLER_SIZE 8
287+#define XEN_EARLY_IDT_HANDLER_SIZE (8 + ENDBR_INSN_SIZE)
287288
288289 #ifndef __ASSEMBLY__
289290
arch/x86/include/asm/setup.h+2−1
@@ -8,6 +8,7 @@ · 7 unmodified lines
88
99 #include <linux/linkage.h>
1010 #include <asm/page_types.h>
11+#include <asm/ibt.h>
1112
1213 #ifdef __i386__
1314
@@ -119,7 +120,7 @@ void *extend_brk(size_t size, size_t align); · 105 unmodified lines
119120 * executable.)
120121 */
121122 #define RESERVE_BRK(name,sz) \
122− static void __section(".discard.text") __used notrace \
123+ static void __section(".discard.text") __noendbr __used notrace \
123124 __brk_reservation_fn_##name##__(void) { \
124125 asm volatile ( \
125126 ".pushsection .brk_reservation,\"aw\",@nobits;" \
arch/x86/include/asm/syscall_wrapper.h+3−3
@@ -159,7 +159,7 @@ extern long __ia32_sys_ni_syscall(const struct pt_regs *regs); · 158 unmodified lines
159159 #endif /* CONFIG_IA32_EMULATION */
160160
161161
162−#ifdef CONFIG_X86_X32
162+#ifdef CONFIG_X86_X32_ABI
163163 /*
164164 * For the x32 ABI, we need to create a stub for compat_sys_*() which is aware
165165 * of the x86-64-style parameter ordering of x32 syscalls. The syscalls common
@@ -177,12 +177,12 @@ extern long __ia32_sys_ni_syscall(const struct pt_regs *regs); · 11 unmodified lines
177177
178178 #define __X32_COMPAT_SYS_NI(name) \
179179 __SYS_NI(x64, compat_sys_##name)
180−#else /* CONFIG_X86_X32 */
180+#else /* CONFIG_X86_X32_ABI */
181181 #define __X32_COMPAT_SYS_STUB0(name)
182182 #define __X32_COMPAT_SYS_STUBx(x, name, ...)
183183 #define __X32_COMPAT_COND_SYSCALL(name)
184184 #define __X32_COMPAT_SYS_NI(name)
185−#endif /* CONFIG_X86_X32 */
185+#endif /* CONFIG_X86_X32_ABI */
186186
187187
188188 #ifdef CONFIG_COMPAT
arch/x86/include/asm/text-patching.h+23−7
@@ -97,24 +97,40 @@ union text_poke_insn { · 96 unmodified lines
9797 };
9898
9999 static __always_inline
100−void *text_gen_insn(u8 opcode, const void *addr, const void *dest)
100+void __text_gen_insn(void *buf, u8 opcode, const void *addr, const void *dest, int size)
101101 {
102− static union text_poke_insn insn; /* per instance */
103− int size = text_opcode_size(opcode);
102+ union text_poke_insn *insn = buf;
103+
104+ BUG_ON(size < text_opcode_size(opcode));
105+
106+ /*
107+ * Hide the addresses to avoid the compiler folding in constants when
108+ * referencing code, these can mess up annotations like
109+ * ANNOTATE_NOENDBR.
110+ */
111+ OPTIMIZER_HIDE_VAR(insn);
112+ OPTIMIZER_HIDE_VAR(addr);
113+ OPTIMIZER_HIDE_VAR(dest);
104114
105− insn.opcode = opcode;
115+ insn->opcode = opcode;
106116
107117 if (size > 1) {
108− insn.disp = (long)dest - (long)(addr + size);
118+ insn->disp = (long)dest - (long)(addr + size);
109119 if (size == 2) {
110120 /*
111− * Ensure that for JMP9 the displacement
121+ * Ensure that for JMP8 the displacement
112122 * actually fits the signed byte.
113123 */
114− BUG_ON((insn.disp >> 31) != (insn.disp >> 7));
124+ BUG_ON((insn->disp >> 31) != (insn->disp >> 7));
115125 }
116126 }
127+}
117128
129+static __always_inline
130+void *text_gen_insn(u8 opcode, const void *addr, const void *dest)
131+{
132+ static union text_poke_insn insn; /* per instance */
133+ __text_gen_insn(&insn, opcode, addr, dest, text_opcode_size(opcode));
118134 return &insn.text;
119135 }
120136
arch/x86/include/asm/traps.h+2−0
@@ -18,6 +18,8 @@ void __init trap_init(void); · 17 unmodified lines
1818 asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *eregs);
1919 #endif
2020
21+extern bool ibt_selftest(void);
22+
2123 #ifdef CONFIG_X86_F00F_BUG
2224 /* For handling the FOOF bug */
2325 void handle_invalid_op(struct pt_regs *regs);
arch/x86/include/asm/vdso.h+1−1
@@ -37,7 +37,7 @@ struct vdso_image { · 36 unmodified lines
3737 extern const struct vdso_image vdso_image_64;
3838 #endif
3939
40−#ifdef CONFIG_X86_X32
40+#ifdef CONFIG_X86_X32_ABI
4141 extern const struct vdso_image vdso_image_x32;
4242 #endif
4343
arch/x86/include/uapi/asm/processor-flags.h+2−0
@@ -130,6 +130,8 @@ · 129 unmodified lines
130130 #define X86_CR4_SMAP _BITUL(X86_CR4_SMAP_BIT)
131131 #define X86_CR4_PKE_BIT 22 /* enable Protection Keys support */
132132 #define X86_CR4_PKE _BITUL(X86_CR4_PKE_BIT)
133+#define X86_CR4_CET_BIT 23 /* enable Control-flow Enforcement Technology */
134+#define X86_CR4_CET _BITUL(X86_CR4_CET_BIT)
133135
134136 /*
135137 * x86-64 Task Priority Register, CR8
arch/x86/kernel/alternative.c+52−14
@@ -115,6 +115,7 @@ static void __init_or_module add_nops(void *insns, unsigned int len) · 114 unmodified lines
115115 }
116116
117117 extern s32 __retpoline_sites[], __retpoline_sites_end[];
118+extern s32 __ibt_endbr_seal[], __ibt_endbr_seal_end[];
118119 extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
119120 extern s32 __smp_locks[], __smp_locks_end[];
120121 void text_poke_early(void *addr, const void *opcode, size_t len);
@@ -512,6 +513,42 @@ void __init_or_module noinline apply_retpolines(s32 *start, s32 *end) { } · 391 unmodified lines
512513
513514 #endif /* CONFIG_RETPOLINE && CONFIG_STACK_VALIDATION */
514515
516+#ifdef CONFIG_X86_KERNEL_IBT
517+
518+/*
519+ * Generated by: objtool --ibt
520+ */
521+void __init_or_module noinline apply_ibt_endbr(s32 *start, s32 *end)
522+{
523+ s32 *s;
524+
525+ for (s = start; s < end; s++) {
526+ u32 endbr, poison = gen_endbr_poison();
527+ void *addr = (void *)s + *s;
528+
529+ if (WARN_ON_ONCE(get_kernel_nofault(endbr, addr)))
530+ continue;
531+
532+ if (WARN_ON_ONCE(!is_endbr(endbr)))
533+ continue;
534+
535+ DPRINTK("ENDBR at: %pS (%px)", addr, addr);
536+
537+ /*
538+ * When we have IBT, the lack of ENDBR will trigger #CP
539+ */
540+ DUMP_BYTES(((u8*)addr), 4, "%px: orig: ", addr);
541+ DUMP_BYTES(((u8*)&poison), 4, "%px: repl: ", addr);
542+ text_poke_early(addr, &poison, 4);
543+ }
544+}
545+
546+#else
547+
548+void __init_or_module noinline apply_ibt_endbr(s32 *start, s32 *end) { }
549+
550+#endif /* CONFIG_X86_KERNEL_IBT */
551+
515552 #ifdef CONFIG_SMP
516553 static void alternatives_smp_lock(const s32 *start, const s32 *end,
517554 u8 *text, u8 *text_end)
@@ -713,34 +750,39 @@ asm ( · 195 unmodified lines
713750 " .pushsection .init.text, \"ax\", @progbits\n"
714751 " .type int3_magic, @function\n"
715752 "int3_magic:\n"
753+ ANNOTATE_NOENDBR
716754 " movl $1, (%" _ASM_ARG1 ")\n"
717755 ASM_RET
718756 " .size int3_magic, .-int3_magic\n"
719757 " .popsection\n"
720758 );
721759
722−extern __initdata unsigned long int3_selftest_ip; /* defined in asm below */
760+extern void int3_selftest_ip(void); /* defined in asm below */
723761
724762 static int __init
725763 int3_exception_notify(struct notifier_block *self, unsigned long val, void *data)
726764 {
765+ unsigned long selftest = (unsigned long)&int3_selftest_ip;
727766 struct die_args *args = data;
728767 struct pt_regs *regs = args->regs;
729768
769+ OPTIMIZER_HIDE_VAR(selftest);
770+
730771 if (!regs || user_mode(regs))
731772 return NOTIFY_DONE;
732773
733774 if (val != DIE_INT3)
734775 return NOTIFY_DONE;
735776
736− if (regs->ip - INT3_INSN_SIZE != int3_selftest_ip)
777+ if (regs->ip - INT3_INSN_SIZE != selftest)
737778 return NOTIFY_DONE;
738779
739780 int3_emulate_call(regs, (unsigned long)&int3_magic);
740781 return NOTIFY_STOP;
741782 }
742783
743−static void __init int3_selftest(void)
784+/* Must be noinline to ensure uniqueness of int3_selftest_ip. */
785+static noinline void __init int3_selftest(void)
744786 {
745787 static __initdata struct notifier_block int3_exception_nb = {
746788 .notifier_call = int3_exception_notify,
@@ -753,18 +795,12 @@ static void __init int3_selftest(void) · 6 unmodified lines
753795 /*
754796 * Basically: int3_magic(&val); but really complicated :-)
755797 *
756− * Stick the address of the INT3 instruction into int3_selftest_ip,
757− * then trigger the INT3, padded with NOPs to match a CALL instruction
758− * length.
798+ * INT3 padded with NOP to CALL_INSN_SIZE. The int3_exception_nb
799+ * notifier above will emulate CALL for us.
759800 */
760− asm volatile ("1: int3; nop; nop; nop; nop\n\t"
761− ".pushsection .init.data,\"aw\"\n\t"
762− ".align " __ASM_SEL(4, 8) "\n\t"
763− ".type int3_selftest_ip, @object\n\t"
764− ".size int3_selftest_ip, " __ASM_SEL(4, 8) "\n\t"
765− "int3_selftest_ip:\n\t"
766− __ASM_SEL(.long, .quad) " 1b\n\t"
767− ".popsection\n\t"
801+ asm volatile ("int3_selftest_ip:\n\t"
802+ ANNOTATE_NOENDBR
803+ " int3; nop; nop; nop; nop\n\t"
768804 : ASM_CALL_CONSTRAINT
769805 : __ASM_SEL_RAW(a, D) (&val)
770806 : "memory");
@@ -831,6 +867,8 @@ void __init alternative_instructions(void) · 60 unmodified lines
831867 */
832868 apply_alternatives(__alt_instructions, __alt_instructions_end);
833869
870+ apply_ibt_endbr(__ibt_endbr_seal, __ibt_endbr_seal_end);
871+
834872 #ifdef CONFIG_SMP
835873 /* Patch to UP if other cpus not imminent. */
836874 if (!noreplace_smp && (num_present_cpus() == 1 || setup_max_cpus <= 1)) {
arch/x86/kernel/apm_32.c+7−0
@@ -232,6 +232,7 @@ · 231 unmodified lines
232232 #include <asm/paravirt.h>
233233 #include <asm/reboot.h>
234234 #include <asm/nospec-branch.h>
235+#include <asm/ibt.h>
235236
236237 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
237238 extern int (*console_blank_hook)(int);
@@ -598,6 +599,7 @@ static long __apm_bios_call(void *_call) · 360 unmodified lines
598599 struct desc_struct save_desc_40;
599600 struct desc_struct *gdt;
600601 struct apm_bios_call *call = _call;
602+ u64 ibt;
601603
602604 cpu = get_cpu();
603605 BUG_ON(cpu != 0);
@@ -607,11 +609,13 @@ static long __apm_bios_call(void *_call) · 3 unmodified lines
607609
608610 apm_irq_save(flags);
609611 firmware_restrict_branch_speculation_start();
612+ ibt = ibt_save();
610613 APM_DO_SAVE_SEGS;
611614 apm_bios_call_asm(call->func, call->ebx, call->ecx,
612615 &call->eax, &call->ebx, &call->ecx, &call->edx,
613616 &call->esi);
614617 APM_DO_RESTORE_SEGS;
618+ ibt_restore(ibt);
615619 firmware_restrict_branch_speculation_end();
616620 apm_irq_restore(flags);
617621 gdt[0x40 / 8] = save_desc_40;
@@ -676,6 +680,7 @@ static long __apm_bios_call_simple(void *_call) · 58 unmodified lines
676680 struct desc_struct save_desc_40;
677681 struct desc_struct *gdt;
678682 struct apm_bios_call *call = _call;
683+ u64 ibt;
679684
680685 cpu = get_cpu();
681686 BUG_ON(cpu != 0);
@@ -685,10 +690,12 @@ static long __apm_bios_call_simple(void *_call) · 3 unmodified lines
685690
686691 apm_irq_save(flags);
687692 firmware_restrict_branch_speculation_start();
693+ ibt = ibt_save();
688694 APM_DO_SAVE_SEGS;
689695 error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx,
690696 &call->eax);
691697 APM_DO_RESTORE_SEGS;
698+ ibt_restore(ibt);
692699 firmware_restrict_branch_speculation_end();
693700 apm_irq_restore(flags);
694701 gdt[0x40 / 8] = save_desc_40;
arch/x86/kernel/cpu/common.c+58−1
@@ -59,6 +59,7 @@ · 58 unmodified lines
5959 #include <asm/cpu_device_id.h>
6060 #include <asm/uv/uv.h>
6161 #include <asm/sigframe.h>
62+#include <asm/traps.h>
6263
6364 #include "cpu.h"
6465
@@ -438,7 +439,8 @@ out: · 373 unmodified lines
438439
439440 /* These bits should not change their value after CPU init is finished. */
440441 static const unsigned long cr4_pinned_mask =
441− X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_UMIP | X86_CR4_FSGSBASE;
442+ X86_CR4_SMEP | X86_CR4_SMAP | X86_CR4_UMIP |
443+ X86_CR4_FSGSBASE | X86_CR4_CET;
442444 static DEFINE_STATIC_KEY_FALSE_RO(cr_pinning);
443445 static unsigned long cr4_pinned_bits __ro_after_init;
444446
@@ -592,6 +594,58 @@ static __init int setup_disable_pku(char *arg) · 147 unmodified lines
592594 __setup("nopku", setup_disable_pku);
593595 #endif /* CONFIG_X86_64 */
594596
597+#ifdef CONFIG_X86_KERNEL_IBT
598+
599+__noendbr u64 ibt_save(void)
600+{
601+ u64 msr = 0;
602+
603+ if (cpu_feature_enabled(X86_FEATURE_IBT)) {
604+ rdmsrl(MSR_IA32_S_CET, msr);
605+ wrmsrl(MSR_IA32_S_CET, msr & ~CET_ENDBR_EN);
606+ }
607+
608+ return msr;
609+}
610+
611+__noendbr void ibt_restore(u64 save)
612+{
613+ u64 msr;
614+
615+ if (cpu_feature_enabled(X86_FEATURE_IBT)) {
616+ rdmsrl(MSR_IA32_S_CET, msr);
617+ msr &= ~CET_ENDBR_EN;
618+ msr |= (save & CET_ENDBR_EN);
619+ wrmsrl(MSR_IA32_S_CET, msr);
620+ }
621+}
622+
623+#endif
624+
625+static __always_inline void setup_cet(struct cpuinfo_x86 *c)
626+{
627+ u64 msr = CET_ENDBR_EN;
628+
629+ if (!HAS_KERNEL_IBT ||
630+ !cpu_feature_enabled(X86_FEATURE_IBT))
631+ return;
632+
633+ wrmsrl(MSR_IA32_S_CET, msr);
634+ cr4_set_bits(X86_CR4_CET);
635+
636+ if (!ibt_selftest()) {
637+ pr_err("IBT selftest: Failed!\n");
638+ setup_clear_cpu_cap(X86_FEATURE_IBT);
639+ return;
640+ }
641+}
642+
643+__noendbr void cet_disable(void)
644+{
645+ if (cpu_feature_enabled(X86_FEATURE_IBT))
646+ wrmsrl(MSR_IA32_S_CET, 0);
647+}
648+
595649 /*
596650 * Some CPU features depend on higher CPUID levels, which may not always
597651 * be available due to CPUID level capping or broken virtualization
@@ -1709,6 +1763,7 @@ static void identify_cpu(struct cpuinfo_x86 *c) · 1111 unmodified lines
17091763
17101764 x86_init_rdrand(c);
17111765 setup_pku(c);
1766+ setup_cet(c);
17121767
17131768 /*
17141769 * Clear/Set all flags overridden by options, need do it
@@ -1777,6 +1832,8 @@ void enable_sep_cpu(void) · 62 unmodified lines
17771832 void __init identify_boot_cpu(void)
17781833 {
17791834 identify_cpu(&boot_cpu_data);
1835+ if (HAS_KERNEL_IBT && cpu_feature_enabled(X86_FEATURE_IBT))
1836+ pr_info("CET detected: Indirect Branch Tracking enabled\n");
17801837 #ifdef CONFIG_X86_32
17811838 sysenter_setup();
17821839 enable_sep_cpu();
arch/x86/kernel/ftrace.c+2−7
@@ -316,12 +316,12 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) · 315 unmodified lines
316316 unsigned long offset;
317317 unsigned long npages;
318318 unsigned long size;
319− unsigned long retq;
320319 unsigned long *ptr;
321320 void *trampoline;
322321 void *ip;
323322 /* 48 8b 15 <offset> is movq <offset>(%rip), %rdx */
324323 unsigned const char op_ref[] = { 0x48, 0x8b, 0x15 };
324+ unsigned const char retq[] = { RET_INSN_OPCODE, INT3_INSN_OPCODE };
325325 union ftrace_op_code_union op_ptr;
326326 int ret;
327327
@@ -359,12 +359,7 @@ create_trampoline(struct ftrace_ops *ops, unsigned int *tramp_size) · 31 unmodified lines
359359 goto fail;
360360
361361 ip = trampoline + size;
362−
363− /* The trampoline ends with ret(q) */
364− retq = (unsigned long)ftrace_stub;
365− ret = copy_from_kernel_nofault(ip, (void *)retq, RET_SIZE);
366− if (WARN_ON(ret < 0))
367− goto fail;
362+ memcpy(ip, retq, RET_SIZE);
368363
369364 /* No need to test direct calls on created trampolines */
370365 if (ops->flags & FTRACE_OPS_FL_SAVE_REGS) {
arch/x86/kernel/ftrace_64.S+24−4
@@ -145,6 +145,7 @@ SYM_FUNC_START(ftrace_caller) · 144 unmodified lines
145145 movq %rcx, RSP(%rsp)
146146
147147 SYM_INNER_LABEL(ftrace_caller_op_ptr, SYM_L_GLOBAL)
148+ ANNOTATE_NOENDBR
148149 /* Load the ftrace_ops into the 3rd parameter */
149150 movq function_trace_op(%rip), %rdx
150151
@@ -155,6 +156,7 @@ SYM_INNER_LABEL(ftrace_caller_op_ptr, SYM_L_GLOBAL) · 4 unmodified lines
155156 movq $0, CS(%rsp)
156157
157158 SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL)
159+ ANNOTATE_NOENDBR
158160 call ftrace_stub
159161
160162 /* Handlers can change the RIP */
@@ -169,6 +171,7 @@ SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL) · 8 unmodified lines
169171 * layout here.
170172 */
171173 SYM_INNER_LABEL(ftrace_caller_end, SYM_L_GLOBAL)
174+ ANNOTATE_NOENDBR
172175
173176 jmp ftrace_epilogue
174177 SYM_FUNC_END(ftrace_caller);
@@ -176,10 +179,10 @@ SYM_FUNC_END(ftrace_caller); · 1 unmodified line
176179 SYM_FUNC_START(ftrace_epilogue)
177180 /*
178181 * This is weak to keep gas from relaxing the jumps.
179− * It is also used to copy the RET for trampolines.
180182 */
181183 SYM_INNER_LABEL_ALIGN(ftrace_stub, SYM_L_WEAK)
182184 UNWIND_HINT_FUNC
185+ ENDBR
183186 RET
184187 SYM_FUNC_END(ftrace_epilogue)
185188
@@ -192,6 +195,7 @@ SYM_FUNC_START(ftrace_regs_caller) · 6 unmodified lines
192195 /* save_mcount_regs fills in first two parameters */
193196
194197 SYM_INNER_LABEL(ftrace_regs_caller_op_ptr, SYM_L_GLOBAL)
198+ ANNOTATE_NOENDBR
195199 /* Load the ftrace_ops into the 3rd parameter */
196200 movq function_trace_op(%rip), %rdx
197201
@@ -221,6 +225,7 @@ SYM_INNER_LABEL(ftrace_regs_caller_op_ptr, SYM_L_GLOBAL) · 23 unmodified lines
221225 leaq (%rsp), %rcx
222226
223227 SYM_INNER_LABEL(ftrace_regs_call, SYM_L_GLOBAL)
228+ ANNOTATE_NOENDBR
224229 call ftrace_stub
225230
226231 /* Copy flags back to SS, to restore them */
@@ -248,6 +253,7 @@ SYM_INNER_LABEL(ftrace_regs_call, SYM_L_GLOBAL) · 21 unmodified lines
248253 */
249254 testq %rax, %rax
250255 SYM_INNER_LABEL(ftrace_regs_caller_jmp, SYM_L_GLOBAL)
256+ ANNOTATE_NOENDBR
251257 jnz 1f
252258
253259 restore_mcount_regs
@@ -261,6 +267,7 @@ SYM_INNER_LABEL(ftrace_regs_caller_jmp, SYM_L_GLOBAL) · 7 unmodified lines
261267 * to the return.
262268 */
263269 SYM_INNER_LABEL(ftrace_regs_caller_end, SYM_L_GLOBAL)
270+ ANNOTATE_NOENDBR
264271 jmp ftrace_epilogue
265272
266273 /* Swap the flags with orig_rax */
@@ -284,6 +291,7 @@ SYM_FUNC_START(__fentry__) · 17 unmodified lines
284291 jnz trace
285292
286293 SYM_INNER_LABEL(ftrace_stub, SYM_L_GLOBAL)
294+ ENDBR
287295 RET
288296
289297 trace:
@@ -307,7 +315,7 @@ EXPORT_SYMBOL(__fentry__) · 17 unmodified lines
307315
308316 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
309317 SYM_FUNC_START(return_to_handler)
310− subq $24, %rsp
318+ subq $16, %rsp
311319
312320 /* Save the return values */
313321 movq %rax, (%rsp)
@@ -319,7 +327,19 @@ SYM_FUNC_START(return_to_handler) · 5 unmodified lines
319327 movq %rax, %rdi
320328 movq 8(%rsp), %rdx
321329 movq (%rsp), %rax
322− addq $24, %rsp
323− JMP_NOSPEC rdi
330+
331+ addq $16, %rsp
332+ /*
333+ * Jump back to the old return address. This cannot be JMP_NOSPEC rdi
334+ * since IBT would demand that contain ENDBR, which simply isn't so for
335+ * return addresses. Use a retpoline here to keep the RSB balanced.
336+ */
337+ ANNOTATE_INTRA_FUNCTION_CALL
338+ call .Ldo_rop
339+ int3
340+.Ldo_rop:
341+ mov %rdi, (%rsp)
342+ UNWIND_HINT_FUNC
343+ RET
324344 SYM_FUNC_END(return_to_handler)
325345 #endif
arch/x86/kernel/head_64.S+12−2
@@ -99,6 +99,7 @@ SYM_CODE_END(startup_64) · 98 unmodified lines
9999
100100 SYM_CODE_START(secondary_startup_64)
101101 UNWIND_HINT_EMPTY
102+ ANNOTATE_NOENDBR
102103 /*
103104 * At this point the CPU runs in 64bit mode CS.L = 1 CS.D = 0,
104105 * and someone has loaded a mapped page table.
@@ -127,6 +128,7 @@ SYM_CODE_START(secondary_startup_64) · 22 unmodified lines
127128 */
128129 SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL)
129130 UNWIND_HINT_EMPTY
131+ ANNOTATE_NOENDBR
130132
131133 /*
132134 * Retrieve the modifier (SME encryption mask if SME is active) to be
@@ -192,6 +194,7 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL) · 59 unmodified lines
192194 jmp *%rax
193195 1:
194196 UNWIND_HINT_EMPTY
197+ ANNOTATE_NOENDBR // above
195198
196199 /*
197200 * We must switch to a new descriptor in kernel space for the GDT
@@ -299,6 +302,7 @@ SYM_INNER_LABEL(secondary_startup_64_no_verify, SYM_L_GLOBAL) · 101 unmodified lines
299302 pushq %rax # target address in negative space
300303 lretq
301304 .Lafter_lret:
305+ ANNOTATE_NOENDBR
302306 SYM_CODE_END(secondary_startup_64)
303307
304308 #include "verify_cpu.S"
@@ -328,6 +332,7 @@ SYM_CODE_END(start_cpu0) · 23 unmodified lines
328332 */
329333 SYM_CODE_START_NOALIGN(vc_boot_ghcb)
330334 UNWIND_HINT_IRET_REGS offset=8
335+ ENDBR
331336
332337 /* Build pt_regs */
333338 PUSH_AND_CLEAR_REGS
@@ -345,7 +350,6 @@ SYM_CODE_START_NOALIGN(vc_boot_ghcb) · 11 unmodified lines
345350 /* Remove Error Code */
346351 addq $8, %rsp
347352
348− /* Pure iret required here - don't use INTERRUPT_RETURN */
349353 iretq
350354 SYM_CODE_END(vc_boot_ghcb)
351355 #endif
@@ -372,9 +376,11 @@ SYM_CODE_START(early_idt_handler_array) · 20 unmodified lines
372376 .rept NUM_EXCEPTION_VECTORS
373377 .if ((EXCEPTION_ERRCODE_MASK >> i) & 1) == 0
374378 UNWIND_HINT_IRET_REGS
379+ ENDBR
375380 pushq $0 # Dummy error code, to make stack frame uniform
376381 .else
377382 UNWIND_HINT_IRET_REGS offset=8
383+ ENDBR
378384 .endif
379385 pushq $i # 72(%rsp) Vector number
380386 jmp early_idt_handler_common
@@ -382,10 +388,11 @@ SYM_CODE_START(early_idt_handler_array) · 1 unmodified line
382388 i = i + 1
383389 .fill early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc
384390 .endr
385− UNWIND_HINT_IRET_REGS offset=16
386391 SYM_CODE_END(early_idt_handler_array)
392+ ANNOTATE_NOENDBR // early_idt_handler_array[NUM_EXCEPTION_VECTORS]
387393
388394 SYM_CODE_START_LOCAL(early_idt_handler_common)
395+ UNWIND_HINT_IRET_REGS offset=16
389396 /*
390397 * The stack is the hardware frame, an error code or zero, and the
391398 * vector number.
@@ -426,11 +433,14 @@ SYM_CODE_END(early_idt_handler_common) · 34 unmodified lines
426433 * early_idt_handler_array can't be used because it returns via the
427434 * paravirtualized INTERRUPT_RETURN and pv-ops don't work that early.
428435 *
436+ * XXX it does, fix this.
437+ *
429438 * This handler will end up in the .init.text section and not be
430439 * available to boot secondary CPUs.
431440 */
432441 SYM_CODE_START_NOALIGN(vc_no_ghcb)
433442 UNWIND_HINT_IRET_REGS offset=8
443+ ENDBR
434444
435445 /* Build pt_regs */
436446 PUSH_AND_CLEAR_REGS
arch/x86/kernel/idt.c+7−2
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 #include <asm/proto.h>
1111 #include <asm/desc.h>
1212 #include <asm/hw_irq.h>
13+#include <asm/idtentry.h>
1314
1415 #define DPL0 0x0
1516 #define DPL3 0x3
@@ -103,6 +104,10 @@ static const __initconst struct idt_data def_idts[] = { · 87 unmodified lines
103104 ISTG(X86_TRAP_MC, asm_exc_machine_check, IST_INDEX_MCE),
104105 #endif
105106
107+#ifdef CONFIG_X86_KERNEL_IBT
108+ INTG(X86_TRAP_CP, asm_exc_control_protection),
109+#endif
110+
106111 #ifdef CONFIG_AMD_MEM_ENCRYPT
107112 ISTG(X86_TRAP_VC, asm_exc_vmm_communication, IST_INDEX_VC),
108113 #endif
@@ -272,7 +277,7 @@ void __init idt_setup_apic_and_irq_gates(void) · 163 unmodified lines
272277 idt_setup_from_table(idt_table, apic_idts, ARRAY_SIZE(apic_idts), true);
273278
274279 for_each_clear_bit_from(i, system_vectors, FIRST_SYSTEM_VECTOR) {
275− entry = irq_entries_start + 8 * (i - FIRST_EXTERNAL_VECTOR);
280+ entry = irq_entries_start + IDT_ALIGN * (i - FIRST_EXTERNAL_VECTOR);
276281 set_intr_gate(i, entry);
277282 }
278283
@@ -283,7 +288,7 @@ void __init idt_setup_apic_and_irq_gates(void) · 4 unmodified lines
283288 * system_vectors bitmap. Otherwise they show up in
284289 * /proc/interrupts.
285290 */
286− entry = spurious_entries_start + 8 * (i - FIRST_SYSTEM_VECTOR);
291+ entry = spurious_entries_start + IDT_ALIGN * (i - FIRST_SYSTEM_VECTOR);
287292 set_intr_gate(i, entry);
288293 }
289294 #endif
arch/x86/kernel/kprobes/core.c+20−9
@@ -52,6 +52,7 @@ · 51 unmodified lines
5252 #include <asm/insn.h>
5353 #include <asm/debugreg.h>
5454 #include <asm/set_memory.h>
55+#include <asm/ibt.h>
5556
5657 #include "common.h"
5758
@@ -193,17 +194,10 @@ static unsigned long · 135 unmodified lines
193194 __recover_probed_insn(kprobe_opcode_t *buf, unsigned long addr)
194195 {
195196 struct kprobe *kp;
196− unsigned long faddr;
197+ bool faddr;
197198
198199 kp = get_kprobe((void *)addr);
199− faddr = ftrace_location(addr);
200− /*
201− * Addresses inside the ftrace location are refused by
202− * arch_check_ftrace_location(). Something went terribly wrong
203− * if such an address is checked here.
204− */
205− if (WARN_ON(faddr && faddr != addr))
206− return 0UL;
200+ faddr = ftrace_location(addr) == addr;
207201 /*
208202 * Use the current code if it is not modified by Kprobe
209203 * and it cannot be modified by ftrace.
@@ -301,6 +295,22 @@ static int can_probe(unsigned long paddr) · 91 unmodified lines
301295 return (addr == paddr);
302296 }
303297
298+/* If x86 supports IBT (ENDBR) it must be skipped. */
299+kprobe_opcode_t *arch_adjust_kprobe_addr(unsigned long addr, unsigned long offset,
300+ bool *on_func_entry)
301+{
302+ if (is_endbr(*(u32 *)addr)) {
303+ *on_func_entry = !offset || offset == 4;
304+ if (*on_func_entry)
305+ offset = 4;
306+
307+ } else {
308+ *on_func_entry = !offset;
309+ }
310+
311+ return (kprobe_opcode_t *)(addr + offset);
312+}
313+
304314 /*
305315 * Copy an instruction with recovering modified instruction by kprobes
306316 * and adjust the displacement if the instruction uses the %rip-relative
@@ -1023,6 +1033,7 @@ asm( · 716 unmodified lines
10231033 ".type __kretprobe_trampoline, @function\n"
10241034 "__kretprobe_trampoline:\n"
10251035 #ifdef CONFIG_X86_64
1036+ ANNOTATE_NOENDBR
10261037 /* Push a fake return address to tell the unwinder it's a kretprobe. */
10271038 " pushq $__kretprobe_trampoline\n"
10281039 UNWIND_HINT_FUNC
arch/x86/kernel/kvm.c+2−1
@@ -1029,10 +1029,11 @@ asm( · 1028 unmodified lines
10291029 ".global __raw_callee_save___kvm_vcpu_is_preempted;"
10301030 ".type __raw_callee_save___kvm_vcpu_is_preempted, @function;"
10311031 "__raw_callee_save___kvm_vcpu_is_preempted:"
1032+ASM_ENDBR
10321033 "movq __per_cpu_offset(,%rdi,8), %rax;"
10331034 "cmpb $0, " __stringify(KVM_STEAL_TIME_preempted) "+steal_time(%rax);"
10341035 "setne %al;"
1035−"ret;"
1036+ASM_RET
10361037 ".size __raw_callee_save___kvm_vcpu_is_preempted, .-__raw_callee_save___kvm_vcpu_is_preempted;"
10371038 ".popsection");
10381039
arch/x86/kernel/machine_kexec_64.c+3−1
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 #include <asm/kexec-bzimage64.h>
2828 #include <asm/setup.h>
2929 #include <asm/set_memory.h>
30+#include <asm/cpu.h>
3031
3132 #ifdef CONFIG_ACPI
3233 /*
@@ -310,6 +311,7 @@ void machine_kexec(struct kimage *image) · 277 unmodified lines
310311 /* Interrupts aren't acceptable while we reboot */
311312 local_irq_disable();
312313 hw_breakpoint_disable();
314+ cet_disable();
313315
314316 if (image->preserve_context) {
315317 #ifdef CONFIG_X86_IO_APIC
@@ -325,7 +327,7 @@ void machine_kexec(struct kimage *image) · 9 unmodified lines
325327 }
326328
327329 control_page = page_address(image->control_code_page) + PAGE_SIZE;
328− memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
330+ __memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
329331
330332 page_list[PA_CONTROL_PAGE] = virt_to_phys(control_page);
331333 page_list[VA_CONTROL_PAGE] = (unsigned long)control_page;
arch/x86/kernel/module.c+7−1
@@ -253,7 +253,7 @@ int module_finalize(const Elf_Ehdr *hdr, · 252 unmodified lines
253253 {
254254 const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL,
255255 *para = NULL, *orc = NULL, *orc_ip = NULL,
256− *retpolines = NULL;
256+ *retpolines = NULL, *ibt_endbr = NULL;
257257 char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
258258
259259 for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
@@ -271,6 +271,8 @@ int module_finalize(const Elf_Ehdr *hdr, · 11 unmodified lines
271271 orc_ip = s;
272272 if (!strcmp(".retpoline_sites", secstrings + s->sh_name))
273273 retpolines = s;
274+ if (!strcmp(".ibt_endbr_seal", secstrings + s->sh_name))
275+ ibt_endbr = s;
274276 }
275277
276278 /*
@@ -290,6 +292,10 @@ int module_finalize(const Elf_Ehdr *hdr, · 13 unmodified lines
290292 void *aseg = (void *)alt->sh_addr;
291293 apply_alternatives(aseg, aseg + alt->sh_size);
292294 }
295+ if (ibt_endbr) {
296+ void *iseg = (void *)ibt_endbr->sh_addr;
297+ apply_ibt_endbr(iseg, iseg + ibt_endbr->sh_size);
298+ }
293299 if (locks && text) {
294300 void *lseg = (void *)locks->sh_addr;
295301 void *tseg = (void *)text->sh_addr;
arch/x86/kernel/paravirt.c+5−24
@@ -41,6 +41,7 @@ extern void _paravirt_nop(void); · 40 unmodified lines
4141 asm (".pushsection .entry.text, \"ax\"\n"
4242 ".global _paravirt_nop\n"
4343 "_paravirt_nop:\n\t"
44+ ASM_ENDBR
4445 ASM_RET
4546 ".size _paravirt_nop, . - _paravirt_nop\n\t"
4647 ".type _paravirt_nop, @function\n\t"
@@ -50,6 +51,7 @@ asm (".pushsection .entry.text, \"ax\"\n" · 3 unmodified lines
5051 asm (".pushsection .entry.text, \"ax\"\n"
5152 ".global paravirt_ret0\n"
5253 "paravirt_ret0:\n\t"
54+ ASM_ENDBR
5355 "xor %" _ASM_AX ", %" _ASM_AX ";\n\t"
5456 ASM_RET
5557 ".size paravirt_ret0, . - paravirt_ret0\n\t"
@@ -69,29 +71,12 @@ noinstr void paravirt_BUG(void) · 13 unmodified lines
6971 BUG();
7072 }
7173
72−struct branch {
73− unsigned char opcode;
74− u32 delta;
75−} __attribute__((packed));
76−
7774 static unsigned paravirt_patch_call(void *insn_buff, const void *target,
7875 unsigned long addr, unsigned len)
7976 {
80− const int call_len = 5;
81− struct branch *b = insn_buff;
82− unsigned long delta = (unsigned long)target - (addr+call_len);
83−
84− if (len < call_len) {
85− pr_warn("paravirt: Failed to patch indirect CALL at %ps\n", (void *)addr);
86− /* Kernel might not be viable if patching fails, bail out: */
87− BUG_ON(1);
88− }
89−
90− b->opcode = 0xe8; /* call */
91− b->delta = delta;
92− BUILD_BUG_ON(sizeof(*b) != call_len);
93−
94− return call_len;
77+ __text_gen_insn(insn_buff, CALL_INSN_OPCODE,
78+ (void *)addr, target, CALL_INSN_SIZE);
79+ return CALL_INSN_SIZE;
9580 }
9681
9782 #ifdef CONFIG_PARAVIRT_XXL
@@ -149,8 +134,6 @@ void paravirt_set_sched_clock(u64 (*func)(void)) · 51 unmodified lines
149134 }
150135
151136 /* These are in entry.S */
152−extern void native_iret(void);
153−
154137 static struct resource reserve_ioports = {
155138 .start = 0,
156139 .end = IO_SPACE_LIMIT,
@@ -414,8 +397,6 @@ struct paravirt_patch_template pv_ops = { · 257 unmodified lines
414397
415398 #ifdef CONFIG_PARAVIRT_XXL
416399 NOKPROBE_SYMBOL(native_load_idt);
417−
418−void (*paravirt_iret)(void) = native_iret;
419400 #endif
420401
421402 EXPORT_SYMBOL(pv_ops);
arch/x86/kernel/process.c+1−1
@@ -747,7 +747,7 @@ bool xen_set_default_idle(void) · 746 unmodified lines
747747 }
748748 #endif
749749
750−void stop_this_cpu(void *dummy)
750+void __noreturn stop_this_cpu(void *dummy)
751751 {
752752 local_irq_disable();
753753 /*
arch/x86/kernel/process_64.c+1−1
@@ -681,7 +681,7 @@ void set_personality_64bit(void) · 680 unmodified lines
681681
682682 static void __set_personality_x32(void)
683683 {
684−#ifdef CONFIG_X86_X32
684+#ifdef CONFIG_X86_X32_ABI
685685 if (current->mm)
686686 current->mm->context.flags = 0;
687687
arch/x86/kernel/relocate_kernel_64.S+10−0
@@ -42,6 +42,7 @@ · 41 unmodified lines
4242 .code64
4343 SYM_CODE_START_NOALIGN(relocate_kernel)
4444 UNWIND_HINT_EMPTY
45+ ANNOTATE_NOENDBR
4546 /*
4647 * %rdi indirection_page
4748 * %rsi page_list
@@ -114,6 +115,14 @@ SYM_CODE_START_LOCAL_NOALIGN(identity_mapped) · 66 unmodified lines
114115 /* store the start address on the stack */
115116 pushq %rdx
116117
118+ /*
119+ * Clear X86_CR4_CET (if it was set) such that we can clear CR0_WP
120+ * below.
121+ */
122+ movq %cr4, %rax
123+ andq $~(X86_CR4_CET), %rax
124+ movq %rax, %cr4
125+
117126 /*
118127 * Set cr0 to a known state:
119128 * - Paging enabled
@@ -215,6 +224,7 @@ SYM_CODE_END(identity_mapped) · 95 unmodified lines
215224
216225 SYM_CODE_START_LOCAL_NOALIGN(virtual_mapped)
217226 UNWIND_HINT_EMPTY
227+ ANNOTATE_NOENDBR // RET target, above
218228 movq RSP(%r8), %rsp
219229 movq CR4(%r8), %rax
220230 movq %rax, %cr4
arch/x86/kernel/traps.c+75−0
@@ -210,6 +210,81 @@ DEFINE_IDTENTRY(exc_overflow) · 209 unmodified lines
210210 do_error_trap(regs, 0, "overflow", X86_TRAP_OF, SIGSEGV, 0, NULL);
211211 }
212212
213+#ifdef CONFIG_X86_KERNEL_IBT
214+
215+static __ro_after_init bool ibt_fatal = true;
216+
217+extern void ibt_selftest_ip(void); /* code label defined in asm below */
218+
219+enum cp_error_code {
220+ CP_EC = (1 << 15) - 1,
221+
222+ CP_RET = 1,
223+ CP_IRET = 2,
224+ CP_ENDBR = 3,
225+ CP_RSTRORSSP = 4,
226+ CP_SETSSBSY = 5,
227+
228+ CP_ENCL = 1 << 15,
229+};
230+
231+DEFINE_IDTENTRY_ERRORCODE(exc_control_protection)
232+{
233+ if (!cpu_feature_enabled(X86_FEATURE_IBT)) {
234+ pr_err("Unexpected #CP\n");
235+ BUG();
236+ }
237+
238+ if (WARN_ON_ONCE(user_mode(regs) || (error_code & CP_EC) != CP_ENDBR))
239+ return;
240+
241+ if (unlikely(regs->ip == (unsigned long)&ibt_selftest_ip)) {
242+ regs->ax = 0;
243+ return;
244+ }
245+
246+ pr_err("Missing ENDBR: %pS\n", (void *)instruction_pointer(regs));
247+ if (!ibt_fatal) {
248+ printk(KERN_DEFAULT CUT_HERE);
249+ __warn(__FILE__, __LINE__, (void *)regs->ip, TAINT_WARN, regs, NULL);
250+ return;
251+ }
252+ BUG();
253+}
254+
255+/* Must be noinline to ensure uniqueness of ibt_selftest_ip. */
256+noinline bool ibt_selftest(void)
257+{
258+ unsigned long ret;
259+
260+ asm (" lea ibt_selftest_ip(%%rip), %%rax\n\t"
261+ ANNOTATE_RETPOLINE_SAFE
262+ " jmp *%%rax\n\t"
263+ "ibt_selftest_ip:\n\t"
264+ UNWIND_HINT_FUNC
265+ ANNOTATE_NOENDBR
266+ " nop\n\t"
267+
268+ : "=a" (ret) : : "memory");
269+
270+ return !ret;
271+}
272+
273+static int __init ibt_setup(char *str)
274+{
275+ if (!strcmp(str, "off"))
276+ setup_clear_cpu_cap(X86_FEATURE_IBT);
277+
278+ if (!strcmp(str, "warn"))
279+ ibt_fatal = false;
280+
281+ return 1;
282+}
283+
284+__setup("ibt=", ibt_setup);
285+
286+#endif /* CONFIG_X86_KERNEL_IBT */
287+
213288 #ifdef CONFIG_X86_F00F_BUG
214289 void handle_invalid_op(struct pt_regs *regs)
215290 #else
arch/x86/kernel/vmlinux.lds.S+9−0
@@ -285,6 +285,15 @@ SECTIONS · 284 unmodified lines
285285 }
286286 #endif
287287
288+#ifdef CONFIG_X86_KERNEL_IBT
289+ . = ALIGN(8);
290+ .ibt_endbr_seal : AT(ADDR(.ibt_endbr_seal) - LOAD_OFFSET) {
291+ __ibt_endbr_seal = .;
292+ *(.ibt_endbr_seal)
293+ __ibt_endbr_seal_end = .;
294+ }
295+#endif
296+
288297 /*
289298 * struct alt_inst entries. From the header (alternative.h):
290299 * "Alternative instructions for different CPU types or capabilities"
arch/x86/kvm/emulate.c+10−6
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424 #include <linux/stringify.h>
2525 #include <asm/debugreg.h>
2626 #include <asm/nospec-branch.h>
27+#include <asm/ibt.h>
2728
2829 #include "x86.h"
2930 #include "tss.h"
@@ -189,7 +190,7 @@ · 159 unmodified lines
189190 #define X16(x...) X8(x), X8(x)
190191
191192 #define NR_FASTOP (ilog2(sizeof(ulong)) + 1)
192−#define FASTOP_SIZE 8
193+#define FASTOP_SIZE (8 * (1 + HAS_KERNEL_IBT))
193194
194195 struct opcode {
195196 u64 flags;
@@ -311,7 +312,8 @@ static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop); · 115 unmodified lines
311312 #define __FOP_FUNC(name) \
312313 ".align " __stringify(FASTOP_SIZE) " \n\t" \
313314 ".type " name ", @function \n\t" \
314− name ":\n\t"
315+ name ":\n\t" \
316+ ASM_ENDBR
315317
316318 #define FOP_FUNC(name) \
317319 __FOP_FUNC(#name)
@@ -433,21 +435,23 @@ static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop); · 115 unmodified lines
433435 /*
434436 * Depending on .config the SETcc functions look like:
435437 *
438+ * ENDBR [4 bytes; CONFIG_X86_KERNEL_IBT]
436439 * SETcc %al [3 bytes]
437440 * RET [1 byte]
438441 * INT3 [1 byte; CONFIG_SLS]
439442 *
440− * Which gives possible sizes 4 or 5. When rounded up to the
441− * next power-of-two alignment they become 4 or 8.
443+ * Which gives possible sizes 4, 5, 8 or 9. When rounded up to the
444+ * next power-of-two alignment they become 4, 8 or 16 resp.
442445 */
443−#define SETCC_LENGTH (4 + IS_ENABLED(CONFIG_SLS))
444−#define SETCC_ALIGN (4 << IS_ENABLED(CONFIG_SLS))
446+#define SETCC_LENGTH (ENDBR_INSN_SIZE + 4 + IS_ENABLED(CONFIG_SLS))
447+#define SETCC_ALIGN (4 << IS_ENABLED(CONFIG_SLS) << HAS_KERNEL_IBT)
445448 static_assert(SETCC_LENGTH <= SETCC_ALIGN);
446449
447450 #define FOP_SETCC(op) \
448451 ".align " __stringify(SETCC_ALIGN) " \n\t" \
449452 ".type " #op ", @function \n\t" \
450453 #op ": \n\t" \
454+ ASM_ENDBR \
451455 #op " %al \n\t" \
452456 __FOP_RET(#op)
453457
arch/x86/lib/error-inject.c+2−0
@@ -3,6 +3,7 @@ · 2 unmodified lines
33 #include <linux/linkage.h>
44 #include <linux/error-injection.h>
55 #include <linux/kprobes.h>
6+#include <linux/objtool.h>
67
78 asmlinkage void just_return_func(void);
89
@@ -11,6 +12,7 @@ asm( · 2 unmodified lines
1112 ".type just_return_func, @function\n"
1213 ".globl just_return_func\n"
1314 "just_return_func:\n"
15+ ANNOTATE_NOENDBR
1416 ASM_RET
1517 ".size just_return_func, .-just_return_func\n"
1618 );
arch/x86/lib/retpoline.S+1−0
@@ -55,6 +55,7 @@ SYM_INNER_LABEL(__x86_indirect_thunk_\reg, SYM_L_GLOBAL) · 54 unmodified lines
5555
5656 .align RETPOLINE_THUNK_SIZE
5757 SYM_CODE_START(__x86_indirect_thunk_array)
58+ ANNOTATE_NOENDBR // apply_retpolines
5859
5960 #define GEN(reg) THUNK reg
6061 #include <asm/GEN-for-each-reg.h>
arch/x86/net/bpf_jit_comp.c+24−2
@@ -46,6 +46,12 @@ static u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len) · 45 unmodified lines
4646 #define EMIT4_off32(b1, b2, b3, b4, off) \
4747 do { EMIT4(b1, b2, b3, b4); EMIT(off, 4); } while (0)
4848
49+#ifdef CONFIG_X86_KERNEL_IBT
50+#define EMIT_ENDBR() EMIT(gen_endbr(), 4)
51+#else
52+#define EMIT_ENDBR()
53+#endif
54+
4955 static bool is_imm8(int value)
5056 {
5157 return value <= 127 && value >= -128;
@@ -241,7 +247,7 @@ struct jit_context { · 189 unmodified lines
241247 /* Number of bytes emit_patch() needs to generate instructions */
242248 #define X86_PATCH_SIZE 5
243249 /* Number of bytes that will be skipped on tailcall */
244−#define X86_TAIL_CALL_OFFSET 11
250+#define X86_TAIL_CALL_OFFSET (11 + ENDBR_INSN_SIZE)
245251
246252 static void push_callee_regs(u8 **pprog, bool *callee_regs_used)
247253 {
@@ -286,6 +292,7 @@ static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf, · 38 unmodified lines
286292 /* BPF trampoline can be made to work without these nops,
287293 * but let's waste 5 bytes for now and optimize later
288294 */
295+ EMIT_ENDBR();
289296 memcpy(prog, x86_nops[5], X86_PATCH_SIZE);
290297 prog += X86_PATCH_SIZE;
291298 if (!ebpf_from_cbpf) {
@@ -296,6 +303,10 @@ static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf, · 4 unmodified lines
296303 }
297304 EMIT1(0x55); /* push rbp */
298305 EMIT3(0x48, 0x89, 0xE5); /* mov rbp, rsp */
306+
307+ /* X86_TAIL_CALL_OFFSET is here */
308+ EMIT_ENDBR();
309+
299310 /* sub rsp, rounded_stack_depth */
300311 if (stack_depth)
301312 EMIT3_off32(0x48, 0x81, 0xEC, round_up(stack_depth, 8));
@@ -380,6 +391,13 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t, · 78 unmodified lines
380391 /* BPF poking in modules is not supported */
381392 return -EINVAL;
382393
394+ /*
395+ * See emit_prologue(), for IBT builds the trampoline hook is preceded
396+ * with an ENDBR instruction.
397+ */
398+ if (is_endbr(*(u32 *)ip))
399+ ip += ENDBR_INSN_SIZE;
400+
383401 return __bpf_arch_text_poke(ip, t, old_addr, new_addr);
384402 }
385403
@@ -2013,14 +2031,18 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i · 1627 unmodified lines
20132031
20142032 ip_off = stack_size;
20152033
2016− if (flags & BPF_TRAMP_F_SKIP_FRAME)
2034+ if (flags & BPF_TRAMP_F_SKIP_FRAME) {
20172035 /* skip patched call instruction and point orig_call to actual
20182036 * body of the kernel function.
20192037 */
2038+ if (is_endbr(*(u32 *)orig_call))
2039+ orig_call += ENDBR_INSN_SIZE;
20202040 orig_call += X86_PATCH_SIZE;
2041+ }
20212042
20222043 prog = image;
20232044
2045+ EMIT_ENDBR();
20242046 EMIT1(0x55); /* push rbp */
20252047 EMIT3(0x48, 0x89, 0xE5); /* mov rbp, rsp */
20262048 EMIT4(0x48, 0x83, 0xEC, stack_size); /* sub rsp, stack_size */
arch/x86/platform/efi/Makefile+0−1
@@ -1,5 +1,4 @@
11 # SPDX-License-Identifier: GPL-2.0
2−OBJECT_FILES_NON_STANDARD_efi_thunk_$(BITS).o := y
32 KASAN_SANITIZE := n
43 GCOV_PROFILE := n
54
arch/x86/platform/efi/efi_thunk_64.S+4−2
@@ -20,12 +20,14 @@ · 19 unmodified lines
2020 */
2121
2222 #include <linux/linkage.h>
23+#include <linux/objtool.h>
2324 #include <asm/page_types.h>
2425 #include <asm/segment.h>
2526
2627 .text
2728 .code64
28−SYM_CODE_START(__efi64_thunk)
29+SYM_FUNC_START(__efi64_thunk)
30+STACK_FRAME_NON_STANDARD __efi64_thunk
2931 push %rbp
3032 push %rbx
3133
@@ -79,7 +81,7 @@ SYM_CODE_START(__efi64_thunk) · 47 unmodified lines
7981 2: pushl $__KERNEL_CS
8082 pushl %ebp
8183 lret
82−SYM_CODE_END(__efi64_thunk)
84+SYM_FUNC_END(__efi64_thunk)
8385
8486 .bss
8587 .balign 8
arch/x86/xen/enlighten_pv.c+9−1
@@ -624,6 +624,9 @@ static struct trap_array_entry trap_array[] = { · 623 unmodified lines
624624 TRAP_ENTRY(exc_coprocessor_error, false ),
625625 TRAP_ENTRY(exc_alignment_check, false ),
626626 TRAP_ENTRY(exc_simd_coprocessor_error, false ),
627+#ifdef CONFIG_X86_KERNEL_IBT
628+ TRAP_ENTRY(exc_control_protection, false ),
629+#endif
627630 };
628631
629632 static bool __ref get_trap_addr(void **addr, unsigned int ist)
@@ -1177,6 +1180,8 @@ static void __init xen_domu_set_legacy_features(void) · 547 unmodified lines
11771180 x86_platform.legacy.rtc = 0;
11781181 }
11791182
1183+extern void early_xen_iret_patch(void);
1184+
11801185 /* First C function to be called on Xen boot */
11811186 asmlinkage __visible void __init xen_start_kernel(void)
11821187 {
@@ -1187,6 +1192,10 @@ asmlinkage __visible void __init xen_start_kernel(void) · 4 unmodified lines
11871192 if (!xen_start_info)
11881193 return;
11891194
1195+ __text_gen_insn(&early_xen_iret_patch,
1196+ JMP32_INSN_OPCODE, &early_xen_iret_patch, &xen_iret,
1197+ JMP32_INSN_SIZE);
1198+
11901199 xen_domain_type = XEN_PV_DOMAIN;
11911200 xen_start_flags = xen_start_info->flags;
11921201
@@ -1195,7 +1204,6 @@ asmlinkage __visible void __init xen_start_kernel(void) · 2 unmodified lines
11951204 /* Install Xen paravirt ops */
11961205 pv_info = xen_info;
11971206 pv_ops.cpu = xen_cpu_ops.cpu;
1198− paravirt_iret = xen_iret;
11991207 xen_init_irq_ops();
12001208
12011209 /*
arch/x86/xen/xen-asm.S+10−0
@@ -122,6 +122,7 @@ SYM_FUNC_END(xen_read_cr2_direct); · 121 unmodified lines
122122 .macro xen_pv_trap name
123123 SYM_CODE_START(xen_\name)
124124 UNWIND_HINT_EMPTY
125+ ENDBR
125126 pop %rcx
126127 pop %r11
127128 jmp \name
@@ -147,6 +148,9 @@ xen_pv_trap asm_exc_page_fault · 19 unmodified lines
147148 xen_pv_trap asm_exc_spurious_interrupt_bug
148149 xen_pv_trap asm_exc_coprocessor_error
149150 xen_pv_trap asm_exc_alignment_check
151+#ifdef CONFIG_X86_KERNEL_IBT
152+xen_pv_trap asm_exc_control_protection
153+#endif
150154 #ifdef CONFIG_X86_MCE
151155 xen_pv_trap asm_xenpv_exc_machine_check
152156 #endif /* CONFIG_X86_MCE */
@@ -162,6 +166,7 @@ SYM_CODE_START(xen_early_idt_handler_array) · 9 unmodified lines
162166 i = 0
163167 .rept NUM_EXCEPTION_VECTORS
164168 UNWIND_HINT_EMPTY
169+ ENDBR
165170 pop %rcx
166171 pop %r11
167172 jmp early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE
@@ -189,6 +194,7 @@ hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32 · 21 unmodified lines
189194 */
190195 SYM_CODE_START(xen_iret)
191196 UNWIND_HINT_EMPTY
197+ ANNOTATE_NOENDBR
192198 pushq $0
193199 jmp hypercall_iret
194200 SYM_CODE_END(xen_iret)
@@ -230,6 +236,7 @@ SYM_CODE_END(xenpv_restore_regs_and_return_to_usermode) · 35 unmodified lines
230236 /* Normal 64-bit system call target */
231237 SYM_CODE_START(xen_syscall_target)
232238 UNWIND_HINT_EMPTY
239+ ENDBR
233240 popq %rcx
234241 popq %r11
235242
@@ -249,6 +256,7 @@ SYM_CODE_END(xen_syscall_target) · 13 unmodified lines
249256 /* 32-bit compat syscall target */
250257 SYM_CODE_START(xen_syscall32_target)
251258 UNWIND_HINT_EMPTY
259+ ENDBR
252260 popq %rcx
253261 popq %r11
254262
@@ -266,6 +274,7 @@ SYM_CODE_END(xen_syscall32_target) · 11 unmodified lines
266274 /* 32-bit compat sysenter target */
267275 SYM_CODE_START(xen_sysenter_target)
268276 UNWIND_HINT_EMPTY
277+ ENDBR
269278 /*
270279 * NB: Xen is polite and clears TF from EFLAGS for us. This means
271280 * that we don't need to guard against single step exceptions here.
@@ -289,6 +298,7 @@ SYM_CODE_END(xen_sysenter_target) · 17 unmodified lines
289298 SYM_CODE_START(xen_syscall32_target)
290299 SYM_CODE_START(xen_sysenter_target)
291300 UNWIND_HINT_EMPTY
301+ ENDBR
292302 lea 16(%rsp), %rsp /* strip %rcx, %r11 */
293303 mov $-ENOSYS, %rax
294304 pushq $0
arch/x86/xen/xen-head.S+7−2
@@ -25,8 +25,12 @@ · 24 unmodified lines
2525 SYM_CODE_START(hypercall_page)
2626 .rept (PAGE_SIZE / 32)
2727 UNWIND_HINT_FUNC
28− .skip 31, 0x90
29− RET
28+ ANNOTATE_NOENDBR
29+ ret
30+ /*
31+ * Xen will write the hypercall page, and sort out ENDBR.
32+ */
33+ .skip 31, 0xcc
3034 .endr
3135
3236 #define HYPERCALL(n) \
@@ -74,6 +78,7 @@ SYM_CODE_END(startup_xen) · 41 unmodified lines
7478 .pushsection .text
7579 SYM_CODE_START(asm_cpu_bringup_and_idle)
7680 UNWIND_HINT_EMPTY
81+ ENDBR
7782
7883 call cpu_bringup_and_idle
7984 SYM_CODE_END(asm_cpu_bringup_and_idle)
fs/fuse/ioctl.c+1−1
@@ -170,7 +170,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, · 169 unmodified lines
170170 #else
171171 if (flags & FUSE_IOCTL_COMPAT) {
172172 inarg.flags |= FUSE_IOCTL_32BIT;
173−#ifdef CONFIG_X86_X32
173+#ifdef CONFIG_X86_X32_ABI
174174 if (in_x32_syscall())
175175 inarg.flags |= FUSE_IOCTL_COMPAT_X32;
176176 #endif
fs/xfs/xfs_ioctl32.c+1−1
@@ -217,7 +217,7 @@ xfs_compat_ioc_fsbulkstat( · 216 unmodified lines
217217 inumbers_fmt_pf inumbers_func = xfs_fsinumbers_fmt_compat;
218218 bulkstat_one_fmt_pf bs_one_func = xfs_fsbulkstat_one_fmt_compat;
219219
220−#ifdef CONFIG_X86_X32
220+#ifdef CONFIG_X86_X32_ABI
221221 if (in_x32_syscall()) {
222222 /*
223223 * ... but on x32 the input xfs_fsop_bulkreq has pointers
include/asm-generic/vmlinux.lds.h+4−0
@@ -394,6 +394,7 @@ · 393 unmodified lines
394394 KEEP(*(__jump_table)) \
395395 __stop___jump_table = .;
396396
397+#ifdef CONFIG_HAVE_STATIC_CALL_INLINE
397398 #define STATIC_CALL_DATA \
398399 . = ALIGN(8); \
399400 __start_static_call_sites = .; \
@@ -402,6 +403,9 @@ · 2 unmodified lines
402403 __start_static_call_tramp_key = .; \
403404 KEEP(*(.static_call_tramp_key)) \
404405 __stop_static_call_tramp_key = .;
406+#else
407+#define STATIC_CALL_DATA
408+#endif
405409
406410 /*
407411 * Allow architectures to handle ro_after_init data on their
include/linux/cfi.h+10−1
@@ -34,8 +34,17 @@ static inline void cfi_module_remove(struct module *mod, unsigned long base_addr · 33 unmodified lines
3434
3535 #else /* !CONFIG_CFI_CLANG */
3636
37−#define __CFI_ADDRESSABLE(fn, __attr)
37+#ifdef CONFIG_X86_KERNEL_IBT
38+
39+#define __CFI_ADDRESSABLE(fn, __attr) \
40+ const void *__cfi_jt_ ## fn __visible __attr = (void *)&fn
41+
42+#endif /* CONFIG_X86_KERNEL_IBT */
3843
3944 #endif /* CONFIG_CFI_CLANG */
4045
46+#ifndef __CFI_ADDRESSABLE
47+#define __CFI_ADDRESSABLE(fn, __attr)
48+#endif
49+
4150 #endif /* _LINUX_CFI_H */
include/linux/compiler.h+0−7
@@ -125,18 +125,11 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, · 124 unmodified lines
125125 })
126126 #define annotate_unreachable() __annotate_unreachable(__COUNTER__)
127127
128−#define ASM_REACHABLE \
129− "998:\n\t" \
130− ".pushsection .discard.reachable\n\t" \
131− ".long 998b - .\n\t" \
132− ".popsection\n\t"
133−
134128 /* Annotate a C jump table to allow objtool to follow the code flow */
135129 #define __annotate_jump_table __section(".rodata..c_jump_table")
136130
137131 #else
138132 #define annotate_unreachable()
139−# define ASM_REACHABLE
140133 #define __annotate_jump_table
141134 #endif
142135
include/linux/cred.h+1−1
@@ -176,7 +176,7 @@ extern int set_cred_ucounts(struct cred *); · 175 unmodified lines
176176 * check for validity of credentials
177177 */
178178 #ifdef CONFIG_DEBUG_CREDENTIALS
179−extern void __invalid_creds(const struct cred *, const char *, unsigned);
179+extern void __noreturn __invalid_creds(const struct cred *, const char *, unsigned);
180180 extern void __validate_process_creds(struct task_struct *,
181181 const char *, unsigned);
182182
include/linux/kprobes.h+2−1
@@ -265,7 +265,6 @@ extern int arch_init_kprobes(void); · 264 unmodified lines
265265 extern void kprobes_inc_nmissed_count(struct kprobe *p);
266266 extern bool arch_within_kprobe_blacklist(unsigned long addr);
267267 extern int arch_populate_kprobe_blacklist(void);
268−extern bool arch_kprobe_on_func_entry(unsigned long offset);
269268 extern int kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset);
270269
271270 extern bool within_kprobe_blacklist(unsigned long addr);
@@ -384,6 +383,8 @@ static inline struct kprobe_ctlblk *get_kprobe_ctlblk(void) · 112 unmodified lines
384383 }
385384
386385 kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset);
386+kprobe_opcode_t *arch_adjust_kprobe_addr(unsigned long addr, unsigned long offset, bool *on_func_entry);
387+
387388 int register_kprobe(struct kprobe *p);
388389 void unregister_kprobe(struct kprobe *p);
389390 int register_kprobes(struct kprobe **kps, int num);
include/linux/objtool.h+32−0
@@ -77,6 +77,18 @@ struct unwind_hint { · 76 unmodified lines
7777 #define STACK_FRAME_NON_STANDARD_FP(func)
7878 #endif
7979
80+#define ANNOTATE_NOENDBR \
81+ "986: \n\t" \
82+ ".pushsection .discard.noendbr\n\t" \
83+ _ASM_PTR " 986b\n\t" \
84+ ".popsection\n\t"
85+
86+#define ASM_REACHABLE \
87+ "998:\n\t" \
88+ ".pushsection .discard.reachable\n\t" \
89+ ".long 998b - .\n\t" \
90+ ".popsection\n\t"
91+
8092 #else /* __ASSEMBLY__ */
8193
8294 /*
@@ -129,6 +141,20 @@ struct unwind_hint { · 46 unmodified lines
129141 .popsection
130142 .endm
131143
144+.macro ANNOTATE_NOENDBR
145+.Lhere_\@:
146+ .pushsection .discard.noendbr
147+ .quad .Lhere_\@
148+ .popsection
149+.endm
150+
151+.macro REACHABLE
152+.Lhere_\@:
153+ .pushsection .discard.reachable
154+ .long .Lhere_\@ - .
155+ .popsection
156+.endm
157+
132158 #endif /* __ASSEMBLY__ */
133159
134160 #else /* !CONFIG_STACK_VALIDATION */
@@ -139,12 +165,18 @@ struct unwind_hint { · 4 unmodified lines
139165 "\n\t"
140166 #define STACK_FRAME_NON_STANDARD(func)
141167 #define STACK_FRAME_NON_STANDARD_FP(func)
168+#define ANNOTATE_NOENDBR
169+#define ASM_REACHABLE
142170 #else
143171 #define ANNOTATE_INTRA_FUNCTION_CALL
144172 .macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0
145173 .endm
146174 .macro STACK_FRAME_NON_STANDARD func:req
147175 .endm
176+.macro ANNOTATE_NOENDBR
177+.endm
178+.macro REACHABLE
179+.endm
148180 #endif
149181
150182 #endif /* CONFIG_STACK_VALIDATION */
include/linux/sched/task.h+1−1
@@ -79,7 +79,7 @@ static inline void exit_thread(struct task_struct *tsk) · 78 unmodified lines
7979 {
8080 }
8181 #endif
82−extern void do_group_exit(int);
82+extern __noreturn void do_group_exit(int);
8383
8484 extern void exit_files(struct task_struct *);
8585 extern void exit_itimers(struct signal_struct *);
kernel/bpf/trampoline.c+4−16
@@ -117,18 +117,6 @@ static void bpf_trampoline_module_put(struct bpf_trampoline *tr) · 116 unmodified lines
117117 tr->mod = NULL;
118118 }
119119
120−static int is_ftrace_location(void *ip)
121−{
122− long addr;
123−
124− addr = ftrace_location((long)ip);
125− if (!addr)
126− return 0;
127− if (WARN_ON_ONCE(addr != (long)ip))
128− return -EFAULT;
129− return 1;
130−}
131−
132120 static int unregister_fentry(struct bpf_trampoline *tr, void *old_addr)
133121 {
134122 void *ip = tr->func.addr;
@@ -160,12 +148,12 @@ static int modify_fentry(struct bpf_trampoline *tr, void *old_addr, void *new_ad · 25 unmodified lines
160148 static int register_fentry(struct bpf_trampoline *tr, void *new_addr)
161149 {
162150 void *ip = tr->func.addr;
151+ unsigned long faddr;
163152 int ret;
164153
165− ret = is_ftrace_location(ip);
166− if (ret < 0)
167− return ret;
168− tr->func.ftrace_managed = ret;
154+ faddr = ftrace_location((unsigned long)ip);
155+ if (faddr)
156+ tr->func.ftrace_managed = true;
169157
170158 if (bpf_trampoline_module_get(tr))
171159 return -ENOENT;
kernel/cred.c+1−1
@@ -870,7 +870,7 @@ static void dump_invalid_creds(const struct cred *cred, const char *label, · 869 unmodified lines
870870 /*
871871 * report use of invalid credentials
872872 */
873−void __invalid_creds(const struct cred *cred, const char *file, unsigned line)
873+void __noreturn __invalid_creds(const struct cred *cred, const char *file, unsigned line)
874874 {
875875 printk(KERN_ERR "CRED: Invalid credentials\n");
876876 printk(KERN_ERR "CRED: At %s:%u\n", file, line);
kernel/exit.c+1−1
@@ -895,7 +895,7 @@ SYSCALL_DEFINE1(exit, int, error_code) · 894 unmodified lines
895895 * Take down every thread in the group. This is called by fatal signals
896896 * as well as by sys_exit_group (below).
897897 */
898−void
898+void __noreturn
899899 do_group_exit(int exit_code)
900900 {
901901 struct signal_struct *sig = current->signal;
kernel/kprobes.c+54−20
@@ -1488,25 +1488,69 @@ bool within_kprobe_blacklist(unsigned long addr) · 1487 unmodified lines
14881488 return false;
14891489 }
14901490
1491+/*
1492+ * arch_adjust_kprobe_addr - adjust the address
1493+ * @addr: symbol base address
1494+ * @offset: offset within the symbol
1495+ * @on_func_entry: was this @addr+@offset on the function entry
1496+ *
1497+ * Typically returns @addr + @offset, except for special cases where the
1498+ * function might be prefixed by a CFI landing pad, in that case any offset
1499+ * inside the landing pad is mapped to the first 'real' instruction of the
1500+ * symbol.
1501+ *
1502+ * Specifically, for things like IBT/BTI, skip the resp. ENDBR/BTI.C
1503+ * instruction at +0.
1504+ */
1505+kprobe_opcode_t *__weak arch_adjust_kprobe_addr(unsigned long addr,
1506+ unsigned long offset,
1507+ bool *on_func_entry)
1508+{
1509+ *on_func_entry = !offset;
1510+ return (kprobe_opcode_t *)(addr + offset);
1511+}
1512+
14911513 /*
14921514 * If 'symbol_name' is specified, look it up and add the 'offset'
14931515 * to it. This way, we can specify a relative address to a symbol.
14941516 * This returns encoded errors if it fails to look up symbol or invalid
14951517 * combination of parameters.
14961518 */
1497−static kprobe_opcode_t *_kprobe_addr(kprobe_opcode_t *addr,
1498− const char *symbol_name, unsigned int offset)
1519+static kprobe_opcode_t *
1520+_kprobe_addr(kprobe_opcode_t *addr, const char *symbol_name,
1521+ unsigned long offset, bool *on_func_entry)
14991522 {
15001523 if ((symbol_name && addr) || (!symbol_name && !addr))
15011524 goto invalid;
15021525
15031526 if (symbol_name) {
1527+ /*
1528+ * Input: @sym + @offset
1529+ * Output: @addr + @offset
1530+ *
1531+ * NOTE: kprobe_lookup_name() does *NOT* fold the offset
1532+ * argument into it's output!
1533+ */
15041534 addr = kprobe_lookup_name(symbol_name, offset);
15051535 if (!addr)
15061536 return ERR_PTR(-ENOENT);
15071537 }
15081538
1509− addr = (kprobe_opcode_t *)(((char *)addr) + offset);
1539+ /*
1540+ * So here we have @addr + @offset, displace it into a new
1541+ * @addr' + @offset' where @addr' is the symbol start address.
1542+ */
1543+ addr = (void *)addr + offset;
1544+ if (!kallsyms_lookup_size_offset((unsigned long)addr, NULL, &offset))
1545+ return ERR_PTR(-ENOENT);
1546+ addr = (void *)addr - offset;
1547+
1548+ /*
1549+ * Then ask the architecture to re-combine them, taking care of
1550+ * magical function entry details while telling us if this was indeed
1551+ * at the start of the function.
1552+ */
1553+ addr = arch_adjust_kprobe_addr((unsigned long)addr, offset, on_func_entry);
15101554 if (addr)
15111555 return addr;
15121556
@@ -1516,7 +1560,8 @@ invalid: · 3 unmodified lines
15161560
15171561 static kprobe_opcode_t *kprobe_addr(struct kprobe *p)
15181562 {
1519− return _kprobe_addr(p->addr, p->symbol_name, p->offset);
1563+ bool on_func_entry;
1564+ return _kprobe_addr(p->addr, p->symbol_name, p->offset, &on_func_entry);
15201565 }
15211566
15221567 /*
@@ -1562,14 +1607,10 @@ static inline int warn_kprobe_rereg(struct kprobe *p) · 39 unmodified lines
15621607
15631608 static int check_ftrace_location(struct kprobe *p)
15641609 {
1565− unsigned long ftrace_addr;
1610+ unsigned long addr = (unsigned long)p->addr;
15661611
1567− ftrace_addr = ftrace_location((unsigned long)p->addr);
1568− if (ftrace_addr) {
1612+ if (ftrace_location(addr) == addr) {
15691613 #ifdef CONFIG_KPROBES_ON_FTRACE
1570− /* Given address is not on the instruction boundary */
1571− if ((unsigned long)p->addr != ftrace_addr)
1572− return -EILSEQ;
15731614 p->flags |= KPROBE_FLAG_FTRACE;
15741615 #else /* !CONFIG_KPROBES_ON_FTRACE */
15751616 return -EINVAL;
@@ -2047,11 +2088,6 @@ static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs) · 471 unmodified lines
20472088 }
20482089 NOKPROBE_SYMBOL(pre_handler_kretprobe);
20492090
2050−bool __weak arch_kprobe_on_func_entry(unsigned long offset)
2051−{
2052− return !offset;
2053−}
2054−
20552091 /**
20562092 * kprobe_on_func_entry() -- check whether given address is function entry
20572093 * @addr: Target address
@@ -2067,15 +2103,13 @@ bool __weak arch_kprobe_on_func_entry(unsigned long offset) · 9 unmodified lines
20672103 */
20682104 int kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset)
20692105 {
2070− kprobe_opcode_t *kp_addr = _kprobe_addr(addr, sym, offset);
2106+ bool on_func_entry;
2107+ kprobe_opcode_t *kp_addr = _kprobe_addr(addr, sym, offset, &on_func_entry);
20712108
20722109 if (IS_ERR(kp_addr))
20732110 return PTR_ERR(kp_addr);
20742111
2075− if (!kallsyms_lookup_size_offset((unsigned long)kp_addr, NULL, &offset))
2076− return -ENOENT;
2077−
2078− if (!arch_kprobe_on_func_entry(offset))
2112+ if (!on_func_entry)
20792113 return -EINVAL;
20802114
20812115 return 0;
kernel/livepatch/patch.c+2−17
@@ -124,19 +124,6 @@ unlock: · 123 unmodified lines
124124 ftrace_test_recursion_unlock(bit);
125125 }
126126
127−/*
128− * Convert a function address into the appropriate ftrace location.
129− *
130− * Usually this is just the address of the function, but on some architectures
131− * it's more complicated so allow them to provide a custom behaviour.
132− */
133−#ifndef klp_get_ftrace_location
134−static unsigned long klp_get_ftrace_location(unsigned long faddr)
135−{
136− return faddr;
137−}
138−#endif
139−
140127 static void klp_unpatch_func(struct klp_func *func)
141128 {
142129 struct klp_ops *ops;
@@ -153,8 +140,7 @@ static void klp_unpatch_func(struct klp_func *func) · 10 unmodified lines
153140 if (list_is_singular(&ops->func_stack)) {
154141 unsigned long ftrace_loc;
155142
156− ftrace_loc =
157− klp_get_ftrace_location((unsigned long)func->old_func);
143+ ftrace_loc = ftrace_location((unsigned long)func->old_func);
158144 if (WARN_ON(!ftrace_loc))
159145 return;
160146
@@ -186,8 +172,7 @@ static int klp_patch_func(struct klp_func *func) · 25 unmodified lines
186172 if (!ops) {
187173 unsigned long ftrace_loc;
188174
189− ftrace_loc =
190− klp_get_ftrace_location((unsigned long)func->old_func);
175+ ftrace_loc = ftrace_location((unsigned long)func->old_func);
191176 if (!ftrace_loc) {
192177 pr_err("failed to find location for function '%s'\n",
193178 func->old_name);
kernel/trace/ftrace.c+40−8
@@ -1568,17 +1568,34 @@ unsigned long ftrace_location_range(unsigned long start, unsigned long end) · 1567 unmodified lines
15681568 }
15691569
15701570 /**
1571− * ftrace_location - return true if the ip giving is a traced location
1571+ * ftrace_location - return the ftrace location
15721572 * @ip: the instruction pointer to check
15731573 *
1574− * Returns rec->ip if @ip given is a pointer to a ftrace location.
1575− * That is, the instruction that is either a NOP or call to
1576− * the function tracer. It checks the ftrace internal tables to
1577− * determine if the address belongs or not.
1574+ * If @ip matches the ftrace location, return @ip.
1575+ * If @ip matches sym+0, return sym's ftrace location.
1576+ * Otherwise, return 0.
15781577 */
15791578 unsigned long ftrace_location(unsigned long ip)
15801579 {
1581− return ftrace_location_range(ip, ip);
1580+ struct dyn_ftrace *rec;
1581+ unsigned long offset;
1582+ unsigned long size;
1583+
1584+ rec = lookup_rec(ip, ip);
1585+ if (!rec) {
1586+ if (!kallsyms_lookup_size_offset(ip, &size, &offset))
1587+ goto out;
1588+
1589+ /* map sym+0 to __fentry__ */
1590+ if (!offset)
1591+ rec = lookup_rec(ip, ip + size - 1);
1592+ }
1593+
1594+ if (rec)
1595+ return rec->ip;
1596+
1597+out:
1598+ return 0;
15821599 }
15831600
15841601 /**
@@ -4962,7 +4979,8 @@ __ftrace_match_addr(struct ftrace_hash *hash, unsigned long ip, int remove) · 3377 unmodified lines
49624979 {
49634980 struct ftrace_func_entry *entry;
49644981
4965− if (!ftrace_location(ip))
4982+ ip = ftrace_location(ip);
4983+ if (!ip)
49664984 return -EINVAL;
49674985
49684986 if (remove) {
@@ -5131,11 +5149,16 @@ int register_ftrace_direct(unsigned long ip, unsigned long addr) · 162 unmodified lines
51315149 struct ftrace_func_entry *entry;
51325150 struct ftrace_hash *free_hash = NULL;
51335151 struct dyn_ftrace *rec;
5134− int ret = -EBUSY;
5152+ int ret = -ENODEV;
51355153
51365154 mutex_lock(&direct_mutex);
51375155
5156+ ip = ftrace_location(ip);
5157+ if (!ip)
5158+ goto out_unlock;
5159+
51385160 /* See if there's a direct function at @ip already */
5161+ ret = -EBUSY;
51395162 if (ftrace_find_rec_direct(ip))
51405163 goto out_unlock;
51415164
@@ -5243,6 +5266,10 @@ int unregister_ftrace_direct(unsigned long ip, unsigned long addr) · 101 unmodified lines
52435266
52445267 mutex_lock(&direct_mutex);
52455268
5269+ ip = ftrace_location(ip);
5270+ if (!ip)
5271+ goto out_unlock;
5272+
52465273 entry = find_direct_entry(&ip, NULL);
52475274 if (!entry)
52485275 goto out_unlock;
@@ -5375,6 +5402,11 @@ int modify_ftrace_direct(unsigned long ip, · 126 unmodified lines
53755402 mutex_lock(&direct_mutex);
53765403
53775404 mutex_lock(&ftrace_lock);
5405+
5406+ ip = ftrace_location(ip);
5407+ if (!ip)
5408+ goto out_unlock;
5409+
53785410 entry = find_direct_entry(&ip, &rec);
53795411 if (!entry)
53805412 goto out_unlock;
samples/ftrace/ftrace-direct-modify.c+5−0
@@ -24,20 +24,25 @@ static unsigned long my_ip = (unsigned long)schedule; · 23 unmodified lines
2424
2525 #ifdef CONFIG_X86_64
2626
27+#include <asm/ibt.h>
28+
2729 asm (
2830 " .pushsection .text, \"ax\", @progbits\n"
2931 " .type my_tramp1, @function\n"
3032 " .globl my_tramp1\n"
3133 " my_tramp1:"
34+ ASM_ENDBR
3235 " pushq %rbp\n"
3336 " movq %rsp, %rbp\n"
3437 " call my_direct_func1\n"
3538 " leave\n"
3639 " .size my_tramp1, .-my_tramp1\n"
3740 ASM_RET
41+
3842 " .type my_tramp2, @function\n"
3943 " .globl my_tramp2\n"
4044 " my_tramp2:"
45+ ASM_ENDBR
4146 " pushq %rbp\n"
4247 " movq %rsp, %rbp\n"
4348 " call my_direct_func2\n"
samples/ftrace/ftrace-direct-multi-modify.c+7−3
@@ -22,11 +22,14 @@ extern void my_tramp2(void *); · 21 unmodified lines
2222
2323 #ifdef CONFIG_X86_64
2424
25+#include <asm/ibt.h>
26+
2527 asm (
2628 " .pushsection .text, \"ax\", @progbits\n"
2729 " .type my_tramp1, @function\n"
2830 " .globl my_tramp1\n"
2931 " my_tramp1:"
32+ ASM_ENDBR
3033 " pushq %rbp\n"
3134 " movq %rsp, %rbp\n"
3235 " pushq %rdi\n"
@@ -34,12 +37,13 @@ asm ( · 1 unmodified line
3437 " call my_direct_func1\n"
3538 " popq %rdi\n"
3639 " leave\n"
37−" ret\n"
40+ ASM_RET
3841 " .size my_tramp1, .-my_tramp1\n"
42+
3943 " .type my_tramp2, @function\n"
40−"\n"
4144 " .globl my_tramp2\n"
4245 " my_tramp2:"
46+ ASM_ENDBR
4347 " pushq %rbp\n"
4448 " movq %rsp, %rbp\n"
4549 " pushq %rdi\n"
@@ -47,7 +51,7 @@ asm ( · 1 unmodified line
4751 " call my_direct_func2\n"
4852 " popq %rdi\n"
4953 " leave\n"
50−" ret\n"
54+ ASM_RET
5155 " .size my_tramp2, .-my_tramp2\n"
5256 " .popsection\n"
5357 );
samples/ftrace/ftrace-direct-multi.c+4−1
@@ -17,11 +17,14 @@ extern void my_tramp(void *); · 16 unmodified lines
1717
1818 #ifdef CONFIG_X86_64
1919
20+#include <asm/ibt.h>
21+
2022 asm (
2123 " .pushsection .text, \"ax\", @progbits\n"
2224 " .type my_tramp, @function\n"
2325 " .globl my_tramp\n"
2426 " my_tramp:"
27+ ASM_ENDBR
2528 " pushq %rbp\n"
2629 " movq %rsp, %rbp\n"
2730 " pushq %rdi\n"
@@ -29,7 +32,7 @@ asm ( · 1 unmodified line
2932 " call my_direct_func\n"
3033 " popq %rdi\n"
3134 " leave\n"
32−" ret\n"
35+ ASM_RET
3336 " .size my_tramp, .-my_tramp\n"
3437 " .popsection\n"
3538 );
samples/ftrace/ftrace-direct-too.c+3−0
@@ -19,11 +19,14 @@ extern void my_tramp(void *); · 18 unmodified lines
1919
2020 #ifdef CONFIG_X86_64
2121
22+#include <asm/ibt.h>
23+
2224 asm (
2325 " .pushsection .text, \"ax\", @progbits\n"
2426 " .type my_tramp, @function\n"
2527 " .globl my_tramp\n"
2628 " my_tramp:"
29+ ASM_ENDBR
2730 " pushq %rbp\n"
2831 " movq %rsp, %rbp\n"
2932 " pushq %rdi\n"
samples/ftrace/ftrace-direct.c+3−0
@@ -16,11 +16,14 @@ extern void my_tramp(void *); · 15 unmodified lines
1616
1717 #ifdef CONFIG_X86_64
1818
19+#include <asm/ibt.h>
20+
1921 asm (
2022 " .pushsection .text, \"ax\", @progbits\n"
2123 " .type my_tramp, @function\n"
2224 " .globl my_tramp\n"
2325 " my_tramp:"
26+ ASM_ENDBR
2427 " pushq %rbp\n"
2528 " movq %rsp, %rbp\n"
2629 " pushq %rdi\n"
scripts/Makefile.build+14−13
@@ -88,8 +88,8 @@ endif · 87 unmodified lines
8888
8989 targets-for-modules := $(patsubst %.o, %.mod, $(filter %.o, $(obj-m)))
9090
91−ifdef CONFIG_LTO_CLANG
92−targets-for-modules += $(patsubst %.o, %.lto.o, $(filter %.o, $(obj-m)))
91+ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
92+targets-for-modules += $(patsubst %.o, %.prelink.o, $(filter %.o, $(obj-m)))
9393 endif
9494
9595 ifdef need-modorder
@@ -230,6 +230,7 @@ objtool := $(objtree)/tools/objtool/objtool · 134 unmodified lines
230230 objtool_args = \
231231 $(if $(CONFIG_UNWINDER_ORC),orc generate,check) \
232232 $(if $(part-of-module), --module) \
233+ $(if $(CONFIG_X86_KERNEL_IBT), --lto --ibt) \
233234 $(if $(CONFIG_FRAME_POINTER),, --no-fp) \
234235 $(if $(CONFIG_GCOV_KERNEL)$(CONFIG_LTO_CLANG), --no-unreachable)\
235236 $(if $(CONFIG_RETPOLINE), --retpoline) \
@@ -242,7 +243,7 @@ cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(o · 6 unmodified lines
242243
243244 endif # CONFIG_STACK_VALIDATION
244245
245−ifdef CONFIG_LTO_CLANG
246+ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
246247
247248 # Skip objtool for LLVM bitcode
248249 $(obj)/%.o: objtool-enabled :=
@@ -288,24 +289,24 @@ $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE · 39 unmodified lines
288289 $(call if_changed_rule,cc_o_c)
289290 $(call cmd,force_checksrc)
290291
291−ifdef CONFIG_LTO_CLANG
292+ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
292293 # Module .o files may contain LLVM bitcode, compile them into native code
293294 # before ELF processing
294−quiet_cmd_cc_lto_link_modules = LTO [M] $@
295−cmd_cc_lto_link_modules = \
295+quiet_cmd_cc_prelink_modules = LD [M] $@
296+ cmd_cc_prelink_modules = \
296297 $(LD) $(ld_flags) -r -o $@ \
297− $(shell [ -s $(@:.lto.o=.o.symversions) ] && \
298− echo -T $(@:.lto.o=.o.symversions)) \
298+ $(shell [ -s $(@:.prelink.o=.o.symversions) ] && \
299+ echo -T $(@:.prelink.o=.o.symversions)) \
299300 --whole-archive $(filter-out FORCE,$^) \
300301 $(cmd_objtool)
301302
302303 # objtool was skipped for LLVM bitcode, run it now that we have compiled
303304 # modules into native code
304−$(obj)/%.lto.o: objtool-enabled = y
305−$(obj)/%.lto.o: part-of-module := y
305+$(obj)/%.prelink.o: objtool-enabled = y
306+$(obj)/%.prelink.o: part-of-module := y
306307
307−$(obj)/%.lto.o: $(obj)/%.o FORCE
308− $(call if_changed,cc_lto_link_modules)
308+$(obj)/%.prelink.o: $(obj)/%.o FORCE
309+ $(call if_changed,cc_prelink_modules)
309310 endif
310311
311312 cmd_mod = { \
@@ -469,7 +470,7 @@ $(obj)/lib.a: $(lib-y) FORCE · 157 unmodified lines
469470 # Do not replace $(filter %.o,^) with $(real-prereqs). When a single object
470471 # module is turned into a multi object module, $^ will contain header file
471472 # dependencies recorded in the .*.cmd file.
472−ifdef CONFIG_LTO_CLANG
473+ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
473474 quiet_cmd_link_multi-m = AR [M] $@
474475 cmd_link_multi-m = \
475476 $(cmd_update_lto_symversions); \
scripts/Makefile.lib+2−2
@@ -225,11 +225,11 @@ dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \ · 224 unmodified lines
225225 $(addprefix -I,$(DTC_INCLUDE)) \
226226 -undef -D__DTS__
227227
228−ifeq ($(CONFIG_LTO_CLANG),y)
228+ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
229229 # With CONFIG_LTO_CLANG, .o files in modules might be LLVM bitcode, so we
230230 # need to run LTO to compile them into native code (.lto.o) before further
231231 # processing.
232−mod-prelink-ext := .lto
232+mod-prelink-ext := .prelink
233233 endif
234234
235235 # Useful for describing the dependency of composite objects
scripts/link-vmlinux.sh+9−3
@@ -108,14 +108,20 @@ objtool_link() · 107 unmodified lines
108108 local objtoolcmd;
109109 local objtoolopt;
110110
111− if is_enabled CONFIG_LTO_CLANG && is_enabled CONFIG_STACK_VALIDATION; then
111+ if is_enabled CONFIG_STACK_VALIDATION && \
112+ ( is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT ); then
113+
112114 # Don't perform vmlinux validation unless explicitly requested,
113115 # but run objtool on vmlinux.o now that we have an object file.
114116 if is_enabled CONFIG_UNWINDER_ORC; then
115117 objtoolcmd="orc generate"
116118 fi
117119
118− objtoolopt="${objtoolopt} --duplicate"
120+ objtoolopt="${objtoolopt} --lto"
121+
122+ if is_enabled CONFIG_X86_KERNEL_IBT; then
123+ objtoolopt="${objtoolopt} --ibt"
124+ fi
119125
120126 if is_enabled CONFIG_FTRACE_MCOUNT_USE_OBJTOOL; then
121127 objtoolopt="${objtoolopt} --mcount"
@@ -168,7 +174,7 @@ vmlinux_link() · 46 unmodified lines
168174 # skip output file argument
169175 shift
170176
171− if is_enabled CONFIG_LTO_CLANG; then
177+ if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then
172178 # Use vmlinux.o instead of performing the slow LTO link again.
173179 objs=vmlinux.o
174180 libs=
scripts/mod/modpost.c+6−6
@@ -1996,9 +1996,9 @@ static char *remove_dot(char *s) · 1995 unmodified lines
19961996 if (m && (s[n + m] == '.' || s[n + m] == 0))
19971997 s[n] = 0;
19981998
1999− /* strip trailing .lto */
2000− if (strends(s, ".lto"))
2001− s[strlen(s) - 4] = '\0';
1999+ /* strip trailing .prelink */
2000+ if (strends(s, ".prelink"))
2001+ s[strlen(s) - 8] = '\0';
20022002 }
20032003 return s;
20042004 }
@@ -2022,9 +2022,9 @@ static void read_symbols(const char *modname) · 17 unmodified lines
20222022 /* strip trailing .o */
20232023 tmp = NOFAIL(strdup(modname));
20242024 tmp[strlen(tmp) - 2] = '\0';
2025− /* strip trailing .lto */
2026− if (strends(tmp, ".lto"))
2027− tmp[strlen(tmp) - 4] = '\0';
2025+ /* strip trailing .prelink */
2026+ if (strends(tmp, ".prelink"))
2027+ tmp[strlen(tmp) - 8] = '\0';
20282028 mod = new_module(tmp);
20292029 free(tmp);
20302030 }
sound/core/control_compat.c+8−8
@@ -150,7 +150,7 @@ struct snd_ctl_elem_value32 { · 149 unmodified lines
150150 unsigned char reserved[128];
151151 };
152152
153−#ifdef CONFIG_X86_X32
153+#ifdef CONFIG_X86_X32_ABI
154154 /* x32 has a different alignment for 64bit values from ia32 */
155155 struct snd_ctl_elem_value_x32 {
156156 struct snd_ctl_elem_id id;
@@ -162,7 +162,7 @@ struct snd_ctl_elem_value_x32 { · 5 unmodified lines
162162 } value;
163163 unsigned char reserved[128];
164164 };
165−#endif /* CONFIG_X86_X32 */
165+#endif /* CONFIG_X86_X32_ABI */
166166
167167 /* get the value type and count of the control */
168168 static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
@@ -347,7 +347,7 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file, · 178 unmodified lines
347347 return ctl_elem_write_user(file, data32, &data32->value);
348348 }
349349
350−#ifdef CONFIG_X86_X32
350+#ifdef CONFIG_X86_X32_ABI
351351 static int snd_ctl_elem_read_user_x32(struct snd_card *card,
352352 struct snd_ctl_elem_value_x32 __user *data32)
353353 {
@@ -359,7 +359,7 @@ static int snd_ctl_elem_write_user_x32(struct snd_ctl_file *file, · 5 unmodified lines
359359 {
360360 return ctl_elem_write_user(file, data32, &data32->value);
361361 }
362−#endif /* CONFIG_X86_X32 */
362+#endif /* CONFIG_X86_X32_ABI */
363363
364364 /* add or replace a user control */
365365 static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
@@ -418,10 +418,10 @@ enum { · 52 unmodified lines
418418 SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct snd_ctl_elem_value32),
419419 SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct snd_ctl_elem_info32),
420420 SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct snd_ctl_elem_info32),
421−#ifdef CONFIG_X86_X32
421+#ifdef CONFIG_X86_X32_ABI
422422 SNDRV_CTL_IOCTL_ELEM_READ_X32 = _IOWR('U', 0x12, struct snd_ctl_elem_value_x32),
423423 SNDRV_CTL_IOCTL_ELEM_WRITE_X32 = _IOWR('U', 0x13, struct snd_ctl_elem_value_x32),
424−#endif /* CONFIG_X86_X32 */
424+#endif /* CONFIG_X86_X32_ABI */
425425 };
426426
427427 static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
@@ -460,12 +460,12 @@ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, uns · 32 unmodified lines
460460 return snd_ctl_elem_add_compat(ctl, argp, 0);
461461 case SNDRV_CTL_IOCTL_ELEM_REPLACE32:
462462 return snd_ctl_elem_add_compat(ctl, argp, 1);
463−#ifdef CONFIG_X86_X32
463+#ifdef CONFIG_X86_X32_ABI
464464 case SNDRV_CTL_IOCTL_ELEM_READ_X32:
465465 return snd_ctl_elem_read_user_x32(ctl->card, argp);
466466 case SNDRV_CTL_IOCTL_ELEM_WRITE_X32:
467467 return snd_ctl_elem_write_user_x32(ctl, argp);
468−#endif /* CONFIG_X86_X32 */
468+#endif /* CONFIG_X86_X32_ABI */
469469 }
470470
471471 down_read(&snd_ioctl_rwsem);
sound/core/pcm_compat.c+10−10
@@ -147,13 +147,13 @@ static int snd_pcm_ioctl_channel_info_compat(struct snd_pcm_substream *substream · 146 unmodified lines
147147 return err;
148148 }
149149
150−#ifdef CONFIG_X86_X32
150+#ifdef CONFIG_X86_X32_ABI
151151 /* X32 ABI has the same struct as x86-64 for snd_pcm_channel_info */
152152 static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream,
153153 struct snd_pcm_channel_info __user *src);
154154 #define snd_pcm_ioctl_channel_info_x32(s, p) \
155155 snd_pcm_channel_info_user(s, p)
156−#endif /* CONFIG_X86_X32 */
156+#endif /* CONFIG_X86_X32_ABI */
157157
158158 struct compat_snd_pcm_status64 {
159159 snd_pcm_state_t state;
@@ -375,7 +375,7 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream, · 215 unmodified lines
375375 return err;
376376 }
377377
378−#ifdef CONFIG_X86_X32
378+#ifdef CONFIG_X86_X32_ABI
379379 /* X32 ABI has 64bit timespec and 64bit alignment */
380380 struct snd_pcm_mmap_status_x32 {
381381 snd_pcm_state_t state;
@@ -468,7 +468,7 @@ static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream, · 86 unmodified lines
468468
469469 return 0;
470470 }
471−#endif /* CONFIG_X86_X32 */
471+#endif /* CONFIG_X86_X32_ABI */
472472
473473 #ifdef __BIG_ENDIAN
474474 typedef char __pad_before_u32[4];
@@ -560,10 +560,10 @@ enum { · 85 unmodified lines
560560 SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct snd_xfern32),
561561 SNDRV_PCM_IOCTL_STATUS_COMPAT64 = _IOR('A', 0x20, struct compat_snd_pcm_status64),
562562 SNDRV_PCM_IOCTL_STATUS_EXT_COMPAT64 = _IOWR('A', 0x24, struct compat_snd_pcm_status64),
563−#ifdef CONFIG_X86_X32
563+#ifdef CONFIG_X86_X32_ABI
564564 SNDRV_PCM_IOCTL_CHANNEL_INFO_X32 = _IOR('A', 0x32, struct snd_pcm_channel_info),
565565 SNDRV_PCM_IOCTL_SYNC_PTR_X32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr_x32),
566−#endif /* CONFIG_X86_X32 */
566+#endif /* CONFIG_X86_X32_ABI */
567567 };
568568
569569 static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
@@ -607,10 +607,10 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l · 37 unmodified lines
607607 case __SNDRV_PCM_IOCTL_SYNC_PTR32:
608608 return snd_pcm_common_ioctl(file, substream, cmd, argp);
609609 case __SNDRV_PCM_IOCTL_SYNC_PTR64:
610−#ifdef CONFIG_X86_X32
610+#ifdef CONFIG_X86_X32_ABI
611611 if (in_x32_syscall())
612612 return snd_pcm_ioctl_sync_ptr_x32(substream, argp);
613−#endif /* CONFIG_X86_X32 */
613+#endif /* CONFIG_X86_X32_ABI */
614614 return snd_pcm_ioctl_sync_ptr_buggy(substream, argp);
615615 case SNDRV_PCM_IOCTL_HW_REFINE32:
616616 return snd_pcm_ioctl_hw_params_compat(substream, 1, argp);
@@ -642,10 +642,10 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l · 25 unmodified lines
642642 return snd_pcm_status_user_compat64(substream, argp, false);
643643 case SNDRV_PCM_IOCTL_STATUS_EXT_COMPAT64:
644644 return snd_pcm_status_user_compat64(substream, argp, true);
645−#ifdef CONFIG_X86_X32
645+#ifdef CONFIG_X86_X32_ABI
646646 case SNDRV_PCM_IOCTL_CHANNEL_INFO_X32:
647647 return snd_pcm_ioctl_channel_info_x32(substream, argp);
648−#endif /* CONFIG_X86_X32 */
648+#endif /* CONFIG_X86_X32_ABI */
649649 }
650650
651651 return -ENOIOCTLCMD;
tools/include/linux/objtool.h+32−0
@@ -77,6 +77,18 @@ struct unwind_hint { · 76 unmodified lines
7777 #define STACK_FRAME_NON_STANDARD_FP(func)
7878 #endif
7979
80+#define ANNOTATE_NOENDBR \
81+ "986: \n\t" \
82+ ".pushsection .discard.noendbr\n\t" \
83+ _ASM_PTR " 986b\n\t" \
84+ ".popsection\n\t"
85+
86+#define ASM_REACHABLE \
87+ "998:\n\t" \
88+ ".pushsection .discard.reachable\n\t" \
89+ ".long 998b - .\n\t" \
90+ ".popsection\n\t"
91+
8092 #else /* __ASSEMBLY__ */
8193
8294 /*
@@ -129,6 +141,20 @@ struct unwind_hint { · 46 unmodified lines
129141 .popsection
130142 .endm
131143
144+.macro ANNOTATE_NOENDBR
145+.Lhere_\@:
146+ .pushsection .discard.noendbr
147+ .quad .Lhere_\@
148+ .popsection
149+.endm
150+
151+.macro REACHABLE
152+.Lhere_\@:
153+ .pushsection .discard.reachable
154+ .long .Lhere_\@ - .
155+ .popsection
156+.endm
157+
132158 #endif /* __ASSEMBLY__ */
133159
134160 #else /* !CONFIG_STACK_VALIDATION */
@@ -139,12 +165,18 @@ struct unwind_hint { · 4 unmodified lines
139165 "\n\t"
140166 #define STACK_FRAME_NON_STANDARD(func)
141167 #define STACK_FRAME_NON_STANDARD_FP(func)
168+#define ANNOTATE_NOENDBR
169+#define ASM_REACHABLE
142170 #else
143171 #define ANNOTATE_INTRA_FUNCTION_CALL
144172 .macro UNWIND_HINT sp_reg:req sp_offset=0 type:req end=0
145173 .endm
146174 .macro STACK_FRAME_NON_STANDARD func:req
147175 .endm
176+.macro ANNOTATE_NOENDBR
177+.endm
178+.macro REACHABLE
179+.endm
148180 #endif
149181
150182 #endif /* CONFIG_STACK_VALIDATION */
tools/objtool/arch/x86/decode.c+29−5
@@ -103,6 +103,18 @@ unsigned long arch_jump_destination(struct instruction *insn) · 102 unmodified lines
103103 #define rm_is_mem(reg) (mod_is_mem() && !is_RIP() && rm_is(reg))
104104 #define rm_is_reg(reg) (mod_is_reg() && modrm_rm == (reg))
105105
106+static bool has_notrack_prefix(struct insn *insn)
107+{
108+ int i;
109+
110+ for (i = 0; i < insn->prefixes.nbytes; i++) {
111+ if (insn->prefixes.bytes[i] == 0x3e)
112+ return true;
113+ }
114+
115+ return false;
116+}
117+
106118 int arch_decode_instruction(struct objtool_file *file, const struct section *sec,
107119 unsigned long offset, unsigned int maxlen,
108120 unsigned int *len, enum insn_type *type,
@@ -112,7 +124,7 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec · 3 unmodified lines
112124 const struct elf *elf = file->elf;
113125 struct insn insn;
114126 int x86_64, ret;
115− unsigned char op1, op2, op3,
127+ unsigned char op1, op2, op3, prefix,
116128 rex = 0, rex_b = 0, rex_r = 0, rex_w = 0, rex_x = 0,
117129 modrm = 0, modrm_mod = 0, modrm_rm = 0, modrm_reg = 0,
118130 sib = 0, /* sib_scale = 0, */ sib_index = 0, sib_base = 0;
@@ -137,6 +149,8 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec · 18 unmodified lines
137149 if (insn.vex_prefix.nbytes)
138150 return 0;
139151
152+ prefix = insn.prefixes.bytes[0];
153+
140154 op1 = insn.opcode.bytes[0];
141155 op2 = insn.opcode.bytes[1];
142156 op3 = insn.opcode.bytes[2];
@@ -492,6 +506,12 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec · 349 unmodified lines
492506 /* nopl/nopw */
493507 *type = INSN_NOP;
494508
509+ } else if (op2 == 0x1e) {
510+
511+ if (prefix == 0xf3 && (modrm == 0xfa || modrm == 0xfb))
512+ *type = INSN_ENDBR;
513+
514+
495515 } else if (op2 == 0x38 && op3 == 0xf8) {
496516 if (insn.prefixes.nbytes == 1 &&
497517 insn.prefixes.bytes[0] == 0xf2) {
@@ -636,20 +656,24 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec · 138 unmodified lines
636656 break;
637657
638658 case 0xff:
639− if (modrm_reg == 2 || modrm_reg == 3)
659+ if (modrm_reg == 2 || modrm_reg == 3) {
640660
641661 *type = INSN_CALL_DYNAMIC;
662+ if (has_notrack_prefix(&insn))
663+ WARN("notrack prefix found at %s:0x%lx", sec->name, offset);
642664
643− else if (modrm_reg == 4)
665+ } else if (modrm_reg == 4) {
644666
645667 *type = INSN_JUMP_DYNAMIC;
668+ if (has_notrack_prefix(&insn))
669+ WARN("notrack prefix found at %s:0x%lx", sec->name, offset);
646670
647− else if (modrm_reg == 5)
671+ } else if (modrm_reg == 5) {
648672
649673 /* jmpf */
650674 *type = INSN_CONTEXT_SWITCH;
651675
652− else if (modrm_reg == 6) {
676+ } else if (modrm_reg == 6) {
653677
654678 /* push from mem */
655679 ADD_OP(op) {
tools/objtool/builtin-check.c+5−2
@@ -20,7 +20,8 @@ · 19 unmodified lines
2020 #include <objtool/objtool.h>
2121
2222 bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats,
23− validate_dup, vmlinux, mcount, noinstr, backup, sls;
23+ lto, vmlinux, mcount, noinstr, backup, sls, dryrun,
24+ ibt;
2425
2526 static const char * const check_usage[] = {
2627 "objtool check [<options>] file.o",
@@ -40,12 +41,14 @@ const struct option check_options[] = { · 13 unmodified lines
4041 OPT_BOOLEAN('b', "backtrace", &backtrace, "unwind on error"),
4142 OPT_BOOLEAN('a', "uaccess", &uaccess, "enable uaccess checking"),
4243 OPT_BOOLEAN('s', "stats", &stats, "print statistics"),
43− OPT_BOOLEAN('d', "duplicate", &validate_dup, "duplicate validation for vmlinux.o"),
44+ OPT_BOOLEAN(0, "lto", &lto, "whole-archive like runs"),
4445 OPT_BOOLEAN('n', "noinstr", &noinstr, "noinstr validation for vmlinux.o"),
4546 OPT_BOOLEAN('l', "vmlinux", &vmlinux, "vmlinux.o validation"),
4647 OPT_BOOLEAN('M', "mcount", &mcount, "generate __mcount_loc"),
4748 OPT_BOOLEAN('B', "backup", &backup, "create .orig files before modification"),
4849 OPT_BOOLEAN('S', "sls", &sls, "validate straight-line-speculation"),
50+ OPT_BOOLEAN(0, "dry-run", &dryrun, "don't write the modifications"),
51+ OPT_BOOLEAN(0, "ibt", &ibt, "validate ENDBR placement"),
4952 OPT_END(),
5053 };
5154
tools/objtool/check.c+376−24
@@ -181,6 +181,9 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func, · 180 unmodified lines
181181 "kunit_try_catch_throw",
182182 "xen_start_kernel",
183183 "cpu_bringup_and_idle",
184+ "do_group_exit",
185+ "stop_this_cpu",
186+ "__invalid_creds",
184187 };
185188
186189 if (!func)
@@ -380,6 +383,7 @@ static int decode_instructions(struct objtool_file *file) · 193 unmodified lines
380383 memset(insn, 0, sizeof(*insn));
381384 INIT_LIST_HEAD(&insn->alts);
382385 INIT_LIST_HEAD(&insn->stack_ops);
386+ INIT_LIST_HEAD(&insn->call_node);
383387
384388 insn->sec = sec;
385389 insn->offset = offset;
@@ -392,6 +396,14 @@ static int decode_instructions(struct objtool_file *file) · 6 unmodified lines
392396 if (ret)
393397 goto err;
394398
399+ /*
400+ * By default, "ud2" is a dead end unless otherwise
401+ * annotated, because GCC 7 inserts it for certain
402+ * divide-by-zero cases.
403+ */
404+ if (insn->type == INSN_BUG)
405+ insn->dead_end = true;
406+
395407 hash_add(file->insn_hash, &insn->hash, sec_offset_hash(sec, insn->offset));
396408 list_add_tail(&insn->list, &file->insn_list);
397409 nr_insns++;
@@ -407,8 +419,17 @@ static int decode_instructions(struct objtool_file *file) · 9 unmodified lines
407419 return -1;
408420 }
409421
410− sym_for_each_insn(file, func, insn)
422+ sym_for_each_insn(file, func, insn) {
411423 insn->func = func;
424+ if (insn->type == INSN_ENDBR && list_empty(&insn->call_node)) {
425+ if (insn->offset == insn->func->offset) {
426+ list_add_tail(&insn->call_node, &file->endbr_list);
427+ file->nr_endbr++;
428+ } else {
429+ file->nr_endbr_int++;
430+ }
431+ }
432+ }
412433 }
413434 }
414435
@@ -520,14 +541,6 @@ static int add_dead_ends(struct objtool_file *file) · 105 unmodified lines
520541 struct reloc *reloc;
521542 struct instruction *insn;
522543
523− /*
524− * By default, "ud2" is a dead end unless otherwise annotated, because
525− * GCC 7 inserts it for certain divide-by-zero cases.
526− */
527− for_each_insn(file, insn)
528− if (insn->type == INSN_BUG)
529− insn->dead_end = true;
530−
531544 /*
532545 * Check for manually annotated dead ends.
533546 */
@@ -731,6 +744,58 @@ static int create_retpoline_sites_sections(struct objtool_file *file) · 197 unmodified lines
731744 return 0;
732745 }
733746
747+static int create_ibt_endbr_seal_sections(struct objtool_file *file)
748+{
749+ struct instruction *insn;
750+ struct section *sec;
751+ int idx;
752+
753+ sec = find_section_by_name(file->elf, ".ibt_endbr_seal");
754+ if (sec) {
755+ WARN("file already has .ibt_endbr_seal, skipping");
756+ return 0;
757+ }
758+
759+ idx = 0;
760+ list_for_each_entry(insn, &file->endbr_list, call_node)
761+ idx++;
762+
763+ if (stats) {
764+ printf("ibt: ENDBR at function start: %d\n", file->nr_endbr);
765+ printf("ibt: ENDBR inside functions: %d\n", file->nr_endbr_int);
766+ printf("ibt: superfluous ENDBR: %d\n", idx);
767+ }
768+
769+ if (!idx)
770+ return 0;
771+
772+ sec = elf_create_section(file->elf, ".ibt_endbr_seal", 0,
773+ sizeof(int), idx);
774+ if (!sec) {
775+ WARN("elf_create_section: .ibt_endbr_seal");
776+ return -1;
777+ }
778+
779+ idx = 0;
780+ list_for_each_entry(insn, &file->endbr_list, call_node) {
781+
782+ int *site = (int *)sec->data->d_buf + idx;
783+ *site = 0;
784+
785+ if (elf_add_reloc_to_insn(file->elf, sec,
786+ idx * sizeof(int),
787+ R_X86_64_PC32,
788+ insn->sec, insn->offset)) {
789+ WARN("elf_add_reloc_to_insn: .ibt_endbr_seal");
790+ return -1;
791+ }
792+
793+ idx++;
794+ }
795+
796+ return 0;
797+}
798+
734799 static int create_mcount_loc_sections(struct objtool_file *file)
735800 {
736801 struct section *sec;
@@ -1111,6 +1176,9 @@ static void annotate_call_site(struct objtool_file *file, · 374 unmodified lines
11111176 list_add_tail(&insn->call_node, &file->mcount_loc_list);
11121177 return;
11131178 }
1179+
1180+ if (!sibling && dead_end_function(file, sym))
1181+ insn->dead_end = true;
11141182 }
11151183
11161184 static void add_call_dest(struct objtool_file *file, struct instruction *insn,
@@ -1165,6 +1233,19 @@ static void add_retpoline_call(struct objtool_file *file, struct instruction *in · 48 unmodified lines
11651233
11661234 annotate_call_site(file, insn, false);
11671235 }
1236+
1237+static bool same_function(struct instruction *insn1, struct instruction *insn2)
1238+{
1239+ return insn1->func->pfunc == insn2->func->pfunc;
1240+}
1241+
1242+static bool is_first_func_insn(struct instruction *insn)
1243+{
1244+ return insn->offset == insn->func->offset ||
1245+ (insn->type == INSN_ENDBR &&
1246+ insn->offset == insn->func->offset + insn->len);
1247+}
1248+
11681249 /*
11691250 * Find the destination instructions for all jumps.
11701251 */
@@ -1245,8 +1326,8 @@ static int add_jump_destinations(struct objtool_file *file) · 74 unmodified lines
12451326 insn->func->cfunc = insn->jump_dest->func;
12461327 insn->jump_dest->func->pfunc = insn->func;
12471328
1248− } else if (insn->jump_dest->func->pfunc != insn->func->pfunc &&
1249− insn->jump_dest->offset == insn->jump_dest->func->offset) {
1329+ } else if (!same_function(insn, insn->jump_dest) &&
1330+ is_first_func_insn(insn->jump_dest)) {
12501331 /* internal sibling call (without reloc) */
12511332 add_call_dest(file, insn, insn->jump_dest->func, true);
12521333 }
@@ -1836,6 +1917,16 @@ static int read_unwind_hints(struct objtool_file *file) · 583 unmodified lines
18361917
18371918 insn->hint = true;
18381919
1920+ if (ibt && hint->type == UNWIND_HINT_TYPE_REGS_PARTIAL) {
1921+ struct symbol *sym = find_symbol_by_offset(insn->sec, insn->offset);
1922+
1923+ if (sym && sym->bind == STB_GLOBAL &&
1924+ insn->type != INSN_ENDBR && !insn->noendbr) {
1925+ WARN_FUNC("UNWIND_HINT_IRET_REGS without ENDBR",
1926+ insn->sec, insn->offset);
1927+ }
1928+ }
1929+
18391930 if (hint->type == UNWIND_HINT_TYPE_FUNC) {
18401931 insn->cfi = &func_cfi;
18411932 continue;
@@ -1860,6 +1951,32 @@ static int read_unwind_hints(struct objtool_file *file) · 18 unmodified lines
18601951 return 0;
18611952 }
18621953
1954+static int read_noendbr_hints(struct objtool_file *file)
1955+{
1956+ struct section *sec;
1957+ struct instruction *insn;
1958+ struct reloc *reloc;
1959+
1960+ sec = find_section_by_name(file->elf, ".rela.discard.noendbr");
1961+ if (!sec)
1962+ return 0;
1963+
1964+ list_for_each_entry(reloc, &sec->reloc_list, list) {
1965+ insn = find_insn(file, reloc->sym->sec, reloc->sym->offset + reloc->addend);
1966+ if (!insn) {
1967+ WARN("bad .discard.noendbr entry");
1968+ return -1;
1969+ }
1970+
1971+ if (insn->type == INSN_ENDBR)
1972+ WARN_FUNC("ANNOTATE_NOENDBR on ENDBR", insn->sec, insn->offset);
1973+
1974+ insn->noendbr = 1;
1975+ }
1976+
1977+ return 0;
1978+}
1979+
18631980 static int read_retpoline_hints(struct objtool_file *file)
18641981 {
18651982 struct section *sec;
@@ -2086,10 +2203,6 @@ static int decode_sections(struct objtool_file *file) · 220 unmodified lines
20862203 if (ret)
20872204 return ret;
20882205
2089− ret = add_dead_ends(file);
2090− if (ret)
2091− return ret;
2092−
20932206 add_ignores(file);
20942207 add_uaccess_safe(file);
20952208
@@ -2097,6 +2210,13 @@ static int decode_sections(struct objtool_file *file) · 1 unmodified line
20972210 if (ret)
20982211 return ret;
20992212
2213+ /*
2214+ * Must be before read_unwind_hints() since that needs insn->noendbr.
2215+ */
2216+ ret = read_noendbr_hints(file);
2217+ if (ret)
2218+ return ret;
2219+
21002220 /*
21012221 * Must be before add_{jump_call}_destination.
21022222 */
@@ -2128,6 +2248,14 @@ static int decode_sections(struct objtool_file *file) · 25 unmodified lines
21282248 if (ret)
21292249 return ret;
21302250
2251+ /*
2252+ * Must be after add_call_destinations() such that it can override
2253+ * dead_end_function() marks.
2254+ */
2255+ ret = add_dead_ends(file);
2256+ if (ret)
2257+ return ret;
2258+
21312259 ret = add_jump_table_alts(file);
21322260 if (ret)
21332261 return ret;
@@ -3026,6 +3154,115 @@ static struct instruction *next_insn_to_validate(struct objtool_file *file, · 892 unmodified lines
30263154 return next_insn_same_sec(file, insn);
30273155 }
30283156
3157+static struct instruction *
3158+validate_ibt_reloc(struct objtool_file *file, struct reloc *reloc)
3159+{
3160+ struct instruction *dest;
3161+ struct section *sec;
3162+ unsigned long off;
3163+
3164+ sec = reloc->sym->sec;
3165+ off = reloc->sym->offset;
3166+
3167+ if ((reloc->sec->base->sh.sh_flags & SHF_EXECINSTR) &&
3168+ (reloc->type == R_X86_64_PC32 || reloc->type == R_X86_64_PLT32))
3169+ off += arch_dest_reloc_offset(reloc->addend);
3170+ else
3171+ off += reloc->addend;
3172+
3173+ dest = find_insn(file, sec, off);
3174+ if (!dest)
3175+ return NULL;
3176+
3177+ if (dest->type == INSN_ENDBR) {
3178+ if (!list_empty(&dest->call_node))
3179+ list_del_init(&dest->call_node);
3180+
3181+ return NULL;
3182+ }
3183+
3184+ if (reloc->sym->static_call_tramp)
3185+ return NULL;
3186+
3187+ return dest;
3188+}
3189+
3190+static void warn_noendbr(const char *msg, struct section *sec, unsigned long offset,
3191+ struct instruction *dest)
3192+{
3193+ WARN_FUNC("%srelocation to !ENDBR: %s+0x%lx", sec, offset, msg,
3194+ dest->func ? dest->func->name : dest->sec->name,
3195+ dest->func ? dest->offset - dest->func->offset : dest->offset);
3196+}
3197+
3198+static void validate_ibt_dest(struct objtool_file *file, struct instruction *insn,
3199+ struct instruction *dest)
3200+{
3201+ if (dest->func && dest->func == insn->func) {
3202+ /*
3203+ * Anything from->to self is either _THIS_IP_ or IRET-to-self.
3204+ *
3205+ * There is no sane way to annotate _THIS_IP_ since the compiler treats the
3206+ * relocation as a constant and is happy to fold in offsets, skewing any
3207+ * annotation we do, leading to vast amounts of false-positives.
3208+ *
3209+ * There's also compiler generated _THIS_IP_ through KCOV and
3210+ * such which we have no hope of annotating.
3211+ *
3212+ * As such, blanket accept self-references without issue.
3213+ */
3214+ return;
3215+ }
3216+
3217+ if (dest->noendbr)
3218+ return;
3219+
3220+ warn_noendbr("", insn->sec, insn->offset, dest);
3221+}
3222+
3223+static void validate_ibt_insn(struct objtool_file *file, struct instruction *insn)
3224+{
3225+ struct instruction *dest;
3226+ struct reloc *reloc;
3227+
3228+ switch (insn->type) {
3229+ case INSN_CALL:
3230+ case INSN_CALL_DYNAMIC:
3231+ case INSN_JUMP_CONDITIONAL:
3232+ case INSN_JUMP_UNCONDITIONAL:
3233+ case INSN_JUMP_DYNAMIC:
3234+ case INSN_JUMP_DYNAMIC_CONDITIONAL:
3235+ case INSN_RETURN:
3236+ /*
3237+ * We're looking for code references setting up indirect code
3238+ * flow. As such, ignore direct code flow and the actual
3239+ * dynamic branches.
3240+ */
3241+ return;
3242+
3243+ case INSN_NOP:
3244+ /*
3245+ * handle_group_alt() will create INSN_NOP instruction that
3246+ * don't belong to any section, ignore all NOP since they won't
3247+ * carry a (useful) relocation anyway.
3248+ */
3249+ return;
3250+
3251+ default:
3252+ break;
3253+ }
3254+
3255+ for (reloc = insn_reloc(file, insn);
3256+ reloc;
3257+ reloc = find_reloc_by_dest_range(file->elf, insn->sec,
3258+ reloc->offset + 1,
3259+ (insn->offset + insn->len) - (reloc->offset + 1))) {
3260+ dest = validate_ibt_reloc(file, reloc);
3261+ if (dest)
3262+ validate_ibt_dest(file, insn, dest);
3263+ }
3264+}
3265+
30293266 /*
30303267 * Follow the branch starting at the given instruction, and recursively follow
30313268 * any other branches (jumps). Meanwhile, track the frame pointer state at
@@ -3115,9 +3352,8 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, · 83 unmodified lines
31153352 switch (insn->type) {
31163353
31173354 case INSN_RETURN:
3118− if (next_insn && next_insn->type == INSN_TRAP) {
3119− next_insn->ignore = true;
3120− } else if (sls && !insn->retpoline_safe) {
3355+ if (sls && !insn->retpoline_safe &&
3356+ next_insn && next_insn->type != INSN_TRAP) {
31213357 WARN_FUNC("missing int3 after ret",
31223358 insn->sec, insn->offset);
31233359 }
@@ -3136,7 +3372,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, · 12 unmodified lines
31363372 return 1;
31373373 }
31383374
3139− if (dead_end_function(file, insn->call_dest))
3375+ if (insn->dead_end)
31403376 return 0;
31413377
31423378 break;
@@ -3164,9 +3400,8 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, · 21 unmodified lines
31643400 break;
31653401
31663402 case INSN_JUMP_DYNAMIC:
3167− if (next_insn && next_insn->type == INSN_TRAP) {
3168− next_insn->ignore = true;
3169− } else if (sls && !insn->retpoline_safe) {
3403+ if (sls && !insn->retpoline_safe &&
3404+ next_insn && next_insn->type != INSN_TRAP) {
31703405 WARN_FUNC("missing int3 after indirect jump",
31713406 insn->sec, insn->offset);
31723407 }
@@ -3237,6 +3472,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, · 64 unmodified lines
32373472 break;
32383473 }
32393474
3475+ if (ibt)
3476+ validate_ibt_insn(file, insn);
3477+
32403478 if (insn->dead_end)
32413479 return 0;
32423480
@@ -3337,7 +3575,7 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio · 94 unmodified lines
33373575 int i;
33383576 struct instruction *prev_insn;
33393577
3340− if (insn->ignore || insn->type == INSN_NOP)
3578+ if (insn->ignore || insn->type == INSN_NOP || insn->type == INSN_TRAP)
33413579 return true;
33423580
33433581 /*
@@ -3348,6 +3586,49 @@ static bool ignore_unreachable_insn(struct objtool_file *file, struct instructio · 4 unmodified lines
33483586 !strcmp(insn->sec->name, ".altinstr_aux"))
33493587 return true;
33503588
3589+ /*
3590+ * Whole archive runs might encounder dead code from weak symbols.
3591+ * This is where the linker will have dropped the weak symbol in
3592+ * favour of a regular symbol, but leaves the code in place.
3593+ *
3594+ * In this case we'll find a piece of code (whole function) that is not
3595+ * covered by a !section symbol. Ignore them.
3596+ */
3597+ if (!insn->func && lto) {
3598+ int size = find_symbol_hole_containing(insn->sec, insn->offset);
3599+ unsigned long end = insn->offset + size;
3600+
3601+ if (!size) /* not a hole */
3602+ return false;
3603+
3604+ if (size < 0) /* hole until the end */
3605+ return true;
3606+
3607+ sec_for_each_insn_continue(file, insn) {
3608+ /*
3609+ * If we reach a visited instruction at or before the
3610+ * end of the hole, ignore the unreachable.
3611+ */
3612+ if (insn->visited)
3613+ return true;
3614+
3615+ if (insn->offset >= end)
3616+ break;
3617+
3618+ /*
3619+ * If this hole jumps to a .cold function, mark it ignore too.
3620+ */
3621+ if (insn->jump_dest && insn->jump_dest->func &&
3622+ strstr(insn->jump_dest->func->name, ".cold")) {
3623+ struct instruction *dest = insn->jump_dest;
3624+ func_for_each_insn(file, dest->func, dest)
3625+ dest->ignore = true;
3626+ }
3627+ }
3628+
3629+ return false;
3630+ }
3631+
33513632 if (!insn->func)
33523633 return false;
33533634
@@ -3479,6 +3760,53 @@ static int validate_functions(struct objtool_file *file) · 125 unmodified lines
34793760 return warnings;
34803761 }
34813762
3763+static int validate_ibt(struct objtool_file *file)
3764+{
3765+ struct section *sec;
3766+ struct reloc *reloc;
3767+
3768+ for_each_sec(file, sec) {
3769+ bool is_data;
3770+
3771+ /* already done in validate_branch() */
3772+ if (sec->sh.sh_flags & SHF_EXECINSTR)
3773+ continue;
3774+
3775+ if (!sec->reloc)
3776+ continue;
3777+
3778+ if (!strncmp(sec->name, ".orc", 4))
3779+ continue;
3780+
3781+ if (!strncmp(sec->name, ".discard", 8))
3782+ continue;
3783+
3784+ if (!strncmp(sec->name, ".debug", 6))
3785+ continue;
3786+
3787+ if (!strcmp(sec->name, "_error_injection_whitelist"))
3788+ continue;
3789+
3790+ if (!strcmp(sec->name, "_kprobe_blacklist"))
3791+ continue;
3792+
3793+ is_data = strstr(sec->name, ".data") || strstr(sec->name, ".rodata");
3794+
3795+ list_for_each_entry(reloc, &sec->reloc->reloc_list, list) {
3796+ struct instruction *dest;
3797+
3798+ dest = validate_ibt_reloc(file, reloc);
3799+ if (is_data && dest && !dest->noendbr) {
3800+ warn_noendbr("data ", reloc->sym->sec,
3801+ reloc->sym->offset + reloc->addend,
3802+ dest);
3803+ }
3804+ }
3805+ }
3806+
3807+ return 0;
3808+}
3809+
34823810 static int validate_reachable_instructions(struct objtool_file *file)
34833811 {
34843812 struct instruction *insn;
@@ -3501,6 +3829,16 @@ int check(struct objtool_file *file) · 16 unmodified lines
35013829 {
35023830 int ret, warnings = 0;
35033831
3832+ if (lto && !(vmlinux || module)) {
3833+ fprintf(stderr, "--lto requires: --vmlinux or --module\n");
3834+ return 1;
3835+ }
3836+
3837+ if (ibt && !lto) {
3838+ fprintf(stderr, "--ibt requires: --lto\n");
3839+ return 1;
3840+ }
3841+
35043842 arch_initial_func_cfi_state(&initial_func_cfi);
35053843 init_cfi_state(&init_cfi);
35063844 init_cfi_state(&func_cfi);
@@ -3521,7 +3859,7 @@ int check(struct objtool_file *file) · 14 unmodified lines
35213859 if (list_empty(&file->insn_list))
35223860 goto out;
35233861
3524− if (vmlinux && !validate_dup) {
3862+ if (vmlinux && !lto) {
35253863 ret = validate_vmlinux_functions(file);
35263864 if (ret < 0)
35273865 goto out;
@@ -3547,6 +3885,13 @@ int check(struct objtool_file *file) · 19 unmodified lines
35473885 goto out;
35483886 warnings += ret;
35493887
3888+ if (ibt) {
3889+ ret = validate_ibt(file);
3890+ if (ret < 0)
3891+ goto out;
3892+ warnings += ret;
3893+ }
3894+
35503895 if (!warnings) {
35513896 ret = validate_reachable_instructions(file);
35523897 if (ret < 0)
@@ -3573,6 +3918,13 @@ int check(struct objtool_file *file) · 20 unmodified lines
35733918 warnings += ret;
35743919 }
35753920
3921+ if (ibt) {
3922+ ret = create_ibt_endbr_seal_sections(file);
3923+ if (ret < 0)
3924+ goto out;
3925+ warnings += ret;
3926+ }
3927+
35763928 if (stats) {
35773929 printf("nr_insns_visited: %ld\n", nr_insns_visited);
35783930 printf("nr_cfi: %ld\n", nr_cfi);
tools/objtool/elf.c+63−0
@@ -83,6 +83,31 @@ static int symbol_by_offset(const void *key, const struct rb_node *node) · 82 unmodified lines
8383 return 0;
8484 }
8585
86+struct symbol_hole {
87+ unsigned long key;
88+ const struct symbol *sym;
89+};
90+
91+/*
92+ * Find !section symbol where @offset is after it.
93+ */
94+static int symbol_hole_by_offset(const void *key, const struct rb_node *node)
95+{
96+ const struct symbol *s = rb_entry(node, struct symbol, node);
97+ struct symbol_hole *sh = (void *)key;
98+
99+ if (sh->key < s->offset)
100+ return -1;
101+
102+ if (sh->key >= s->offset + s->len) {
103+ if (s->type != STT_SECTION)
104+ sh->sym = s;
105+ return 1;
106+ }
107+
108+ return 0;
109+}
110+
86111 struct section *find_section_by_name(const struct elf *elf, const char *name)
87112 {
88113 struct section *sec;
@@ -162,6 +187,41 @@ struct symbol *find_symbol_containing(const struct section *sec, unsigned long o · 73 unmodified lines
162187 return NULL;
163188 }
164189
190+/*
191+ * Returns size of hole starting at @offset.
192+ */
193+int find_symbol_hole_containing(const struct section *sec, unsigned long offset)
194+{
195+ struct symbol_hole hole = {
196+ .key = offset,
197+ .sym = NULL,
198+ };
199+ struct rb_node *n;
200+ struct symbol *s;
201+
202+ /*
203+ * Find the rightmost symbol for which @offset is after it.
204+ */
205+ n = rb_find(&hole, &sec->symbol_tree, symbol_hole_by_offset);
206+
207+ /* found a symbol that contains @offset */
208+ if (n)
209+ return 0; /* not a hole */
210+
211+ /* didn't find a symbol for which @offset is after it */
212+ if (!hole.sym)
213+ return 0; /* not a hole */
214+
215+ /* @offset >= sym->offset + sym->len, find symbol after it */
216+ n = rb_next(&hole.sym->node);
217+ if (!n)
218+ return -1; /* until end of address space */
219+
220+ /* hole until start of next symbol */
221+ s = rb_entry(n, struct symbol, node);
222+ return s->offset - offset;
223+}
224+
165225 struct symbol *find_func_containing(struct section *sec, unsigned long offset)
166226 {
167227 struct rb_node *node;
@@ -1019,6 +1079,9 @@ int elf_write(struct elf *elf) · 851 unmodified lines
10191079 struct section *sec;
10201080 Elf_Scn *s;
10211081
1082+ if (dryrun)
1083+ return 0;
1084+
10221085 /* Update changed relocation sections and section headers: */
10231086 list_for_each_entry(sec, &elf->sections, list) {
10241087 if (sec->changed) {
tools/objtool/include/objtool/arch.h+1−0
@@ -27,6 +27,7 @@ enum insn_type { · 26 unmodified lines
2727 INSN_STD,
2828 INSN_CLD,
2929 INSN_TRAP,
30+ INSN_ENDBR,
3031 INSN_OTHER,
3132 };
3233
tools/objtool/include/objtool/builtin.h+2−1
@@ -9,7 +9,8 @@ · 8 unmodified lines
99
1010 extern const struct option check_options[];
1111 extern bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats,
12− validate_dup, vmlinux, mcount, noinstr, backup, sls;
12+ lto, vmlinux, mcount, noinstr, backup, sls, dryrun,
13+ ibt;
1314
1415 extern int cmd_parse_options(int argc, const char **argv, const char * const usage[]);
1516
tools/objtool/include/objtool/check.h+10−3
@@ -45,11 +45,18 @@ struct instruction { · 44 unmodified lines
4545 unsigned int len;
4646 enum insn_type type;
4747 unsigned long immediate;
48− bool dead_end, ignore, ignore_alts;
49− bool hint;
50− bool retpoline_safe;
48+
49+ u8 dead_end : 1,
50+ ignore : 1,
51+ ignore_alts : 1,
52+ hint : 1,
53+ retpoline_safe : 1,
54+ noendbr : 1;
55+ /* 2 bit hole */
5156 s8 instr;
5257 u8 visited;
58+ /* u8 hole */
59+
5360 struct alt_group *alt_group;
5461 struct symbol *call_dest;
5562 struct instruction *jump_dest;
tools/objtool/include/objtool/elf.h+1−0
@@ -152,6 +152,7 @@ struct symbol *find_func_by_offset(struct section *sec, unsigned long offset); · 151 unmodified lines
152152 struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
153153 struct symbol *find_symbol_by_name(const struct elf *elf, const char *name);
154154 struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset);
155+int find_symbol_hole_containing(const struct section *sec, unsigned long offset);
155156 struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset);
156157 struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
157158 unsigned long offset, unsigned int len);
tools/objtool/include/objtool/objtool.h+4−0
@@ -26,8 +26,12 @@ struct objtool_file { · 25 unmodified lines
2626 struct list_head retpoline_call_list;
2727 struct list_head static_call_list;
2828 struct list_head mcount_loc_list;
29+ struct list_head endbr_list;
2930 bool ignore_unreachables, c_file, hints, rodata;
3031
32+ unsigned int nr_endbr;
33+ unsigned int nr_endbr_int;
34+
3135 unsigned long jl_short, jl_long;
3236 unsigned long jl_nop_short, jl_nop_long;
3337
tools/objtool/include/objtool/warn.h+2−0
@@ -22,6 +22,8 @@ static inline char *offstr(struct section *sec, unsigned long offset) · 21 unmodified lines
2222 unsigned long name_off;
2323
2424 func = find_func_containing(sec, offset);
25+ if (!func)
26+ func = find_symbol_containing(sec, offset);
2527 if (func) {
2628 name = func->name;
2729 name_off = offset - func->offset;
tools/objtool/objtool.c+1−0
@@ -128,6 +128,7 @@ struct objtool_file *objtool_open_read(const char *_objname) · 127 unmodified lines
128128 INIT_LIST_HEAD(&file.retpoline_call_list);
129129 INIT_LIST_HEAD(&file.static_call_list);
130130 INIT_LIST_HEAD(&file.mcount_loc_list);
131+ INIT_LIST_HEAD(&file.endbr_list);
131132 file.c_file = !vmlinux && find_section_by_name(file.elf, ".comment");
132133 file.ignore_unreachables = no_unreachable;
133134 file.hints = false;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t