From 5f3da8c08508df82823566c32f753071c8ad36af Mon Sep 17 00:00:00 2001 From: Josh Poimboeuf Date: Tue, 19 Apr 2022 09:05:09 -0700 Subject: objtool: Add CONFIG_HAVE_UACCESS_VALIDATION Allow an arch specify that it has objtool uaccess validation with CONFIG_HAVE_UACCESS_VALIDATION. For now, doing so unconditionally selects CONFIG_OBJTOOL. Signed-off-by: Josh Poimboeuf Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/d393d5e2fe73aec6e8e41d5c24f4b6fe8583f2d8.1650384225.git.jpoimboe@redhat.com --- arch/Kconfig | 4 ++++ arch/x86/Kconfig | 1 + scripts/Makefile.build | 2 +- scripts/link-vmlinux.sh | 4 +++- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 904ed51736d4..cb2954027d10 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1050,6 +1050,10 @@ config HAVE_NOINSTR_HACK config HAVE_NOINSTR_VALIDATION bool +config HAVE_UACCESS_VALIDATION + bool + select OBJTOOL + config HAVE_STACK_VALIDATION bool help diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index cf531fbcd229..5f41f3c3df9a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -258,6 +258,7 @@ config X86 select HAVE_PREEMPT_DYNAMIC_CALL select HAVE_RSEQ select HAVE_SYSCALL_TRACEPOINTS + select HAVE_UACCESS_VALIDATION if HAVE_OBJTOOL select HAVE_UNSTABLE_SCHED_CLOCK select HAVE_USER_RETURN_NOTIFIER select HAVE_GENERIC_VDSO diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 06400504150b..6a663b27b286 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -218,7 +218,7 @@ objtool_args = \ $(if $(CONFIG_SLS), --sls) \ $(if $(CONFIG_STACK_VALIDATION), --stackval) \ $(if $(CONFIG_HAVE_STATIC_CALL_INLINE), --static-call) \ - --uaccess \ + $(if $(CONFIG_HAVE_UACCESS_VALIDATION), --uaccess) \ $(if $(linked-object), --link) \ $(if $(part-of-module), --module) \ $(if $(CONFIG_GCOV_KERNEL), --no-unreachable) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index a7f6196c7e41..fd578c380919 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -134,7 +134,9 @@ objtool_link() objtoolopt="${objtoolopt} --static-call" fi - objtoolopt="${objtoolopt} --uaccess" + if is_enabled CONFIG_HAVE_UACCESS_VALIDATION; then + objtoolopt="${objtoolopt} --uaccess" + fi fi if is_enabled CONFIG_NOINSTR_VALIDATION; then -- cgit v1.2.3 From 385bd430c011a8cb8278e61c32d602d11e06f414 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 2 May 2022 11:15:14 +0200 Subject: objtool: Mark __ubsan_handle_builtin_unreachable() as noreturn fs/ntfs3/ntfs3.prelink.o: warning: objtool: ni_read_frame() falls through to next function ni_readpage_cmpr.cold() That is in fact: 000000000000124a : 124a: 44 89 e0 mov %r12d,%eax 124d: 0f b6 55 98 movzbl -0x68(%rbp),%edx 1251: 48 c7 c7 00 00 00 00 mov $0x0,%rdi 1254: R_X86_64_32S .data+0x1380 1258: 48 89 c6 mov %rax,%rsi 125b: e8 00 00 00 00 call 1260 125c: R_X86_64_PLT32 __ubsan_handle_shift_out_of_bounds-0x4 1260: 48 8d 7d cc lea -0x34(%rbp),%rdi 1264: e8 00 00 00 00 call 1269 1265: R_X86_64_PLT32 __tsan_read4-0x4 1269: 8b 45 cc mov -0x34(%rbp),%eax 126c: e9 00 00 00 00 jmp 1271 126d: R_X86_64_PC32 .text+0x19109 1271: 48 8b 75 a0 mov -0x60(%rbp),%rsi 1275: 48 63 d0 movslq %eax,%rdx 1278: 48 c7 c7 00 00 00 00 mov $0x0,%rdi 127b: R_X86_64_32S .data+0x13a0 127f: 89 45 88 mov %eax,-0x78(%rbp) 1282: e8 00 00 00 00 call 1287 1283: R_X86_64_PLT32 __ubsan_handle_shift_out_of_bounds-0x4 1287: 8b 45 88 mov -0x78(%rbp),%eax 128a: e9 00 00 00 00 jmp 128f 128b: R_X86_64_PC32 .text+0x19098 128f: 48 c7 c7 00 00 00 00 mov $0x0,%rdi 1292: R_X86_64_32S .data+0x11f0 1296: e8 00 00 00 00 call 129b 1297: R_X86_64_PLT32 __ubsan_handle_builtin_unreachable-0x4 000000000000129b : Tell objtool that __ubsan_handle_builtin_unreachable() is a noreturn. Reported-by: kernel test robot Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20220502091514.GB479834@worktop.programming.kicks-ass.net --- tools/objtool/check.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 190b2f6e360a..7a187dae2fcf 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -185,7 +185,8 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func, "do_group_exit", "stop_this_cpu", "__invalid_creds", - "cpu_startup_entry", + "cpu_startup_entry", + "__ubsan_handle_builtin_unreachable", }; if (!func) -- cgit v1.2.3 From a6a5eb269f6f3a2fe392f725a8d9052190c731e2 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 2 May 2022 12:15:23 +0200 Subject: x86/cpu: Elide KCSAN for cpu_has() and friends As x86 uses the headers, the regular forms of all bitops are instrumented with explicit calls to KASAN and KCSAN checks. As these are explicit calls, these are not suppressed by the noinstr function attribute. This can result in calls to those check functions in noinstr code, which objtool warns about: vmlinux.o: warning: objtool: enter_from_user_mode+0x24: call to __kcsan_check_access() leaves .noinstr.text section vmlinux.o: warning: objtool: syscall_enter_from_user_mode+0x28: call to __kcsan_check_access() leaves .noinstr.text section vmlinux.o: warning: objtool: syscall_enter_from_user_mode_prepare+0x24: call to __kcsan_check_access() leaves .noinstr.text section vmlinux.o: warning: objtool: irqentry_enter_from_user_mode+0x24: call to __kcsan_check_access() leaves .noinstr.text section Prevent this by using the arch_*() bitops, which are the underlying bitops without explciit instrumentation. [null: Changelog] Reported-by: kernel test robot Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20220502111216.290518605@infradead.org --- arch/x86/include/asm/cpufeature.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 66d3e3b1d24d..ea34cc31b047 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -54,7 +54,7 @@ extern const char * const x86_power_flags[32]; extern const char * const x86_bug_flags[NBUGINTS*32]; #define test_cpu_cap(c, bit) \ - test_bit(bit, (unsigned long *)((c)->x86_capability)) + arch_test_bit(bit, (unsigned long *)((c)->x86_capability)) /* * There are 32 bits/features in each mask word. The high bits -- cgit v1.2.3 From 656d054e0a15ec327bd82801ccd58201e59f6896 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 2 May 2022 12:30:20 +0200 Subject: jump_label,noinstr: Avoid instrumentation for JUMP_LABEL=n builds When building x86_64 with JUMP_LABEL=n it's possible for instrumentation to sneak into noinstr: vmlinux.o: warning: objtool: exit_to_user_mode+0x14: call to static_key_count.constprop.0() leaves .noinstr.text section vmlinux.o: warning: objtool: syscall_exit_to_user_mode+0x2d: call to static_key_count.constprop.0() leaves .noinstr.text section vmlinux.o: warning: objtool: irqentry_exit_to_user_mode+0x1b: call to static_key_count.constprop.0() leaves .noinstr.text section Switch to arch_ prefixed atomic to avoid the explicit instrumentation. Reported-by: kernel test robot Signed-off-by: Peter Zijlstra (Intel) --- include/linux/jump_label.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h index 107751cc047b..bf1eef337a07 100644 --- a/include/linux/jump_label.h +++ b/include/linux/jump_label.h @@ -256,9 +256,9 @@ extern void static_key_disable_cpuslocked(struct static_key *key); #include #include -static inline int static_key_count(struct static_key *key) +static __always_inline int static_key_count(struct static_key *key) { - return atomic_read(&key->enabled); + return arch_atomic_read(&key->enabled); } static __always_inline void jump_label_init(void) -- cgit v1.2.3 From 1894a4030582472336c2873cb07911ce67e0d14e Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 7 May 2022 13:37:45 +0200 Subject: x86: Always inline on_thread_stack() and current_top_of_stack() Becaues GCC clearly lost it's marbles again... vmlinux.o: warning: objtool: enter_from_user_mode+0x4e: call to on_thread_stack() leaves .noinstr.text section vmlinux.o: warning: objtool: syscall_enter_from_user_mode+0x53: call to on_thread_stack() leaves .noinstr.text section vmlinux.o: warning: objtool: syscall_enter_from_user_mode_prepare+0x4e: call to on_thread_stack() leaves .noinstr.text section vmlinux.o: warning: objtool: irqentry_enter_from_user_mode+0x4e: call to on_thread_stack() leaves .noinstr.text section vmlinux.o: warning: objtool: enter_from_user_mode+0x4e: call to current_top_of_stack() leaves .noinstr.text section vmlinux.o: warning: objtool: syscall_enter_from_user_mode+0x53: call to current_top_of_stack() leaves .noinstr.text section vmlinux.o: warning: objtool: syscall_enter_from_user_mode_prepare+0x4e: call to current_top_of_stack() leaves .noinstr.text section vmlinux.o: warning: objtool: irqentry_enter_from_user_mode+0x4e: call to current_top_of_stack() leaves .noinstr.text section Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20220526105958.071435483@infradead.org --- arch/x86/include/asm/processor.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 91d0f93a00c7..356308c73951 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -559,7 +559,7 @@ static __always_inline void native_swapgs(void) #endif } -static inline unsigned long current_top_of_stack(void) +static __always_inline unsigned long current_top_of_stack(void) { /* * We can't read directly from tss.sp0: sp0 on x86_32 is special in @@ -569,7 +569,7 @@ static inline unsigned long current_top_of_stack(void) return this_cpu_read_stable(cpu_current_top_of_stack); } -static inline bool on_thread_stack(void) +static __always_inline bool on_thread_stack(void) { return (unsigned long)(current_top_of_stack() - current_stack_pointer) < THREAD_SIZE; -- cgit v1.2.3 From 620f8d3bd3d5e82dff8cc591c831827d4beeae2e Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 7 May 2022 13:35:37 +0200 Subject: context_tracking: Always inline empty stubs Because GCC is seriously challenged.. vmlinux.o: warning: objtool: enter_from_user_mode+0x85: call to context_tracking_enabled() leaves .noinstr.text section vmlinux.o: warning: objtool: syscall_enter_from_user_mode+0x8f: call to context_tracking_enabled() leaves .noinstr.text section vmlinux.o: warning: objtool: syscall_enter_from_user_mode_prepare+0x85: call to context_tracking_enabled() leaves .noinstr.text section vmlinux.o: warning: objtool: irqentry_enter_from_user_mode+0x85: call to context_tracking_enabled() leaves .noinstr.text section Signed-off-by: Peter Zijlstra (Intel) Acked-by: Mark Rutland Link: https://lkml.kernel.org/r/20220526105958.134113388@infradead.org --- include/linux/context_tracking_state.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/context_tracking_state.h b/include/linux/context_tracking_state.h index 65a60d3313b0..ae1e63e26947 100644 --- a/include/linux/context_tracking_state.h +++ b/include/linux/context_tracking_state.h @@ -46,10 +46,10 @@ static __always_inline bool context_tracking_in_user(void) return __this_cpu_read(context_tracking.state) == CONTEXT_USER; } #else -static inline bool context_tracking_in_user(void) { return false; } -static inline bool context_tracking_enabled(void) { return false; } -static inline bool context_tracking_enabled_cpu(int cpu) { return false; } -static inline bool context_tracking_enabled_this_cpu(void) { return false; } +static __always_inline bool context_tracking_in_user(void) { return false; } +static __always_inline bool context_tracking_enabled(void) { return false; } +static __always_inline bool context_tracking_enabled_cpu(int cpu) { return false; } +static __always_inline bool context_tracking_enabled_this_cpu(void) { return false; } #endif /* CONFIG_CONTEXT_TRACKING */ #endif -- cgit v1.2.3 From 2028a255f4df3af9e759f01f958d3237f825f256 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Fri, 20 May 2022 21:27:29 +0200 Subject: x86/extable: Annotate ex_handler_msr_mce() as a dead end Fix vmlinux.o: warning: objtool: fixup_exception+0x2d6: unreachable instruction Signed-off-by: Borislav Petkov Signed-off-by: Peter Zijlstra (Intel) Link: https://lkml.kernel.org/r/20220520192729.23969-1-bp@alien8.de --- arch/x86/include/asm/extable.h | 8 ++++++-- tools/objtool/check.c | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/extable.h b/arch/x86/include/asm/extable.h index 155c991ba95e..eeed395c3177 100644 --- a/arch/x86/include/asm/extable.h +++ b/arch/x86/include/asm/extable.h @@ -42,9 +42,13 @@ extern int ex_get_fixup_type(unsigned long ip); extern void early_fixup_exception(struct pt_regs *regs, int trapnr); #ifdef CONFIG_X86_MCE -extern void ex_handler_msr_mce(struct pt_regs *regs, bool wrmsr); +extern void __noreturn ex_handler_msr_mce(struct pt_regs *regs, bool wrmsr); #else -static inline void ex_handler_msr_mce(struct pt_regs *regs, bool wrmsr) { } +static inline void __noreturn ex_handler_msr_mce(struct pt_regs *regs, bool wrmsr) +{ + for (;;) + cpu_relax(); +} #endif #if defined(CONFIG_BPF_JIT) && defined(CONFIG_X86_64) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 7a187dae2fcf..864bb9dd3584 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -187,6 +187,7 @@ static bool __dead_end_function(struct objtool_file *file, struct symbol *func, "__invalid_creds", "cpu_startup_entry", "__ubsan_handle_builtin_unreachable", + "ex_handler_msr_mce", }; if (!func) -- cgit v1.2.3