On Thu, Sep 8, 2022 at 3:07 AM Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote: > > On Thu, Sep 08, 2022 at 11:30:41AM +0200, Peter Zijlstra wrote: > > Let me go do a patch. > > --- > Subject: x86,retpoline: Be sure to emit INT3 after JMP *%\reg > > 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@xxxxxxxxxxxxx> > --- > arch/x86/kernel/alternative.c | 9 +++++++++ > arch/x86/net/bpf_jit_comp.c | 3 ++- > 2 files changed, 11 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c > index 62f6b8b7c4a5..68d84cf8e001 100644 > --- a/arch/x86/kernel/alternative.c > +++ b/arch/x86/kernel/alternative.c > @@ -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; > > diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c > index c1f6c1c51d99..37f821dee68f 100644 > --- a/arch/x86/net/bpf_jit_comp.c > +++ b/arch/x86/net/bpf_jit_comp.c > @@ -419,7 +419,8 @@ 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 */ > + EMIT1(0xCC); /* int3 */ Hmm. Why is this unconditional? Shouldn't it be guarded with CONFIG_xx or cpu_feature_enabled ? People that don't care about hw speculation vulnerabilities shouldn't pay the price of increased code size.