On Wed, Nov 17, 2021 at 7:53 AM Uros Bizjak wrote: > > On Wed, Nov 17, 2021 at 4:35 PM H.J. Lu wrote: > > > > Add -mharden-sls= to mitigate against straight line speculation (SLS) > > for function return and indirect branch by adding an INT3 instruction > > after function return and indirect branch. > > > > gcc/ > > > > PR target/102952 > > * config/i386/i386-opts.h (harden_sls): New enum. > > * config/i386/i386.c (output_indirect_thunk): Mitigate against > > SLS for function return. > > (ix86_output_function_return): Likewise. > > (ix86_output_jmp_thunk_or_indirect): Mitigate against indirect > > branch. > > (ix86_output_indirect_jmp): Likewise. > > (ix86_output_call_insn): Likewise. > > * config/i386/i386.opt: Add -mharden-sls=. > > * doc/invoke.texi: Document -mharden-sls=. > > > > gcc/testsuite/ > > > > PR target/102952 > > * gcc.target/i386/harden-sls-1.c: New test. > > * gcc.target/i386/harden-sls-2.c: Likewise. > > * gcc.target/i386/harden-sls-3.c: Likewise. > > * gcc.target/i386/harden-sls-4.c: Likewise. > > * gcc.target/i386/harden-sls-5.c: Likewise. > > --- > > gcc/config/i386/i386-opts.h | 7 ++++++ > > gcc/config/i386/i386.c | 23 ++++++++++++++------ > > gcc/config/i386/i386.opt | 20 +++++++++++++++++ > > gcc/doc/invoke.texi | 10 ++++++++- > > gcc/testsuite/gcc.target/i386/harden-sls-1.c | 14 ++++++++++++ > > gcc/testsuite/gcc.target/i386/harden-sls-2.c | 14 ++++++++++++ > > gcc/testsuite/gcc.target/i386/harden-sls-3.c | 14 ++++++++++++ > > gcc/testsuite/gcc.target/i386/harden-sls-4.c | 16 ++++++++++++++ > > gcc/testsuite/gcc.target/i386/harden-sls-5.c | 17 +++++++++++++++ > > 9 files changed, 127 insertions(+), 8 deletions(-) > > create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-1.c > > create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-2.c > > create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-3.c > > create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-4.c > > create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-5.c > > > > diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h > > index 04e4ad608fb..171d3106d0a 100644 > > --- a/gcc/config/i386/i386-opts.h > > +++ b/gcc/config/i386/i386-opts.h > > @@ -121,4 +121,11 @@ enum instrument_return { > > instrument_return_nop5 > > }; > > > > +enum harden_sls { > > + harden_sls_none = 0, > > + harden_sls_return = 1 << 0, > > + harden_sls_indirect_branch = 1 << 1, > > + harden_sls_all = harden_sls_return | harden_sls_indirect_branch > > +}; > > + > > #endif > > diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > > index 73c4d5115bb..8bbf6ae9875 100644 > > --- a/gcc/config/i386/i386.c > > +++ b/gcc/config/i386/i386.c > > @@ -5914,6 +5914,8 @@ output_indirect_thunk (unsigned int regno) > > } > > > > fputs ("\tret\n", asm_out_file); > > + if ((ix86_harden_sls & harden_sls_return)) > > + fputs ("\tint3\n", asm_out_file); > > } > > > > /* Output a funtion with a call and return thunk for indirect branch. > > @@ -15984,6 +15986,8 @@ ix86_output_jmp_thunk_or_indirect (const char *thunk_name, const int regno) > > fprintf (asm_out_file, "\tjmp\t"); > > assemble_name (asm_out_file, thunk_name); > > putc ('\n', asm_out_file); > > + if ((ix86_harden_sls & harden_sls_indirect_branch)) > > + fputs ("\tint3\n", asm_out_file); > > } > > else > > output_indirect_thunk (regno); > > @@ -16206,10 +16210,10 @@ ix86_output_indirect_jmp (rtx call_op) > > gcc_unreachable (); > > > > ix86_output_indirect_branch (call_op, "%0", true); > > - return ""; > > } > > else > > - return "%!jmp\t%A0"; > > + output_asm_insn ("%!jmp\t%A0", &call_op); > > + return (ix86_harden_sls & harden_sls_indirect_branch) ? "int3" : ""; > > } > > > > /* Output return instrumentation for current function if needed. */ > > @@ -16277,10 +16281,10 @@ ix86_output_function_return (bool long_p) > > return ""; > > } > > > > - if (!long_p) > > - return "%!ret"; > > - > > - return "rep%; ret"; > > + if ((ix86_harden_sls & harden_sls_return)) > > + long_p = false; > > Is the above really needed? This will change "rep ret" to a "[notrack] > ret" when SLS hardening is in effect, with a conditional [notrack] > prefix, even when long ret was requested. Fixed in the v3 patch. > On a related note, "notrack ret" does not assemble for me, the > assembler reports: > > notrack.s:1: Error: expecting indirect branch instruction after `notrack' > > Can you please clarify the above change? I opened: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103307 Here is the v3 patch. -- H.J.