Skip to content

Commit 69afd82

Browse files
Peter Zijlstragregkh
authored andcommitted
x86/its: FineIBT-paranoid vs ITS
commit e52c1dc7455d32c8a55f9949d300e5e87d011fa6 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) <[email protected]> Signed-off-by: Pawan Gupta <[email protected]> Signed-off-by: Dave Hansen <[email protected]> Reviewed-by: Alexandre Chartre <[email protected]> [ 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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 73c7176 commit 69afd82

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

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 ALTINSTR_FLAG_INV (1 << 15)
1011
#define ALT_NOT(feat) ((feat) | ALTINSTR_FLAG_INV)
@@ -85,10 +86,17 @@ struct module;
8586
extern void its_init_mod(struct module *mod);
8687
extern void its_fini_mod(struct module *mod);
8788
extern void its_free_mod(struct module *mod);
89+
extern u8 *its_static_thunk(int reg);
8890
#else /* CONFIG_MITIGATION_ITS */
8991
static inline void its_init_mod(struct module *mod) { }
9092
static inline void its_fini_mod(struct module *mod) { }
9193
static inline void its_free_mod(struct module *mod) { }
94+
static inline u8 *its_static_thunk(int reg)
95+
{
96+
WARN_ONCE(1, "ITS not compiled in");
97+
98+
return NULL;
99+
}
92100
#endif
93101

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

arch/x86/kernel/alternative.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,14 @@ static bool cpu_wants_indirect_its_thunk_at(unsigned long addr, int reg)
596596
/* Lower-half of the cacheline? */
597597
return !(addr & 0x20);
598598
}
599+
600+
u8 *its_static_thunk(int reg)
601+
{
602+
u8 *thunk = __x86_indirect_its_thunk_array[reg];
603+
604+
return thunk;
605+
}
606+
599607
#endif
600608

601609
/*

arch/x86/net/bpf_jit_comp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ static void emit_indirect_jump(u8 **pprog, int reg, u8 *ip)
467467
if (IS_ENABLED(CONFIG_MITIGATION_ITS) &&
468468
cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS)) {
469469
OPTIMIZER_HIDE_VAR(reg);
470-
emit_jump(&prog, &__x86_indirect_its_thunk_array[reg], ip);
470+
emit_jump(&prog, its_static_thunk(reg), ip);
471471
} else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE)) {
472472
EMIT_LFENCE();
473473
EMIT2(0xFF, 0xE0 + reg);

0 commit comments

Comments
 (0)