[GIT pull] objtool/urgent for v5.19-rc1

From: Thomas Gleixner
Date: Sun Jun 05 2022 - 05:31:01 EST


Linus,

please pull the latest objtool/urgent branch from:

git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git objtool-urgent-2022-06-05

up to: 2028a255f4df: x86/extable: Annotate ex_handler_msr_mce() as a dead end


A set of objtool fixes:

- Handle __ubsan_handle_builtin_unreachable() correctly and treat it as
noreturn.

- Allow architectures to select uaccess validation

- Use the non-instrumented bit test for test_cpu_has() to prevent escape
from non-instrumentable regions.

- Use arch_ prefixed atomics for JUMP_LABEL=n builds to prevent escape
from non-instrumentable regions.

- Mark a few tiny inline as __always_inline to prevent GCC from bringing
them out of line and instrumenting them.

- Mark the empty stub context_tracking_enabled() as always inline as GCC
brings them out of line and instruments the empty shell.

- Annotate ex_handler_msr_mce() as dead end

Thanks,

tglx

------------------>
Borislav Petkov (1):
x86/extable: Annotate ex_handler_msr_mce() as a dead end

Josh Poimboeuf (1):
objtool: Add CONFIG_HAVE_UACCESS_VALIDATION

Peter Zijlstra (5):
objtool: Mark __ubsan_handle_builtin_unreachable() as noreturn
x86/cpu: Elide KCSAN for cpu_has() and friends
jump_label,noinstr: Avoid instrumentation for JUMP_LABEL=n builds
x86: Always inline on_thread_stack() and current_top_of_stack()
context_tracking: Always inline empty stubs


arch/Kconfig | 4 ++++
arch/x86/Kconfig | 1 +
arch/x86/include/asm/cpufeature.h | 2 +-
arch/x86/include/asm/extable.h | 8 ++++++--
arch/x86/include/asm/processor.h | 4 ++--
include/linux/context_tracking_state.h | 8 ++++----
include/linux/jump_label.h | 4 ++--
scripts/Makefile.build | 2 +-
scripts/link-vmlinux.sh | 4 +++-
tools/objtool/check.c | 4 +++-
10 files changed, 27 insertions(+), 14 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/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
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/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;
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
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 <linux/atomic.h>
#include <linux/bug.h>

-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)
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
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 190b2f6e360a..864bb9dd3584 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -185,7 +185,9 @@ 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",
+ "ex_handler_msr_mce",
};

if (!func)