]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
x86/its: FineIBT-paranoid vs ITS
authorPeter Zijlstra <peterz@infradead.org>
Wed, 23 Apr 2025 07:57:31 +0000 (09:57 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 18 May 2025 06:21:26 +0000 (08:21 +0200)
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) <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>
arch/x86/include/asm/alternative.h
arch/x86/kernel/alternative.c
arch/x86/net/bpf_jit_comp.c

index 4463cf38c16998ae61568665d763931616bf996d..fd3b730177384539c287704517385c54cbc0e9aa 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/types.h>
 #include <linux/stringify.h>
 #include <asm/asm.h>
+#include <asm/bug.h>
 
 #define ALTINSTR_FLAG_INV      (1 << 15)
 #define ALT_NOT(feat)          ((feat) | ALTINSTR_FLAG_INV)
@@ -85,10 +86,17 @@ struct module;
 extern void its_init_mod(struct module *mod);
 extern void its_fini_mod(struct module *mod);
 extern void its_free_mod(struct module *mod);
+extern u8 *its_static_thunk(int reg);
 #else /* CONFIG_MITIGATION_ITS */
 static inline void its_init_mod(struct module *mod) { }
 static inline void its_fini_mod(struct module *mod) { }
 static inline void its_free_mod(struct module *mod) { }
+static inline u8 *its_static_thunk(int reg)
+{
+       WARN_ONCE(1, "ITS not compiled in");
+
+       return NULL;
+}
 #endif
 
 #if defined(CONFIG_RETHUNK) && defined(CONFIG_OBJTOOL)
index 7d61f8c7ec38a4bedf154fd8a7e4ed1531dcba58..3bc6be6404d231d76013a598414d20443e473e76 100644 (file)
@@ -596,6 +596,14 @@ static bool cpu_wants_indirect_its_thunk_at(unsigned long addr, int reg)
        /* Lower-half of the cacheline? */
        return !(addr & 0x20);
 }
+
+u8 *its_static_thunk(int reg)
+{
+       u8 *thunk = __x86_indirect_its_thunk_array[reg];
+
+       return thunk;
+}
+
 #endif
 
 /*
index b5fd521a7fa05ed61fae0c0bd00db02b3a2aeca6..f3068bb53c4dbc463ea6761acf195fca1a1f6d79 100644 (file)
@@ -467,7 +467,7 @@ static void emit_indirect_jump(u8 **pprog, int reg, u8 *ip)
        if (IS_ENABLED(CONFIG_MITIGATION_ITS) &&
            cpu_feature_enabled(X86_FEATURE_INDIRECT_THUNK_ITS)) {
                OPTIMIZER_HIDE_VAR(reg);
-               emit_jump(&prog, &__x86_indirect_its_thunk_array[reg], ip);
+               emit_jump(&prog, its_static_thunk(reg), ip);
        } else if (cpu_feature_enabled(X86_FEATURE_RETPOLINE_LFENCE)) {
                EMIT_LFENCE();
                EMIT2(0xFF, 0xE0 + reg);