x86,retpoline: Be sure to emit INT3 after JMP *%\reg
authorPeter Zijlstra <peterz@infradead.org>
Thu, 8 Sep 2022 10:04:50 +0000 (12:04 +0200)
committerPeter Zijlstra <peterz@infradead.org>
Thu, 15 Sep 2022 14:13:53 +0000 (16:13 +0200)
Both AMD and Intel recommend using INT3 after an indirect JMP. Make sure
to emit one when rewriting the retpoline JMP irrespective of compiler
SLS options or even CONFIG_SLS.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Link: https://lkml.kernel.org/r/Yxm+QkFPOhrVSH6q@hirez.programming.kicks-ass.net
arch/x86/kernel/alternative.c
arch/x86/net/bpf_jit_comp.c

index 62f6b8b7c4a5285933b80013ff6fe2aa7bf6e183..68d84cf8e001bc2439247d800fc1e3b550fa930a 100644 (file)
@@ -453,6 +453,15 @@ static int patch_retpoline(void *addr, struct insn *insn, u8 *bytes)
                return ret;
        i += ret;
 
+       /*
+        * The compiler is supposed to EMIT an INT3 after every unconditional
+        * JMP instruction due to AMD BTC. However, if the compiler is too old
+        * or SLS isn't enabled, we still need an INT3 after indirect JMPs
+        * even on Intel.
+        */
+       if (op == JMP32_INSN_OPCODE && i < insn->length)
+               bytes[i++] = INT3_INSN_OPCODE;
+
        for (; i < insn->length;)
                bytes[i++] = BYTES_NOP1;
 
index c1f6c1c51d998ffafedb79e1cab167939f372aa4..4922517ddb0d5fd1a093249e75193ebf2e17fc65 100644 (file)
@@ -419,7 +419,9 @@ static void emit_indirect_jump(u8 **pprog, int reg, u8 *ip)
                OPTIMIZER_HIDE_VAR(reg);
                emit_jump(&prog, &__x86_indirect_thunk_array[reg], ip);
        } else {
-               EMIT2(0xFF, 0xE0 + reg);
+               EMIT2(0xFF, 0xE0 + reg);        /* jmp *%\reg */
+               if (IS_ENABLED(CONFIG_RETPOLINE) || IS_ENABLED(CONFIG_SLS))
+                       EMIT1(0xCC);            /* int3 */
        }
 
        *pprog = prog;