diff --git a/SOURCES/gcc8-harden-1.patch b/SOURCES/gcc8-harden-1.patch new file mode 100644 index 0000000..a325c09 --- /dev/null +++ b/SOURCES/gcc8-harden-1.patch @@ -0,0 +1,294 @@ +From 88bf1c3910e4cf97dcb85c6d32291c23e572a516 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 27 Oct 2021 07:48:54 -0700 +Subject: [PATCH 1/4] x86: Add -mharden-sls=[none|all|return|indirect-branch] + +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. + +(cherry picked from commit 53a643f8568067d7700a9f2facc8ba39974973d3) +--- + gcc/config/i386/i386-opts.h | 7 +++++++ + gcc/config/i386/i386.c | 22 +++++++++++++++----- + 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, 128 insertions(+), 6 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 46366cbfa72..34718b6d52c 100644 +--- a/gcc/config/i386/i386-opts.h ++++ b/gcc/config/i386/i386-opts.h +@@ -119,4 +119,11 @@ enum indirect_branch { + indirect_branch_thunk_extern + }; + ++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 31502774ef3..eb9303f8742 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -10977,6 +10977,9 @@ output_indirect_thunk (enum indirect_thunk_prefix need_prefix, + fputs ("\tbnd ret\n", asm_out_file); + else + 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. +@@ -28728,6 +28731,8 @@ ix86_output_jmp_thunk_or_indirect (const char *thunk_name, + 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 (need_prefix, regno); +@@ -28973,10 +28978,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 function return. CALL_OP is the jump target. Add a REP +@@ -29018,9 +29023,11 @@ ix86_output_function_return (bool long_p) + } + + if (!long_p || ix86_bnd_prefixed_insn_p (current_output_insn)) +- return "%!ret"; ++ output_asm_insn ("%!ret", NULL); ++ else ++ output_asm_insn ("rep%; ret", NULL); + +- return "rep%; ret"; ++ return (ix86_harden_sls & harden_sls_return) ? "int3" : ""; + } + + /* Output indirect function return. RET_OP is the function return +@@ -29158,7 +29165,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 d9bd909a885..3ae48609e25 100644 +--- a/gcc/config/i386/i386.opt ++++ b/gcc/config/i386/i386.opt +@@ -1055,3 +1055,23 @@ Support MOVDIRI built-in functions and code generation. + mmovdir64b + Target Report Mask(ISA_MOVDIR64B) Var(ix86_isa_flags2) Save + Support MOVDIR64B built-in functions and code generation. ++ ++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(return) Value(harden_sls_return) ++ ++EnumValue ++Enum(harden_sls) String(indirect-branch) Value(harden_sls_indirect_branch) ++ ++EnumValue ++Enum(harden_sls) String(all) Value(harden_sls_all) +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 78ca7738df2..1e20efd6969 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -1284,7 +1284,7 @@ See RS/6000 and PowerPC Options. + -mstack-protector-guard-symbol=@var{symbol} -mmitigate-rop @gol + -mgeneral-regs-only -mcall-ms2sysv-xlogues @gol + -mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol +--mindirect-branch-register} ++-mindirect-branch-register -mharden-sls=@var{choice}} + + @emph{x86 Windows Options} + @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol +@@ -28036,6 +28036,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..f70dd1379d3 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/harden-sls-4.c +@@ -0,0 +1,16 @@ ++/* { 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" { target { ! x32 } } } } */ ++/* { dg-final { scan-assembler "movl\[ \t\]+fptr\\(%rip\\), %eax" { target x32 } } } */ ++/* { dg-final { scan-assembler "jmp\[ \t\]+\\*%rax" { target x32 } } } */ ++/* { dg-final { scan-assembler-times "int3" 1 } } */ +diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-5.c b/gcc/testsuite/gcc.target/i386/harden-sls-5.c +new file mode 100644 +index 00000000000..613c44c6f82 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/harden-sls-5.c +@@ -0,0 +1,17 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -mharden-sls=return" } */ ++/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ ++ ++typedef void (*dispatch_t)(long offset); ++ ++dispatch_t dispatch; ++ ++int ++male_indirect_jump (long offset) ++{ ++ dispatch(offset); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler-times "ret" 1 } } */ ++/* { dg-final { scan-assembler-times "int3" 1 } } */ +-- +2.36.1 + diff --git a/SOURCES/gcc8-harden-2.patch b/SOURCES/gcc8-harden-2.patch new file mode 100644 index 0000000..669c11f --- /dev/null +++ b/SOURCES/gcc8-harden-2.patch @@ -0,0 +1,155 @@ +From 0df8313a0a5d8533f2487e21d7b42e9adee28f18 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 27 Oct 2021 06:27:15 -0700 +Subject: [PATCH 2/4] x86: Add -mindirect-branch-cs-prefix + +Add -mindirect-branch-cs-prefix to add CS prefix to call and jmp to +indirect thunk with branch target in r8-r15 registers so that the call +and jmp instruction length is 6 bytes to allow them to be replaced with +"lfence; call *%r8-r15" or "lfence; jmp *%r8-r15" at run-time. + +gcc/ + + PR target/102952 + * config/i386/i386.c (ix86_output_jmp_thunk_or_indirect): Emit + CS prefix for -mindirect-branch-cs-prefix. + (ix86_output_indirect_branch_via_reg): Likewise. + * config/i386/i386.opt: Add -mindirect-branch-cs-prefix. + * doc/invoke.texi: Document -mindirect-branch-cs-prefix. + +gcc/testsuite/ + + PR target/102952 + * gcc.target/i386/indirect-thunk-cs-prefix-1.c: New test. + * gcc.target/i386/indirect-thunk-cs-prefix-2.c: Likewise. + +(cherry picked from commit 2196a681d7810ad8b227bf983f38ba716620545e) +--- + gcc/config/i386/i386.c | 14 ++++++++++++-- + gcc/config/i386/i386.opt | 4 ++++ + gcc/doc/invoke.texi | 10 +++++++++- + .../gcc.target/i386/indirect-thunk-cs-prefix-1.c | 14 ++++++++++++++ + .../gcc.target/i386/indirect-thunk-cs-prefix-2.c | 15 +++++++++++++++ + 5 files changed, 54 insertions(+), 3 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-1.c + create mode 100644 gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-2.c + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index eb9303f8742..8442dd0daea 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -28728,7 +28728,12 @@ ix86_output_jmp_thunk_or_indirect (const char *thunk_name, + if (need_prefix == indirect_thunk_prefix_bnd) + fprintf (asm_out_file, "\tbnd jmp\t"); + else +- fprintf (asm_out_file, "\tjmp\t"); ++ { ++ if (REX_INT_REGNO_P (regno) ++ && ix86_indirect_branch_cs_prefix) ++ fprintf (asm_out_file, "\tcs\n"); ++ 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)) +@@ -28787,7 +28792,12 @@ ix86_output_indirect_branch_via_reg (rtx call_op, bool sibcall_p) + if (need_prefix == indirect_thunk_prefix_bnd) + fprintf (asm_out_file, "\tbnd call\t"); + else +- fprintf (asm_out_file, "\tcall\t"); ++ { ++ if (REX_INT_REGNO_P (regno) ++ && ix86_indirect_branch_cs_prefix) ++ fprintf (asm_out_file, "\tcs\n"); ++ fprintf (asm_out_file, "\tcall\t"); ++ } + assemble_name (asm_out_file, thunk_name); + putc ('\n', asm_out_file); + return; +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt +index 3ae48609e25..9f67ef558dc 100644 +--- a/gcc/config/i386/i386.opt ++++ b/gcc/config/i386/i386.opt +@@ -1044,6 +1044,10 @@ Enum(indirect_branch) String(thunk-inline) Value(indirect_branch_thunk_inline) + EnumValue + Enum(indirect_branch) String(thunk-extern) Value(indirect_branch_thunk_extern) + ++mindirect-branch-cs-prefix ++Target Var(ix86_indirect_branch_cs_prefix) Init(0) ++Add CS prefix to call and jmp to indirect thunk with branch target in r8-r15 registers. ++ + mindirect-branch-register + Target Report Var(ix86_indirect_branch_register) Init(0) + Force indirect call and jump via register. +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 1e20efd6969..605cd4b93f1 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -1284,7 +1284,8 @@ See RS/6000 and PowerPC Options. + -mstack-protector-guard-symbol=@var{symbol} -mmitigate-rop @gol + -mgeneral-regs-only -mcall-ms2sysv-xlogues @gol + -mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol +--mindirect-branch-register -mharden-sls=@var{choice}} ++-mindirect-branch-register -mharden-sls=@var{choice} @gol ++-mindirect-branch-cs-prefix} + + @emph{x86 Windows Options} + @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol +@@ -28044,6 +28045,13 @@ hardening. @samp{return} enables SLS hardening for function return. + @samp{indirect-branch} enables SLS hardening for indirect branch. + @samp{all} enables all SLS hardening. + ++@item -mindirect-branch-cs-prefix ++@opindex mindirect-branch-cs-prefix ++Add CS prefix to call and jmp to indirect thunk with branch target in ++r8-r15 registers so that the call and jmp instruction length is 6 bytes ++to allow them to be replaced with @samp{lfence; call *%r8-r15} or ++@samp{lfence; jmp *%r8-r15} at run-time. ++ + @end table + + These @samp{-m} switches are supported in addition to the above +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-1.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-1.c +new file mode 100644 +index 00000000000..db2f3416823 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-1.c +@@ -0,0 +1,14 @@ ++/* { dg-do compile { target { ! ia32 } } } */ ++/* { dg-options "-O2 -ffixed-rax -ffixed-rbx -ffixed-rcx -ffixed-rdx -ffixed-rdi -ffixed-rsi -mindirect-branch-cs-prefix -mindirect-branch=thunk-extern" } */ ++/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ ++ ++extern void (*fptr) (void); ++ ++void ++foo (void) ++{ ++ fptr (); ++} ++ ++/* { dg-final { scan-assembler-times "jmp\[ \t\]+_?__x86_indirect_thunk_r\[0-9\]+" 1 } } */ ++/* { dg-final { scan-assembler-times "\tcs" 1 } } */ +diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-2.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-2.c +new file mode 100644 +index 00000000000..adfc39a49d4 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-cs-prefix-2.c +@@ -0,0 +1,15 @@ ++/* { dg-do compile { target { ! ia32 } } } */ ++/* { dg-options "-O2 -ffixed-rax -ffixed-rbx -ffixed-rcx -ffixed-rdx -ffixed-rdi -ffixed-rsi -mindirect-branch-cs-prefix -mindirect-branch=thunk-extern" } */ ++/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ ++ ++extern void (*bar) (void); ++ ++int ++foo (void) ++{ ++ bar (); ++ return 0; ++} ++ ++/* { dg-final { scan-assembler-times "call\[ \t\]+_?__x86_indirect_thunk_r\[0-9\]+" 1 } } */ ++/* { dg-final { scan-assembler-times "\tcs" 1 } } */ +-- +2.36.1 + diff --git a/SOURCES/gcc8-harden-3.patch b/SOURCES/gcc8-harden-3.patch new file mode 100644 index 0000000..ecb643a --- /dev/null +++ b/SOURCES/gcc8-harden-3.patch @@ -0,0 +1,108 @@ +From 621de498ee19e1f2642eebde707430254c0459c0 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 5 Jan 2022 16:33:16 -0800 +Subject: [PATCH 3/4] x86: Rename -harden-sls=indirect-branch to + -harden-sls=indirect-jmp + +Indirect branch also includes indirect call instructions. Rename +-harden-sls=indirect-branch to -harden-sls=indirect-jmp to match its +intended behavior. + + PR target/102952 + * config/i386/i386-opts.h (harden_sls): Replace + harden_sls_indirect_branch with harden_sls_indirect_jmp. + * config/i386/i386.c (ix86_output_jmp_thunk_or_indirect): + Likewise. + (ix86_output_indirect_jmp): Likewise. + (ix86_output_call_insn): Likewise. + * config/i386/i386.opt: Replace indirect-branch with + indirect-jmp. Replace harden_sls_indirect_branch with + harden_sls_indirect_jmp. + * doc/invoke.texi (-harden-sls=): Replace indirect-branch with + indirect-jmp. + +(cherry picked from commit ed8060950c64f2e449aaf90e438aa26d0d9d0b31) +--- + gcc/config/i386/i386-opts.h | 4 ++-- + gcc/config/i386/i386.c | 6 +++--- + gcc/config/i386/i386.opt | 2 +- + gcc/doc/invoke.texi | 4 ++-- + 4 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h +index 34718b6d52c..47facc254cd 100644 +--- a/gcc/config/i386/i386-opts.h ++++ b/gcc/config/i386/i386-opts.h +@@ -122,8 +122,8 @@ enum indirect_branch { + 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 ++ harden_sls_indirect_jmp = 1 << 1, ++ harden_sls_all = harden_sls_return | harden_sls_indirect_jmp + }; + + #endif +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index 8442dd0daea..3bc14e20105 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -28736,7 +28736,7 @@ ix86_output_jmp_thunk_or_indirect (const char *thunk_name, + } + assemble_name (asm_out_file, thunk_name); + putc ('\n', asm_out_file); +- if ((ix86_harden_sls & harden_sls_indirect_branch)) ++ if ((ix86_harden_sls & harden_sls_indirect_jmp)) + fputs ("\tint3\n", asm_out_file); + } + else +@@ -28991,7 +28991,7 @@ ix86_output_indirect_jmp (rtx call_op) + } + else + output_asm_insn ("%!jmp\t%A0", &call_op); +- return (ix86_harden_sls & harden_sls_indirect_branch) ? "int3" : ""; ++ return (ix86_harden_sls & harden_sls_indirect_jmp) ? "int3" : ""; + } + + /* Output function return. CALL_OP is the jump target. Add a REP +@@ -29178,7 +29178,7 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) + { + output_asm_insn (xasm, &call_op); + if (!direct_p +- && (ix86_harden_sls & harden_sls_indirect_branch)) ++ && (ix86_harden_sls & harden_sls_indirect_jmp)) + return "int3"; + } + return ""; +diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt +index 9f67ef558dc..7a5c7b9369a 100644 +--- a/gcc/config/i386/i386.opt ++++ b/gcc/config/i386/i386.opt +@@ -1075,7 +1075,7 @@ EnumValue + Enum(harden_sls) String(return) Value(harden_sls_return) + + EnumValue +-Enum(harden_sls) String(indirect-branch) Value(harden_sls_indirect_branch) ++Enum(harden_sls) String(indirect-jmp) Value(harden_sls_indirect_jmp) + + EnumValue + Enum(harden_sls) String(all) Value(harden_sls_all) +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 605cd4b93f1..20d8e3fd782 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -28041,8 +28041,8 @@ Force indirect call and jump via register. + @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. ++hardening. @samp{return} enables SLS hardening for function returns. ++@samp{indirect-jmp} enables SLS hardening for indirect jumps. + @samp{all} enables all SLS hardening. + + @item -mindirect-branch-cs-prefix +-- +2.36.1 + diff --git a/SOURCES/gcc8-harden-4.patch b/SOURCES/gcc8-harden-4.patch new file mode 100644 index 0000000..648d543 --- /dev/null +++ b/SOURCES/gcc8-harden-4.patch @@ -0,0 +1,75 @@ +From 5a5e7890cefa112e95e1de9800d8081c2a38a1da Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 5 Jan 2022 18:04:21 -0800 +Subject: [PATCH 4/4] x86: Generate INT3 for __builtin_eh_return + +Generate INT3 after indirect jmp in exception return for -fcf-protection +with -mharden-sls=indirect-jmp. + +gcc/ + + PR target/103925 + * config/i386/i386.c (ix86_output_indirect_function_return): + Generate INT3 after indirect jmp for -mharden-sls=indirect-jmp. + +gcc/testsuite/ + + PR target/103925 + * gcc.target/i386/harden-sls-6.c: New test. + +(cherry picked from commit c2e5c4feed32c808591b5278f680bbabe63eb225) +--- + gcc/config/i386/i386.c | 9 ++++++--- + gcc/testsuite/gcc.target/i386/harden-sls-6.c | 18 ++++++++++++++++++ + 2 files changed, 24 insertions(+), 3 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-6.c + +diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c +index 3bc14e20105..dbc3d462fda 100644 +--- a/gcc/config/i386/i386.c ++++ b/gcc/config/i386/i386.c +@@ -29083,11 +29083,14 @@ ix86_output_indirect_function_return (rtx ret_op) + } + else + output_indirect_thunk (need_prefix, regno); +- +- return ""; + } + else +- return "%!jmp\t%A0"; ++ { ++ output_asm_insn ("%!jmp\t%A0", &ret_op); ++ if (ix86_harden_sls & harden_sls_indirect_jmp) ++ fputs ("\tint3\n", asm_out_file); ++ } ++ return ""; + } + + /* Split simple return with popping POPC bytes from stack to indirect +diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-6.c b/gcc/testsuite/gcc.target/i386/harden-sls-6.c +new file mode 100644 +index 00000000000..9068eb64008 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/i386/harden-sls-6.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile { target { ! ia32 } } } */ ++/* { dg-options "-O2 -fcf-protection -mharden-sls=indirect-jmp" } */ ++ ++struct _Unwind_Context _Unwind_Resume_or_Rethrow_this_context; ++ ++void offset (int); ++ ++struct _Unwind_Context { ++ void *reg[7]; ++} _Unwind_Resume_or_Rethrow() { ++ struct _Unwind_Context cur_contextcur_context = ++ _Unwind_Resume_or_Rethrow_this_context; ++ offset(0); ++ __builtin_eh_return ((long) offset, 0); ++} ++ ++/* { dg-final { scan-assembler "jmp\[ \t\]+\\*%rcx" } } */ ++/* { dg-final { scan-assembler-times "int3" 1 } } */ +-- +2.36.1 + diff --git a/SPECS/gcc.spec b/SPECS/gcc.spec index b37c765..c87b4c9 100644 --- a/SPECS/gcc.spec +++ b/SPECS/gcc.spec @@ -4,7 +4,7 @@ %global gcc_major 8 # Note, gcc_release must be integer, if you want to add suffixes to # %%{release}, append them after %%{gcc_release} on Release: line. -%global gcc_release 14 +%global gcc_release 15 %global nvptx_tools_gitrev c28050f60193b3b95a18866a96f03334e874e78f %global nvptx_newlib_gitrev aadc8eb0ec43b7cd0dd2dfb484bae63c8b05ef24 %global _unpackaged_files_terminate_build 0 @@ -290,6 +290,10 @@ Patch28: gcc8-rh2001788.patch Patch30: gcc8-rh1668903-1.patch Patch31: gcc8-rh1668903-2.patch Patch32: gcc8-rh1668903-3.patch +Patch33: gcc8-harden-1.patch +Patch34: gcc8-harden-2.patch +Patch35: gcc8-harden-3.patch +Patch36: gcc8-harden-4.patch Patch1000: nvptx-tools-no-ptxas.patch Patch1001: nvptx-tools-build.patch @@ -896,6 +900,10 @@ so that there cannot be any synchronization problems. %patch30 -p0 -b .rh1668903-1~ %patch31 -p0 -b .rh1668903-2~ %patch32 -p0 -b .rh1668903-3~ +%patch33 -p1 -b .harden-1~ +%patch34 -p1 -b .harden-2~ +%patch35 -p1 -b .harden-3~ +%patch36 -p1 -b .harden-4~ cd nvptx-tools-%{nvptx_tools_gitrev} %patch1000 -p1 -b .nvptx-tools-no-ptxas~ @@ -3303,6 +3311,9 @@ fi %{ANNOBIN_GCC_PLUGIN_DIR}/gcc-annobin.so.0.0.0 %changelog +* Wed Jul 20 2022 Marek Polacek 8.5.0-15 +- backport straight-line-speculation mitigation (#2108721) + * Fri Jul 8 2022 Jonathan Wakely 8.5.0-14 - backport std::regex check for invalid range (#2001788)