[PATCH v3] x86: Add -mharden-sls=[none|all|return|indirect-branch]

H.J. Lu hjl.tools@gmail.com
Wed Nov 17 20:01:51 GMT 2021


On Wed, Nov 17, 2021 at 7:53 AM Uros Bizjak <ubizjak@gmail.com> wrote:
>
> On Wed, Nov 17, 2021 at 4:35 PM H.J. Lu <hjl.tools@gmail.com> 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.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: v3-0001-x86-Add-mharden-sls-none-all-return-indirect-bran.patch
Type: text/x-patch
Size: 10063 bytes
Desc: not available
URL: <https://gcc.gnu.org/pipermail/gcc-patches/attachments/20211117/640d1d7e/attachment-0001.bin>


More information about the Gcc-patches mailing list