Skip to content

Commit 8dc8351

Browse files
Peter Zijlstraopsiff
authored andcommitted
x86/its: FineIBT-paranoid vs ITS
commit e52c1dc upstream. FineIBT-paranoid was using the retpoline bytes for the paranoid check, disabling retpolines, because all parts that have IBT also have eIBRS and thus don't need no stinking retpolines. Except... ITS needs the retpolines for indirect calls must not be in the first half of a cacheline :-/ So what was the paranoid call sequence: <fineibt_paranoid_start>: 0: 41 ba 78 56 34 12 mov $0x12345678, %r10d 6: 45 3b 53 f7 cmp -0x9(%r11), %r10d a: 4d 8d 5b <f0> lea -0x10(%r11), %r11 e: 75 fd jne d <fineibt_paranoid_start+0xd> 10: 41 ff d3 call *%r11 13: 90 nop Now becomes: <fineibt_paranoid_start>: 0: 41 ba 78 56 34 12 mov $0x12345678, %r10d 6: 45 3b 53 f7 cmp -0x9(%r11), %r10d a: 4d 8d 5b f0 lea -0x10(%r11), %r11 e: 2e e8 XX XX XX XX cs call __x86_indirect_paranoid_thunk_r11 Where the paranoid_thunk looks like: 1d: <ea> (bad) __x86_indirect_paranoid_thunk_r11: 1e: 75 fd jne 1d __x86_indirect_its_thunk_r11: 20: 41 ff eb jmp *%r11 23: cc int3 [ dhansen: remove initialization to false ] Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Reviewed-by: Alexandre Chartre <alexandre.chartre@oracle.com> [ Just a portion of the original commit, in order to fix a build issue in stable kernels due to backports ] Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com> Link: https://lore.kernel.org/r/20250514113952.GB16434@noisy.programming.kicks-ass.net Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> (cherry picked from commit 772934d9062a0f7297ad4e5bffbd904208655660)
1 parent a822a49 commit 8dc8351

3 files changed

Lines changed: 16 additions & 1 deletion

File tree

arch/x86/include/asm/alternative.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <linux/types.h>
66
#include <linux/stringify.h>
77
#include <asm/asm.h>
8+
#include <asm/bug.h>
89

910
#define ALT_FLAGS_SHIFT 16
1011

@@ -134,10 +135,17 @@ static __always_inline int x86_call_depth_emit_accounting(u8 **pprog,
134135
extern void its_init_mod(struct module *mod);
135136
extern void its_fini_mod(struct module *mod);
136137
extern void its_free_mod(struct module *mod);
138+
extern u8 *its_static_thunk(int reg);
137139
#else /* CONFIG_MITIGATION_ITS */
138140
static inline void its_init_mod(struct module *mod) { }
139141
static inline void its_fini_mod(struct module *mod) { }
140142
static inline void its_free_mod(struct module *mod) { }
143+
static inline u8 *its_static_thunk(int reg)
144+
{
145+
WARN_ONCE(1, "ITS not compiled in");
146+
147+
return NULL;
148+
}
141149
#endif
142150

143151
#if defined(CONFIG_RETHUNK) && defined(CONFIG_OBJTOOL)

arch/x86/kernel/alternative.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,6 +1449,13 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,
14491449
static void poison_cfi(void *addr) { }
14501450
#endif
14511451

1452+
u8 *its_static_thunk(int reg)
1453+
{
1454+
u8 *thunk = __x86_indirect_its_thunk_array[reg];
1455+
1456+
return thunk;
1457+
}
1458+
14521459
#endif
14531460

14541461
void apply_fineibt(s32 *start_retpoline, s32 *end_retpoline,

arch/x86/net/bpf_jit_comp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ static void emit_indirect_jump(u8 **pprog, int reg, u8 *ip)
475475
if (IS_ENABLED(CONFIG_MITIGATION_ITS) &&
476476
cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS)) {
477477
OPTIMIZER_HIDE_VAR(reg);
478-
emit_jump(&prog, &__x86_indirect_its_thunk_array[reg], ip);
478+
emit_jump(&prog, its_static_thunk(reg), ip);
479479
} else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE)) {
480480
EMIT_LFENCE();
481481
EMIT2(0xFF, 0xE0 + reg);

0 commit comments

Comments
 (0)