Message ID | 20211116182003.3859036-1-hjl.tools@gmail.com |
---|---|
State | New |
Headers | show |
Series | x86: Add -mharden-sls=[none|all|return|indirect-branch] | expand |
On Tue, Nov 16, 2021 at 7:20 PM H.J. Lu via Gcc-patches <gcc-patches@gcc.gnu.org> 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/config/i386/i386-opts.h | 7 +++++ > gcc/config/i386/i386.c | 30 ++++++++++++++++---- > 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 | 14 +++++++++ > 8 files changed, 116 insertions(+), 7 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 > > 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 cc9f9322fad..0a902d66321 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. > @@ -15987,6 +15989,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); > @@ -16212,10 +16216,14 @@ ix86_output_indirect_jmp (rtx call_op) > gcc_unreachable (); > > ix86_output_indirect_branch (call_op, "%0", true); > - return ""; > + if ((ix86_harden_sls & harden_sls_indirect_branch)) > + return "int3"; > + else > + return ""; > } > else > - return "%!jmp\t%A0"; > + return ((ix86_harden_sls & harden_sls_indirect_branch) > + ? "%!jmp\t%A0\n\tint3" : "%!jmp\t%A0"); > } Just change existing returns to fputs and end function with: return (ix86_harden_sls & harden_sls_indirect_branch) ? "int3" : ""; > /* Output return instrumentation for current function if needed. */ > @@ -16283,10 +16291,15 @@ ix86_output_function_return (bool long_p) > return ""; > } > > - if (!long_p) > - return "%!ret"; > + if ((ix86_harden_sls & harden_sls_return)) > + return "%!ret\n\tint3"; > + else > + { > + if (!long_p) > + return "%!ret"; > > - return "rep%; ret"; > + return "rep%; ret"; > + } > } Also here. > > /* Output indirect function return. RET_OP is the function return > @@ -16381,7 +16394,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) > if (output_indirect_p && !direct_p) > ix86_output_indirect_branch (call_op, xasm, true); > else > - output_asm_insn (xasm, &call_op); > + { > + output_asm_insn (xasm, &call_op); > + if (!direct_p > + && (ix86_harden_sls & harden_sls_indirect_branch)) > + return "int3"; > + } > return ""; > } > > diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt > index b38ac13fc91..c5452c49597 100644 > --- a/gcc/config/i386/i386.opt > +++ b/gcc/config/i386/i386.opt > @@ -1121,6 +1121,26 @@ mrecord-return > Target Var(ix86_flag_record_return) Init(0) > Generate a __return_loc section pointing to all return instrumentation code. > > +mharden-sls= > +Target RejectNegative Joined Enum(harden_sls) Var(ix86_harden_sls) Init(harden_sls_none) > +Generate code to mitigate against straight line speculation. > + > +Enum > +Name(harden_sls) Type(enum harden_sls) > +Known choices for mitigation against straight line speculation with -mharden-sls=: > + > +EnumValue > +Enum(harden_sls) String(none) Value(harden_sls_none) > + > +EnumValue > +Enum(harden_sls) String(all) Value(harden_sls_all) > + > +EnumValue > +Enum(harden_sls) String(return) Value(harden_sls_return) > + > +EnumValue > +Enum(harden_sls) String(indirect-branch) Value(harden_sls_indirect_branch) > + > mavx512bf16 > Target Mask(ISA2_AVX512BF16) Var(ix86_isa_flags2) Save > Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > index 6070288856c..f3b4b467765 100644 > --- a/gcc/doc/invoke.texi > +++ b/gcc/doc/invoke.texi > @@ -1425,7 +1425,7 @@ See RS/6000 and PowerPC Options. > -mstack-protector-guard-symbol=@var{symbol} @gol > -mgeneral-regs-only -mcall-ms2sysv-xlogues -mrelax-cmpxchg-loop @gol > -mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol > --mindirect-branch-register -mneeded} > +-mindirect-branch-register -mharden-sls=@var{choice} -mneeded} > > @emph{x86 Windows Options} > @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol > @@ -32382,6 +32382,14 @@ not be reachable in the large code model. > @opindex mindirect-branch-register > Force indirect call and jump via register. > > +@item -mharden-sls=@var{choice} > +@opindex mharden-sls > +Generate code to mitigate against straight line speculation (SLS) with > +@var{choice}. The default is @samp{none} which disables all SLS > +hardening. @samp{return} enables SLS hardening for function return. > +@samp{indirect-branch} enables SLS hardening for indirect branch. > +@samp{all} enables all SLS hardening. > + > @end table > > These @samp{-m} switches are supported in addition to the above > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-1.c b/gcc/testsuite/gcc.target/i386/harden-sls-1.c > new file mode 100644 > index 00000000000..6f70dc94a23 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-1.c > @@ -0,0 +1,14 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */ > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > + > +extern void foo (void); > + > +void > +bar (void) > +{ > + foo (); > +} > + > +/* { dg-final { scan-assembler "jmp\[ \t\]+_?foo" } } */ > +/* { dg-final { scan-assembler-not {int3} } } */ > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-2.c b/gcc/testsuite/gcc.target/i386/harden-sls-2.c > new file mode 100644 > index 00000000000..a7c59078d03 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-2.c > @@ -0,0 +1,14 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */ > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > + > +extern void (*fptr) (void); > + > +void > +foo (void) > +{ > + fptr (); > +} > + > +/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */ > +/* { dg-final { scan-assembler-times "int3" 1 } } */ > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-3.c b/gcc/testsuite/gcc.target/i386/harden-sls-3.c > new file mode 100644 > index 00000000000..1a6056b6d7b > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-3.c > @@ -0,0 +1,14 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -mindirect-branch=thunk -mharden-sls=all" } */ > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > + > +extern void (*fptr) (void); > + > +void > +foo (void) > +{ > + fptr (); > +} > + > +/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */ > +/* { dg-final { scan-assembler-times "int3" 2 } } */ > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-4.c b/gcc/testsuite/gcc.target/i386/harden-sls-4.c > new file mode 100644 > index 00000000000..c33147f11b5 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-4.c > @@ -0,0 +1,14 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -mindirect-branch=keep -mharden-sls=all" } */ > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > + > +extern void (*fptr) (void); > + > +void > +foo (void) > +{ > + fptr (); > +} > + > +/* { dg-final { scan-assembler "jmp\[ \t\]+\\*_?fptr" } } */ > +/* { dg-final { scan-assembler-times "int3" 1 } } */ > -- > 2.33.1 >
On Wed, Nov 17, 2021 at 1:05 AM Uros Bizjak <ubizjak@gmail.com> wrote: > > On Tue, Nov 16, 2021 at 7:20 PM H.J. Lu via Gcc-patches > <gcc-patches@gcc.gnu.org> 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/config/i386/i386-opts.h | 7 +++++ > > gcc/config/i386/i386.c | 30 ++++++++++++++++---- > > 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 | 14 +++++++++ > > 8 files changed, 116 insertions(+), 7 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 > > > > 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 cc9f9322fad..0a902d66321 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. > > @@ -15987,6 +15989,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); > > @@ -16212,10 +16216,14 @@ ix86_output_indirect_jmp (rtx call_op) > > gcc_unreachable (); > > > > ix86_output_indirect_branch (call_op, "%0", true); > > - return ""; > > + if ((ix86_harden_sls & harden_sls_indirect_branch)) > > + return "int3"; > > + else > > + return ""; > > } > > else > > - return "%!jmp\t%A0"; > > + return ((ix86_harden_sls & harden_sls_indirect_branch) > > + ? "%!jmp\t%A0\n\tint3" : "%!jmp\t%A0"); > > } > > Just change existing returns to fputs and end function with: > > return (ix86_harden_sls & harden_sls_indirect_branch) ? "int3" : ""; But fputs doesn't support %A0. > > /* Output return instrumentation for current function if needed. */ > > @@ -16283,10 +16291,15 @@ ix86_output_function_return (bool long_p) > > return ""; > > } > > > > - if (!long_p) > > - return "%!ret"; > > + if ((ix86_harden_sls & harden_sls_return)) > > + return "%!ret\n\tint3"; > > + else > > + { > > + if (!long_p) > > + return "%!ret"; > > > > - return "rep%; ret"; > > + return "rep%; ret"; > > + } > > } > > Also here. But fputs doesn't know "%!". > > > > > /* Output indirect function return. RET_OP is the function return > > @@ -16381,7 +16394,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) > > if (output_indirect_p && !direct_p) > > ix86_output_indirect_branch (call_op, xasm, true); > > else > > - output_asm_insn (xasm, &call_op); > > + { > > + output_asm_insn (xasm, &call_op); > > + if (!direct_p > > + && (ix86_harden_sls & harden_sls_indirect_branch)) > > + return "int3"; > > + } > > return ""; > > } > > > > diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt > > index b38ac13fc91..c5452c49597 100644 > > --- a/gcc/config/i386/i386.opt > > +++ b/gcc/config/i386/i386.opt > > @@ -1121,6 +1121,26 @@ mrecord-return > > Target Var(ix86_flag_record_return) Init(0) > > Generate a __return_loc section pointing to all return instrumentation code. > > > > +mharden-sls= > > +Target RejectNegative Joined Enum(harden_sls) Var(ix86_harden_sls) Init(harden_sls_none) > > +Generate code to mitigate against straight line speculation. > > + > > +Enum > > +Name(harden_sls) Type(enum harden_sls) > > +Known choices for mitigation against straight line speculation with -mharden-sls=: > > + > > +EnumValue > > +Enum(harden_sls) String(none) Value(harden_sls_none) > > + > > +EnumValue > > +Enum(harden_sls) String(all) Value(harden_sls_all) > > + > > +EnumValue > > +Enum(harden_sls) String(return) Value(harden_sls_return) > > + > > +EnumValue > > +Enum(harden_sls) String(indirect-branch) Value(harden_sls_indirect_branch) > > + > > mavx512bf16 > > Target Mask(ISA2_AVX512BF16) Var(ix86_isa_flags2) Save > > Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and > > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > > index 6070288856c..f3b4b467765 100644 > > --- a/gcc/doc/invoke.texi > > +++ b/gcc/doc/invoke.texi > > @@ -1425,7 +1425,7 @@ See RS/6000 and PowerPC Options. > > -mstack-protector-guard-symbol=@var{symbol} @gol > > -mgeneral-regs-only -mcall-ms2sysv-xlogues -mrelax-cmpxchg-loop @gol > > -mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol > > --mindirect-branch-register -mneeded} > > +-mindirect-branch-register -mharden-sls=@var{choice} -mneeded} > > > > @emph{x86 Windows Options} > > @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol > > @@ -32382,6 +32382,14 @@ not be reachable in the large code model. > > @opindex mindirect-branch-register > > Force indirect call and jump via register. > > > > +@item -mharden-sls=@var{choice} > > +@opindex mharden-sls > > +Generate code to mitigate against straight line speculation (SLS) with > > +@var{choice}. The default is @samp{none} which disables all SLS > > +hardening. @samp{return} enables SLS hardening for function return. > > +@samp{indirect-branch} enables SLS hardening for indirect branch. > > +@samp{all} enables all SLS hardening. > > + > > @end table > > > > These @samp{-m} switches are supported in addition to the above > > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-1.c b/gcc/testsuite/gcc.target/i386/harden-sls-1.c > > new file mode 100644 > > index 00000000000..6f70dc94a23 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-1.c > > @@ -0,0 +1,14 @@ > > +/* { dg-do compile } */ > > +/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */ > > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > > + > > +extern void foo (void); > > + > > +void > > +bar (void) > > +{ > > + foo (); > > +} > > + > > +/* { dg-final { scan-assembler "jmp\[ \t\]+_?foo" } } */ > > +/* { dg-final { scan-assembler-not {int3} } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-2.c b/gcc/testsuite/gcc.target/i386/harden-sls-2.c > > new file mode 100644 > > index 00000000000..a7c59078d03 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-2.c > > @@ -0,0 +1,14 @@ > > +/* { dg-do compile } */ > > +/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */ > > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > > + > > +extern void (*fptr) (void); > > + > > +void > > +foo (void) > > +{ > > + fptr (); > > +} > > + > > +/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */ > > +/* { dg-final { scan-assembler-times "int3" 1 } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-3.c b/gcc/testsuite/gcc.target/i386/harden-sls-3.c > > new file mode 100644 > > index 00000000000..1a6056b6d7b > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-3.c > > @@ -0,0 +1,14 @@ > > +/* { dg-do compile } */ > > +/* { dg-options "-O2 -mindirect-branch=thunk -mharden-sls=all" } */ > > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > > + > > +extern void (*fptr) (void); > > + > > +void > > +foo (void) > > +{ > > + fptr (); > > +} > > + > > +/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */ > > +/* { dg-final { scan-assembler-times "int3" 2 } } */ > > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-4.c b/gcc/testsuite/gcc.target/i386/harden-sls-4.c > > new file mode 100644 > > index 00000000000..c33147f11b5 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-4.c > > @@ -0,0 +1,14 @@ > > +/* { dg-do compile } */ > > +/* { dg-options "-O2 -mindirect-branch=keep -mharden-sls=all" } */ > > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > > + > > +extern void (*fptr) (void); > > + > > +void > > +foo (void) > > +{ > > + fptr (); > > +} > > + > > +/* { dg-final { scan-assembler "jmp\[ \t\]+\\*_?fptr" } } */ > > +/* { dg-final { scan-assembler-times "int3" 1 } } */ > > -- > > 2.33.1 > >
On Wed, Nov 17, 2021 at 2:46 PM H.J. Lu <hjl.tools@gmail.com> wrote: > > On Wed, Nov 17, 2021 at 1:05 AM Uros Bizjak <ubizjak@gmail.com> wrote: > > > > On Tue, Nov 16, 2021 at 7:20 PM H.J. Lu via Gcc-patches > > <gcc-patches@gcc.gnu.org> 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/config/i386/i386-opts.h | 7 +++++ > > > gcc/config/i386/i386.c | 30 ++++++++++++++++---- > > > 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 | 14 +++++++++ > > > 8 files changed, 116 insertions(+), 7 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 > > > > > > 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 cc9f9322fad..0a902d66321 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. > > > @@ -15987,6 +15989,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); > > > @@ -16212,10 +16216,14 @@ ix86_output_indirect_jmp (rtx call_op) > > > gcc_unreachable (); > > > > > > ix86_output_indirect_branch (call_op, "%0", true); > > > - return ""; > > > + if ((ix86_harden_sls & harden_sls_indirect_branch)) > > > + return "int3"; > > > + else > > > + return ""; > > > } > > > else > > > - return "%!jmp\t%A0"; > > > + return ((ix86_harden_sls & harden_sls_indirect_branch) > > > + ? "%!jmp\t%A0\n\tint3" : "%!jmp\t%A0"); > > > } > > > > Just change existing returns to fputs and end function with: > > > > return (ix86_harden_sls & harden_sls_indirect_branch) ? "int3" : ""; > > But fputs doesn't support %A0. Sorry for the thinko, output_asm_insn instead of fputs will do the trick. Uros. > > > > /* Output return instrumentation for current function if needed. */ > > > @@ -16283,10 +16291,15 @@ ix86_output_function_return (bool long_p) > > > return ""; > > > } > > > > > > - if (!long_p) > > > - return "%!ret"; > > > + if ((ix86_harden_sls & harden_sls_return)) > > > + return "%!ret\n\tint3"; > > > + else > > > + { > > > + if (!long_p) > > > + return "%!ret"; > > > > > > - return "rep%; ret"; > > > + return "rep%; ret"; > > > + } > > > } > > > > Also here. > > But fputs doesn't know "%!". > > > > > > > > > /* Output indirect function return. RET_OP is the function return > > > @@ -16381,7 +16394,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) > > > if (output_indirect_p && !direct_p) > > > ix86_output_indirect_branch (call_op, xasm, true); > > > else > > > - output_asm_insn (xasm, &call_op); > > > + { > > > + output_asm_insn (xasm, &call_op); > > > + if (!direct_p > > > + && (ix86_harden_sls & harden_sls_indirect_branch)) > > > + return "int3"; > > > + } > > > return ""; > > > } > > > > > > diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt > > > index b38ac13fc91..c5452c49597 100644 > > > --- a/gcc/config/i386/i386.opt > > > +++ b/gcc/config/i386/i386.opt > > > @@ -1121,6 +1121,26 @@ mrecord-return > > > Target Var(ix86_flag_record_return) Init(0) > > > Generate a __return_loc section pointing to all return instrumentation code. > > > > > > +mharden-sls= > > > +Target RejectNegative Joined Enum(harden_sls) Var(ix86_harden_sls) Init(harden_sls_none) > > > +Generate code to mitigate against straight line speculation. > > > + > > > +Enum > > > +Name(harden_sls) Type(enum harden_sls) > > > +Known choices for mitigation against straight line speculation with -mharden-sls=: > > > + > > > +EnumValue > > > +Enum(harden_sls) String(none) Value(harden_sls_none) > > > + > > > +EnumValue > > > +Enum(harden_sls) String(all) Value(harden_sls_all) > > > + > > > +EnumValue > > > +Enum(harden_sls) String(return) Value(harden_sls_return) > > > + > > > +EnumValue > > > +Enum(harden_sls) String(indirect-branch) Value(harden_sls_indirect_branch) > > > + > > > mavx512bf16 > > > Target Mask(ISA2_AVX512BF16) Var(ix86_isa_flags2) Save > > > Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and > > > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > > > index 6070288856c..f3b4b467765 100644 > > > --- a/gcc/doc/invoke.texi > > > +++ b/gcc/doc/invoke.texi > > > @@ -1425,7 +1425,7 @@ See RS/6000 and PowerPC Options. > > > -mstack-protector-guard-symbol=@var{symbol} @gol > > > -mgeneral-regs-only -mcall-ms2sysv-xlogues -mrelax-cmpxchg-loop @gol > > > -mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol > > > --mindirect-branch-register -mneeded} > > > +-mindirect-branch-register -mharden-sls=@var{choice} -mneeded} > > > > > > @emph{x86 Windows Options} > > > @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol > > > @@ -32382,6 +32382,14 @@ not be reachable in the large code model. > > > @opindex mindirect-branch-register > > > Force indirect call and jump via register. > > > > > > +@item -mharden-sls=@var{choice} > > > +@opindex mharden-sls > > > +Generate code to mitigate against straight line speculation (SLS) with > > > +@var{choice}. The default is @samp{none} which disables all SLS > > > +hardening. @samp{return} enables SLS hardening for function return. > > > +@samp{indirect-branch} enables SLS hardening for indirect branch. > > > +@samp{all} enables all SLS hardening. > > > + > > > @end table > > > > > > These @samp{-m} switches are supported in addition to the above > > > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-1.c b/gcc/testsuite/gcc.target/i386/harden-sls-1.c > > > new file mode 100644 > > > index 00000000000..6f70dc94a23 > > > --- /dev/null > > > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-1.c > > > @@ -0,0 +1,14 @@ > > > +/* { dg-do compile } */ > > > +/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */ > > > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > > > + > > > +extern void foo (void); > > > + > > > +void > > > +bar (void) > > > +{ > > > + foo (); > > > +} > > > + > > > +/* { dg-final { scan-assembler "jmp\[ \t\]+_?foo" } } */ > > > +/* { dg-final { scan-assembler-not {int3} } } */ > > > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-2.c b/gcc/testsuite/gcc.target/i386/harden-sls-2.c > > > new file mode 100644 > > > index 00000000000..a7c59078d03 > > > --- /dev/null > > > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-2.c > > > @@ -0,0 +1,14 @@ > > > +/* { dg-do compile } */ > > > +/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */ > > > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > > > + > > > +extern void (*fptr) (void); > > > + > > > +void > > > +foo (void) > > > +{ > > > + fptr (); > > > +} > > > + > > > +/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */ > > > +/* { dg-final { scan-assembler-times "int3" 1 } } */ > > > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-3.c b/gcc/testsuite/gcc.target/i386/harden-sls-3.c > > > new file mode 100644 > > > index 00000000000..1a6056b6d7b > > > --- /dev/null > > > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-3.c > > > @@ -0,0 +1,14 @@ > > > +/* { dg-do compile } */ > > > +/* { dg-options "-O2 -mindirect-branch=thunk -mharden-sls=all" } */ > > > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > > > + > > > +extern void (*fptr) (void); > > > + > > > +void > > > +foo (void) > > > +{ > > > + fptr (); > > > +} > > > + > > > +/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */ > > > +/* { dg-final { scan-assembler-times "int3" 2 } } */ > > > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-4.c b/gcc/testsuite/gcc.target/i386/harden-sls-4.c > > > new file mode 100644 > > > index 00000000000..c33147f11b5 > > > --- /dev/null > > > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-4.c > > > @@ -0,0 +1,14 @@ > > > +/* { dg-do compile } */ > > > +/* { dg-options "-O2 -mindirect-branch=keep -mharden-sls=all" } */ > > > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > > > + > > > +extern void (*fptr) (void); > > > + > > > +void > > > +foo (void) > > > +{ > > > + fptr (); > > > +} > > > + > > > +/* { dg-final { scan-assembler "jmp\[ \t\]+\\*_?fptr" } } */ > > > +/* { dg-final { scan-assembler-times "int3" 1 } } */ > > > -- > > > 2.33.1 > > > > > > > -- > H.J.
On Wed, Nov 17, 2021 at 6:08 AM Uros Bizjak <ubizjak@gmail.com> wrote: > > On Wed, Nov 17, 2021 at 2:46 PM H.J. Lu <hjl.tools@gmail.com> wrote: > > > > On Wed, Nov 17, 2021 at 1:05 AM Uros Bizjak <ubizjak@gmail.com> wrote: > > > > > > On Tue, Nov 16, 2021 at 7:20 PM H.J. Lu via Gcc-patches > > > <gcc-patches@gcc.gnu.org> 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/config/i386/i386-opts.h | 7 +++++ > > > > gcc/config/i386/i386.c | 30 ++++++++++++++++---- > > > > 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 | 14 +++++++++ > > > > 8 files changed, 116 insertions(+), 7 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 > > > > > > > > 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 cc9f9322fad..0a902d66321 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. > > > > @@ -15987,6 +15989,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); > > > > @@ -16212,10 +16216,14 @@ ix86_output_indirect_jmp (rtx call_op) > > > > gcc_unreachable (); > > > > > > > > ix86_output_indirect_branch (call_op, "%0", true); > > > > - return ""; > > > > + if ((ix86_harden_sls & harden_sls_indirect_branch)) > > > > + return "int3"; > > > > + else > > > > + return ""; > > > > } > > > > else > > > > - return "%!jmp\t%A0"; > > > > + return ((ix86_harden_sls & harden_sls_indirect_branch) > > > > + ? "%!jmp\t%A0\n\tint3" : "%!jmp\t%A0"); > > > > } > > > > > > Just change existing returns to fputs and end function with: > > > > > > return (ix86_harden_sls & harden_sls_indirect_branch) ? "int3" : ""; > > > > But fputs doesn't support %A0. > > Sorry for the thinko, output_asm_insn instead of fputs will do the trick. Fixed in the v2 patch. Thanks. > Uros. > > > > > > > /* Output return instrumentation for current function if needed. */ > > > > @@ -16283,10 +16291,15 @@ ix86_output_function_return (bool long_p) > > > > return ""; > > > > } > > > > > > > > - if (!long_p) > > > > - return "%!ret"; > > > > + if ((ix86_harden_sls & harden_sls_return)) > > > > + return "%!ret\n\tint3"; > > > > + else > > > > + { > > > > + if (!long_p) > > > > + return "%!ret"; > > > > > > > > - return "rep%; ret"; > > > > + return "rep%; ret"; > > > > + } > > > > } > > > > > > Also here. > > > > But fputs doesn't know "%!". > > > > > > > > > > > > > /* Output indirect function return. RET_OP is the function return > > > > @@ -16381,7 +16394,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) > > > > if (output_indirect_p && !direct_p) > > > > ix86_output_indirect_branch (call_op, xasm, true); > > > > else > > > > - output_asm_insn (xasm, &call_op); > > > > + { > > > > + output_asm_insn (xasm, &call_op); > > > > + if (!direct_p > > > > + && (ix86_harden_sls & harden_sls_indirect_branch)) > > > > + return "int3"; > > > > + } > > > > return ""; > > > > } > > > > > > > > diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt > > > > index b38ac13fc91..c5452c49597 100644 > > > > --- a/gcc/config/i386/i386.opt > > > > +++ b/gcc/config/i386/i386.opt > > > > @@ -1121,6 +1121,26 @@ mrecord-return > > > > Target Var(ix86_flag_record_return) Init(0) > > > > Generate a __return_loc section pointing to all return instrumentation code. > > > > > > > > +mharden-sls= > > > > +Target RejectNegative Joined Enum(harden_sls) Var(ix86_harden_sls) Init(harden_sls_none) > > > > +Generate code to mitigate against straight line speculation. > > > > + > > > > +Enum > > > > +Name(harden_sls) Type(enum harden_sls) > > > > +Known choices for mitigation against straight line speculation with -mharden-sls=: > > > > + > > > > +EnumValue > > > > +Enum(harden_sls) String(none) Value(harden_sls_none) > > > > + > > > > +EnumValue > > > > +Enum(harden_sls) String(all) Value(harden_sls_all) > > > > + > > > > +EnumValue > > > > +Enum(harden_sls) String(return) Value(harden_sls_return) > > > > + > > > > +EnumValue > > > > +Enum(harden_sls) String(indirect-branch) Value(harden_sls_indirect_branch) > > > > + > > > > mavx512bf16 > > > > Target Mask(ISA2_AVX512BF16) Var(ix86_isa_flags2) Save > > > > Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and > > > > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi > > > > index 6070288856c..f3b4b467765 100644 > > > > --- a/gcc/doc/invoke.texi > > > > +++ b/gcc/doc/invoke.texi > > > > @@ -1425,7 +1425,7 @@ See RS/6000 and PowerPC Options. > > > > -mstack-protector-guard-symbol=@var{symbol} @gol > > > > -mgeneral-regs-only -mcall-ms2sysv-xlogues -mrelax-cmpxchg-loop @gol > > > > -mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol > > > > --mindirect-branch-register -mneeded} > > > > +-mindirect-branch-register -mharden-sls=@var{choice} -mneeded} > > > > > > > > @emph{x86 Windows Options} > > > > @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol > > > > @@ -32382,6 +32382,14 @@ not be reachable in the large code model. > > > > @opindex mindirect-branch-register > > > > Force indirect call and jump via register. > > > > > > > > +@item -mharden-sls=@var{choice} > > > > +@opindex mharden-sls > > > > +Generate code to mitigate against straight line speculation (SLS) with > > > > +@var{choice}. The default is @samp{none} which disables all SLS > > > > +hardening. @samp{return} enables SLS hardening for function return. > > > > +@samp{indirect-branch} enables SLS hardening for indirect branch. > > > > +@samp{all} enables all SLS hardening. > > > > + > > > > @end table > > > > > > > > These @samp{-m} switches are supported in addition to the above > > > > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-1.c b/gcc/testsuite/gcc.target/i386/harden-sls-1.c > > > > new file mode 100644 > > > > index 00000000000..6f70dc94a23 > > > > --- /dev/null > > > > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-1.c > > > > @@ -0,0 +1,14 @@ > > > > +/* { dg-do compile } */ > > > > +/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */ > > > > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > > > > + > > > > +extern void foo (void); > > > > + > > > > +void > > > > +bar (void) > > > > +{ > > > > + foo (); > > > > +} > > > > + > > > > +/* { dg-final { scan-assembler "jmp\[ \t\]+_?foo" } } */ > > > > +/* { dg-final { scan-assembler-not {int3} } } */ > > > > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-2.c b/gcc/testsuite/gcc.target/i386/harden-sls-2.c > > > > new file mode 100644 > > > > index 00000000000..a7c59078d03 > > > > --- /dev/null > > > > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-2.c > > > > @@ -0,0 +1,14 @@ > > > > +/* { dg-do compile } */ > > > > +/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */ > > > > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > > > > + > > > > +extern void (*fptr) (void); > > > > + > > > > +void > > > > +foo (void) > > > > +{ > > > > + fptr (); > > > > +} > > > > + > > > > +/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */ > > > > +/* { dg-final { scan-assembler-times "int3" 1 } } */ > > > > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-3.c b/gcc/testsuite/gcc.target/i386/harden-sls-3.c > > > > new file mode 100644 > > > > index 00000000000..1a6056b6d7b > > > > --- /dev/null > > > > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-3.c > > > > @@ -0,0 +1,14 @@ > > > > +/* { dg-do compile } */ > > > > +/* { dg-options "-O2 -mindirect-branch=thunk -mharden-sls=all" } */ > > > > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > > > > + > > > > +extern void (*fptr) (void); > > > > + > > > > +void > > > > +foo (void) > > > > +{ > > > > + fptr (); > > > > +} > > > > + > > > > +/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */ > > > > +/* { dg-final { scan-assembler-times "int3" 2 } } */ > > > > diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-4.c b/gcc/testsuite/gcc.target/i386/harden-sls-4.c > > > > new file mode 100644 > > > > index 00000000000..c33147f11b5 > > > > --- /dev/null > > > > +++ b/gcc/testsuite/gcc.target/i386/harden-sls-4.c > > > > @@ -0,0 +1,14 @@ > > > > +/* { dg-do compile } */ > > > > +/* { dg-options "-O2 -mindirect-branch=keep -mharden-sls=all" } */ > > > > +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ > > > > + > > > > +extern void (*fptr) (void); > > > > + > > > > +void > > > > +foo (void) > > > > +{ > > > > + fptr (); > > > > +} > > > > + > > > > +/* { dg-final { scan-assembler "jmp\[ \t\]+\\*_?fptr" } } */ > > > > +/* { dg-final { scan-assembler-times "int3" 1 } } */ > > > > -- > > > > 2.33.1 > > > > > > > > > > > > -- > > H.J.
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 cc9f9322fad..0a902d66321 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. @@ -15987,6 +15989,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); @@ -16212,10 +16216,14 @@ ix86_output_indirect_jmp (rtx call_op) gcc_unreachable (); ix86_output_indirect_branch (call_op, "%0", true); - return ""; + if ((ix86_harden_sls & harden_sls_indirect_branch)) + return "int3"; + else + return ""; } else - return "%!jmp\t%A0"; + return ((ix86_harden_sls & harden_sls_indirect_branch) + ? "%!jmp\t%A0\n\tint3" : "%!jmp\t%A0"); } /* Output return instrumentation for current function if needed. */ @@ -16283,10 +16291,15 @@ ix86_output_function_return (bool long_p) return ""; } - if (!long_p) - return "%!ret"; + if ((ix86_harden_sls & harden_sls_return)) + return "%!ret\n\tint3"; + else + { + if (!long_p) + return "%!ret"; - return "rep%; ret"; + return "rep%; ret"; + } } /* Output indirect function return. RET_OP is the function return @@ -16381,7 +16394,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) if (output_indirect_p && !direct_p) ix86_output_indirect_branch (call_op, xasm, true); else - output_asm_insn (xasm, &call_op); + { + output_asm_insn (xasm, &call_op); + if (!direct_p + && (ix86_harden_sls & harden_sls_indirect_branch)) + return "int3"; + } return ""; } diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index b38ac13fc91..c5452c49597 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -1121,6 +1121,26 @@ mrecord-return Target Var(ix86_flag_record_return) Init(0) Generate a __return_loc section pointing to all return instrumentation code. +mharden-sls= +Target RejectNegative Joined Enum(harden_sls) Var(ix86_harden_sls) Init(harden_sls_none) +Generate code to mitigate against straight line speculation. + +Enum +Name(harden_sls) Type(enum harden_sls) +Known choices for mitigation against straight line speculation with -mharden-sls=: + +EnumValue +Enum(harden_sls) String(none) Value(harden_sls_none) + +EnumValue +Enum(harden_sls) String(all) Value(harden_sls_all) + +EnumValue +Enum(harden_sls) String(return) Value(harden_sls_return) + +EnumValue +Enum(harden_sls) String(indirect-branch) Value(harden_sls_indirect_branch) + mavx512bf16 Target Mask(ISA2_AVX512BF16) Var(ix86_isa_flags2) Save Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 6070288856c..f3b4b467765 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1425,7 +1425,7 @@ See RS/6000 and PowerPC Options. -mstack-protector-guard-symbol=@var{symbol} @gol -mgeneral-regs-only -mcall-ms2sysv-xlogues -mrelax-cmpxchg-loop @gol -mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol --mindirect-branch-register -mneeded} +-mindirect-branch-register -mharden-sls=@var{choice} -mneeded} @emph{x86 Windows Options} @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol @@ -32382,6 +32382,14 @@ not be reachable in the large code model. @opindex mindirect-branch-register Force indirect call and jump via register. +@item -mharden-sls=@var{choice} +@opindex mharden-sls +Generate code to mitigate against straight line speculation (SLS) with +@var{choice}. The default is @samp{none} which disables all SLS +hardening. @samp{return} enables SLS hardening for function return. +@samp{indirect-branch} enables SLS hardening for indirect branch. +@samp{all} enables all SLS hardening. + @end table These @samp{-m} switches are supported in addition to the above diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-1.c b/gcc/testsuite/gcc.target/i386/harden-sls-1.c new file mode 100644 index 00000000000..6f70dc94a23 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/harden-sls-1.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */ +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ + +extern void foo (void); + +void +bar (void) +{ + foo (); +} + +/* { dg-final { scan-assembler "jmp\[ \t\]+_?foo" } } */ +/* { dg-final { scan-assembler-not {int3} } } */ diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-2.c b/gcc/testsuite/gcc.target/i386/harden-sls-2.c new file mode 100644 index 00000000000..a7c59078d03 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/harden-sls-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */ +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ + +extern void (*fptr) (void); + +void +foo (void) +{ + fptr (); +} + +/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */ +/* { dg-final { scan-assembler-times "int3" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-3.c b/gcc/testsuite/gcc.target/i386/harden-sls-3.c new file mode 100644 index 00000000000..1a6056b6d7b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/harden-sls-3.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk -mharden-sls=all" } */ +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ + +extern void (*fptr) (void); + +void +foo (void) +{ + fptr (); +} + +/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */ +/* { dg-final { scan-assembler-times "int3" 2 } } */ diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-4.c b/gcc/testsuite/gcc.target/i386/harden-sls-4.c new file mode 100644 index 00000000000..c33147f11b5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/harden-sls-4.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=keep -mharden-sls=all" } */ +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ + +extern void (*fptr) (void); + +void +foo (void) +{ + fptr (); +} + +/* { dg-final { scan-assembler "jmp\[ \t\]+\\*_?fptr" } } */ +/* { dg-final { scan-assembler-times "int3" 1 } } */