mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 02:24:24 +02:00
Miscellaneous x86 fixes:
- Fix speculative safety in fred_extint()
- Fix __WARN_printf() trap in early_fixup_exception()
- Fix clang-build boot bug for unusual alignments,
triggered by CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B=y
- Replace the final few __ASSEMBLY__ stragglers that snuck
in lately into non-UAPI x86 headers and use __ASSEMBLER__
consistently (again).
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-----BEGIN PGP SIGNATURE-----
iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAmmkBnwRHG1pbmdvQGtl
cm5lbC5vcmcACgkQEnMQ0APhK1hPpw/+IyRN/VoRYWnqJL/BVCT6PRLhtmc+/+9t
JLYjCXwDZDf6NGDVOQfeMuubJSt7wSlttPScbQbCSpj1o/xN5AdyBav5jG6fV/PQ
B9+p+dh4rQSLQR5PHj/PKC9arBSsnBgnTuQKYxCEd/RDc5czNd+tgy6AWsQKS4Ti
a5xOtsE4xZql49ypOm1JeOu8bZKF+yui6zl8alIE1V1P/dDt9VQ7h7tQB5Dki7Vc
XVxKOhPAcNpsAa7PXgFihH3g5fqF5WRz1MOvxuVEhlpnJ31LsNhYznUJjwu+VnV0
0rQDPLs1qs2tq0ysboXh6NVmmjH0ojSQXTlkGsi5Qa4r2EwH0ZcmF74YS9fOzwP2
V35vGb6Fl0rtZPdQMN0uA6DfiG8+M2yyky71QwoTE27qvbZtXA8wDYn4N2PQa4ZJ
BJG1MVNzttkxwmRNJa2rg8Uyr7FvG2NVpqJUbFwD87McQtlyv9LUWHw4N8z2nqq9
3uhj862MCz136zA+jUSR2+zh9aNnx8y/pNMzmwqRAuj5mpH5CK3FZfUlDKWE2YI0
3tEnbrvL3pv8sIT0/ttyERkCQGBdesHZ5ZaHljb7AUcSVn/Neroo1TZGqrBjyeeV
kq0w8SHj+BNBs8dNuuy+ONc/Pzk0BMTPpS/flb5qvbCKT655LnCUwIdwy2IIT3XA
94PISb+ZZQ8=
=A61U
-----END PGP SIGNATURE-----
Merge tag 'x86-urgent-2026-03-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Ingo Molnar:
- Fix speculative safety in fred_extint()
- Fix __WARN_printf() trap in early_fixup_exception()
- Fix clang-build boot bug for unusual alignments, triggered by
CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B=y
- Replace the final few __ASSEMBLY__ stragglers that snuck in lately
into non-UAPI x86 headers and use __ASSEMBLER__ consistently (again)
* tag 'x86-urgent-2026-03-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/headers: Replace __ASSEMBLY__ stragglers with __ASSEMBLER__
x86/cfi: Fix CFI rewrite for odd alignments
x86/bug: Handle __WARN_printf() trap in early_fixup_exception()
x86/fred: Correct speculative safety in fred_extint()
This commit is contained in:
commit
5920da4455
|
|
@ -160,8 +160,6 @@ void __init fred_complete_exception_setup(void)
|
|||
static noinstr void fred_extint(struct pt_regs *regs)
|
||||
{
|
||||
unsigned int vector = regs->fred_ss.vector;
|
||||
unsigned int index = array_index_nospec(vector - FIRST_SYSTEM_VECTOR,
|
||||
NR_SYSTEM_VECTORS);
|
||||
|
||||
if (WARN_ON_ONCE(vector < FIRST_EXTERNAL_VECTOR))
|
||||
return;
|
||||
|
|
@ -170,7 +168,8 @@ static noinstr void fred_extint(struct pt_regs *regs)
|
|||
irqentry_state_t state = irqentry_enter(regs);
|
||||
|
||||
instrumentation_begin();
|
||||
sysvec_table[index](regs);
|
||||
sysvec_table[array_index_nospec(vector - FIRST_SYSTEM_VECTOR,
|
||||
NR_SYSTEM_VECTORS)](regs);
|
||||
instrumentation_end();
|
||||
irqentry_exit(regs, state);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#include <linux/objtool.h>
|
||||
#include <asm/asm.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifndef __ASSEMBLER__
|
||||
struct bug_entry;
|
||||
extern void __WARN_trap(struct bug_entry *bug, ...);
|
||||
#endif
|
||||
|
|
@ -137,7 +137,7 @@ do { \
|
|||
|
||||
#ifdef HAVE_ARCH_BUG_FORMAT_ARGS
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifndef __ASSEMBLER__
|
||||
#include <linux/static_call_types.h>
|
||||
DECLARE_STATIC_CALL(WARN_trap, __WARN_trap);
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ struct arch_va_list {
|
|||
struct sysv_va_list args;
|
||||
};
|
||||
extern void *__warn_args(struct arch_va_list *args, struct pt_regs *regs);
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#define __WARN_bug_entry(flags, format) ({ \
|
||||
struct bug_entry *bug; \
|
||||
|
|
|
|||
|
|
@ -111,6 +111,12 @@ extern bhi_thunk __bhi_args_end[];
|
|||
|
||||
struct pt_regs;
|
||||
|
||||
#ifdef CONFIG_CALL_PADDING
|
||||
#define CFI_OFFSET (CONFIG_FUNCTION_PADDING_CFI+5)
|
||||
#else
|
||||
#define CFI_OFFSET 5
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CFI
|
||||
enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
|
||||
#define __bpfcall
|
||||
|
|
@ -119,11 +125,9 @@ static inline int cfi_get_offset(void)
|
|||
{
|
||||
switch (cfi_mode) {
|
||||
case CFI_FINEIBT:
|
||||
return 16;
|
||||
return /* fineibt_prefix_size */ 16;
|
||||
case CFI_KCFI:
|
||||
if (IS_ENABLED(CONFIG_CALL_PADDING))
|
||||
return 16;
|
||||
return 5;
|
||||
return CFI_OFFSET;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ static __always_inline void native_local_irq_restore(unsigned long flags)
|
|||
#endif
|
||||
|
||||
#ifndef CONFIG_PARAVIRT
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifndef __ASSEMBLER__
|
||||
/*
|
||||
* Used in the idle loop; sti takes one instruction cycle
|
||||
* to complete:
|
||||
|
|
@ -95,7 +95,7 @@ static __always_inline void halt(void)
|
|||
{
|
||||
native_halt();
|
||||
}
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif /* CONFIG_PARAVIRT */
|
||||
|
||||
#ifdef CONFIG_PARAVIRT_XXL
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
* Depending on -fpatchable-function-entry=N,N usage (CONFIG_CALL_PADDING) the
|
||||
* CFI symbol layout changes.
|
||||
*
|
||||
* Without CALL_THUNKS:
|
||||
* Without CALL_PADDING:
|
||||
*
|
||||
* .align FUNCTION_ALIGNMENT
|
||||
* __cfi_##name:
|
||||
|
|
@ -77,7 +77,7 @@
|
|||
* .long __kcfi_typeid_##name
|
||||
* name:
|
||||
*
|
||||
* With CALL_THUNKS:
|
||||
* With CALL_PADDING:
|
||||
*
|
||||
* .align FUNCTION_ALIGNMENT
|
||||
* __cfi_##name:
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
#define PER_CPU_VAR(var) __percpu(var)__percpu_rel
|
||||
|
||||
#else /* !__ASSEMBLY__: */
|
||||
#else /* !__ASSEMBLER__: */
|
||||
|
||||
#include <linux/args.h>
|
||||
#include <linux/bits.h>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#error "Cannot use runtime-const infrastructure from modules"
|
||||
#endif
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
#ifdef __ASSEMBLER__
|
||||
|
||||
.macro RUNTIME_CONST_PTR sym reg
|
||||
movq $0x0123456789abcdef, %\reg
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
.popsection
|
||||
.endm
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
#else /* __ASSEMBLER__ */
|
||||
|
||||
#define runtime_const_ptr(sym) ({ \
|
||||
typeof(sym) __ret; \
|
||||
|
|
@ -74,5 +74,5 @@ static inline void runtime_const_fixup(void (*fn)(void *, unsigned long),
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ASSEMBLER__ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ extern int ibt_selftest_noendbr(void);
|
|||
void handle_invalid_op(struct pt_regs *regs);
|
||||
#endif
|
||||
|
||||
noinstr bool handle_bug(struct pt_regs *regs);
|
||||
|
||||
static inline int get_si_code(unsigned long condition)
|
||||
{
|
||||
if (condition & DR_STEP)
|
||||
|
|
|
|||
|
|
@ -1182,7 +1182,7 @@ void __init_or_module noinline apply_seal_endbr(s32 *start, s32 *end)
|
|||
|
||||
poison_endbr(addr);
|
||||
if (IS_ENABLED(CONFIG_FINEIBT))
|
||||
poison_cfi(addr - 16);
|
||||
poison_cfi(addr - CFI_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1389,6 +1389,8 @@ extern u8 fineibt_preamble_end[];
|
|||
#define fineibt_preamble_ud 0x13
|
||||
#define fineibt_preamble_hash 5
|
||||
|
||||
#define fineibt_prefix_size (fineibt_preamble_size - ENDBR_INSN_SIZE)
|
||||
|
||||
/*
|
||||
* <fineibt_caller_start>:
|
||||
* 0: b8 78 56 34 12 mov $0x12345678, %eax
|
||||
|
|
@ -1634,7 +1636,7 @@ static int cfi_rewrite_preamble(s32 *start, s32 *end)
|
|||
* have determined there are no indirect calls to it and we
|
||||
* don't need no CFI either.
|
||||
*/
|
||||
if (!is_endbr(addr + 16))
|
||||
if (!is_endbr(addr + CFI_OFFSET))
|
||||
continue;
|
||||
|
||||
hash = decode_preamble_hash(addr, &arity);
|
||||
|
|
@ -1642,6 +1644,15 @@ static int cfi_rewrite_preamble(s32 *start, s32 *end)
|
|||
addr, addr, 5, addr))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* FineIBT relies on being at func-16, so if the preamble is
|
||||
* actually larger than that, place it the tail end.
|
||||
*
|
||||
* NOTE: this is possible with things like DEBUG_CALL_THUNKS
|
||||
* and DEBUG_FORCE_FUNCTION_ALIGN_64B.
|
||||
*/
|
||||
addr += CFI_OFFSET - fineibt_prefix_size;
|
||||
|
||||
text_poke_early(addr, fineibt_preamble_start, fineibt_preamble_size);
|
||||
WARN_ON(*(u32 *)(addr + fineibt_preamble_hash) != 0x12345678);
|
||||
text_poke_early(addr + fineibt_preamble_hash, &hash, 4);
|
||||
|
|
@ -1664,10 +1675,10 @@ static void cfi_rewrite_endbr(s32 *start, s32 *end)
|
|||
for (s = start; s < end; s++) {
|
||||
void *addr = (void *)s + *s;
|
||||
|
||||
if (!exact_endbr(addr + 16))
|
||||
if (!exact_endbr(addr + CFI_OFFSET))
|
||||
continue;
|
||||
|
||||
poison_endbr(addr + 16);
|
||||
poison_endbr(addr + CFI_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1772,7 +1783,8 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,
|
|||
if (FINEIBT_WARN(fineibt_preamble_size, 20) ||
|
||||
FINEIBT_WARN(fineibt_preamble_bhi + fineibt_bhi1_size, 20) ||
|
||||
FINEIBT_WARN(fineibt_caller_size, 14) ||
|
||||
FINEIBT_WARN(fineibt_paranoid_size, 20))
|
||||
FINEIBT_WARN(fineibt_paranoid_size, 20) ||
|
||||
WARN_ON_ONCE(CFI_OFFSET < fineibt_prefix_size))
|
||||
return;
|
||||
|
||||
if (cfi_mode == CFI_AUTO) {
|
||||
|
|
@ -1885,6 +1897,11 @@ static void poison_cfi(void *addr)
|
|||
*/
|
||||
switch (cfi_mode) {
|
||||
case CFI_FINEIBT:
|
||||
/*
|
||||
* FineIBT preamble is at func-16.
|
||||
*/
|
||||
addr += CFI_OFFSET - fineibt_prefix_size;
|
||||
|
||||
/*
|
||||
* FineIBT prefix should start with an ENDBR.
|
||||
*/
|
||||
|
|
@ -1923,8 +1940,6 @@ static void poison_cfi(void *addr)
|
|||
}
|
||||
}
|
||||
|
||||
#define fineibt_prefix_size (fineibt_preamble_size - ENDBR_INSN_SIZE)
|
||||
|
||||
/*
|
||||
* When regs->ip points to a 0xD6 byte in the FineIBT preamble,
|
||||
* return true and fill out target and type.
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ static inline void handle_invalid_op(struct pt_regs *regs)
|
|||
ILL_ILLOPN, error_get_trap_addr(regs));
|
||||
}
|
||||
|
||||
static noinstr bool handle_bug(struct pt_regs *regs)
|
||||
noinstr bool handle_bug(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long addr = regs->ip;
|
||||
bool handled = false;
|
||||
|
|
|
|||
|
|
@ -411,14 +411,11 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
|
|||
return;
|
||||
|
||||
if (trapnr == X86_TRAP_UD) {
|
||||
if (report_bug(regs->ip, regs) == BUG_TRAP_TYPE_WARN) {
|
||||
/* Skip the ud2. */
|
||||
regs->ip += LEN_UD2;
|
||||
if (handle_bug(regs))
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this was a BUG and report_bug returns or if this
|
||||
* If this was a BUG and handle_bug returns or if this
|
||||
* was just a normal #UD, we want to continue onward and
|
||||
* crash.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -438,17 +438,8 @@ static void emit_kcfi(u8 **pprog, u32 hash)
|
|||
|
||||
EMIT1_off32(0xb8, hash); /* movl $hash, %eax */
|
||||
#ifdef CONFIG_CALL_PADDING
|
||||
EMIT1(0x90);
|
||||
EMIT1(0x90);
|
||||
EMIT1(0x90);
|
||||
EMIT1(0x90);
|
||||
EMIT1(0x90);
|
||||
EMIT1(0x90);
|
||||
EMIT1(0x90);
|
||||
EMIT1(0x90);
|
||||
EMIT1(0x90);
|
||||
EMIT1(0x90);
|
||||
EMIT1(0x90);
|
||||
for (int i = 0; i < CONFIG_FUNCTION_PADDING_CFI; i++)
|
||||
EMIT1(0x90);
|
||||
#endif
|
||||
EMIT_ENDBR();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user