Blame SOURCES/gcc8-harden-1.patch

6d6b46
From 88bf1c3910e4cf97dcb85c6d32291c23e572a516 Mon Sep 17 00:00:00 2001
6d6b46
From: "H.J. Lu" <hjl.tools@gmail.com>
6d6b46
Date: Wed, 27 Oct 2021 07:48:54 -0700
6d6b46
Subject: [PATCH 1/4] x86: Add -mharden-sls=[none|all|return|indirect-branch]
6d6b46
6d6b46
Add -mharden-sls= to mitigate against straight line speculation (SLS)
6d6b46
for function return and indirect branch by adding an INT3 instruction
6d6b46
after function return and indirect branch.
6d6b46
6d6b46
gcc/
6d6b46
6d6b46
	PR target/102952
6d6b46
	* config/i386/i386-opts.h (harden_sls): New enum.
6d6b46
	* config/i386/i386.c (output_indirect_thunk): Mitigate against
6d6b46
	SLS for function return.
6d6b46
	(ix86_output_function_return): Likewise.
6d6b46
	(ix86_output_jmp_thunk_or_indirect): Mitigate against indirect
6d6b46
	branch.
6d6b46
	(ix86_output_indirect_jmp): Likewise.
6d6b46
	(ix86_output_call_insn): Likewise.
6d6b46
	* config/i386/i386.opt: Add -mharden-sls=.
6d6b46
	* doc/invoke.texi: Document -mharden-sls=.
6d6b46
6d6b46
gcc/testsuite/
6d6b46
6d6b46
	PR target/102952
6d6b46
	* gcc.target/i386/harden-sls-1.c: New test.
6d6b46
	* gcc.target/i386/harden-sls-2.c: Likewise.
6d6b46
	* gcc.target/i386/harden-sls-3.c: Likewise.
6d6b46
	* gcc.target/i386/harden-sls-4.c: Likewise.
6d6b46
	* gcc.target/i386/harden-sls-5.c: Likewise.
6d6b46
6d6b46
(cherry picked from commit 53a643f8568067d7700a9f2facc8ba39974973d3)
6d6b46
---
6d6b46
 gcc/config/i386/i386-opts.h                  |  7 +++++++
6d6b46
 gcc/config/i386/i386.c                       | 22 +++++++++++++++-----
6d6b46
 gcc/config/i386/i386.opt                     | 20 ++++++++++++++++++
6d6b46
 gcc/doc/invoke.texi                          | 10 ++++++++-
6d6b46
 gcc/testsuite/gcc.target/i386/harden-sls-1.c | 14 +++++++++++++
6d6b46
 gcc/testsuite/gcc.target/i386/harden-sls-2.c | 14 +++++++++++++
6d6b46
 gcc/testsuite/gcc.target/i386/harden-sls-3.c | 14 +++++++++++++
6d6b46
 gcc/testsuite/gcc.target/i386/harden-sls-4.c | 16 ++++++++++++++
6d6b46
 gcc/testsuite/gcc.target/i386/harden-sls-5.c | 17 +++++++++++++++
6d6b46
 9 files changed, 128 insertions(+), 6 deletions(-)
6d6b46
 create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-1.c
6d6b46
 create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-2.c
6d6b46
 create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-3.c
6d6b46
 create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-4.c
6d6b46
 create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-5.c
6d6b46
6d6b46
diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h
6d6b46
index 46366cbfa72..34718b6d52c 100644
6d6b46
--- a/gcc/config/i386/i386-opts.h
6d6b46
+++ b/gcc/config/i386/i386-opts.h
6d6b46
@@ -119,4 +119,11 @@ enum indirect_branch {
6d6b46
   indirect_branch_thunk_extern
6d6b46
 };
6d6b46
 
6d6b46
+enum harden_sls {
6d6b46
+  harden_sls_none = 0,
6d6b46
+  harden_sls_return = 1 << 0,
6d6b46
+  harden_sls_indirect_branch = 1 << 1,
6d6b46
+  harden_sls_all = harden_sls_return | harden_sls_indirect_branch
6d6b46
+};
6d6b46
+
6d6b46
 #endif
6d6b46
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
6d6b46
index 31502774ef3..eb9303f8742 100644
6d6b46
--- a/gcc/config/i386/i386.c
6d6b46
+++ b/gcc/config/i386/i386.c
6d6b46
@@ -10977,6 +10977,9 @@ output_indirect_thunk (enum indirect_thunk_prefix need_prefix,
6d6b46
     fputs ("\tbnd ret\n", asm_out_file);
6d6b46
   else
6d6b46
     fputs ("\tret\n", asm_out_file);
6d6b46
+
6d6b46
+  if ((ix86_harden_sls & harden_sls_return))
6d6b46
+    fputs ("\tint3\n", asm_out_file);
6d6b46
 }
6d6b46
 
6d6b46
 /* Output a funtion with a call and return thunk for indirect branch.
6d6b46
@@ -28728,6 +28731,8 @@ ix86_output_jmp_thunk_or_indirect (const char *thunk_name,
6d6b46
 	fprintf (asm_out_file, "\tjmp\t");
6d6b46
       assemble_name (asm_out_file, thunk_name);
6d6b46
       putc ('\n', asm_out_file);
6d6b46
+      if ((ix86_harden_sls & harden_sls_indirect_branch))
6d6b46
+	fputs ("\tint3\n", asm_out_file);
6d6b46
     }
6d6b46
   else
6d6b46
     output_indirect_thunk (need_prefix, regno);
6d6b46
@@ -28973,10 +28978,10 @@ ix86_output_indirect_jmp (rtx call_op)
6d6b46
 	gcc_unreachable ();
6d6b46
 
6d6b46
       ix86_output_indirect_branch (call_op, "%0", true);
6d6b46
-      return "";
6d6b46
     }
6d6b46
   else
6d6b46
-    return "%!jmp\t%A0";
6d6b46
+    output_asm_insn ("%!jmp\t%A0", &call_op);
6d6b46
+  return (ix86_harden_sls & harden_sls_indirect_branch) ? "int3" : "";
6d6b46
 }
6d6b46
 
6d6b46
 /* Output function return.  CALL_OP is the jump target.  Add a REP
6d6b46
@@ -29018,9 +29023,11 @@ ix86_output_function_return (bool long_p)
6d6b46
     }
6d6b46
 
6d6b46
   if (!long_p || ix86_bnd_prefixed_insn_p (current_output_insn))
6d6b46
-    return "%!ret";
6d6b46
+    output_asm_insn ("%!ret", NULL);
6d6b46
+  else
6d6b46
+    output_asm_insn ("rep%; ret", NULL);
6d6b46
 
6d6b46
-  return "rep%; ret";
6d6b46
+  return (ix86_harden_sls & harden_sls_return) ? "int3" : "";
6d6b46
 }
6d6b46
 
6d6b46
 /* Output indirect function return.  RET_OP is the function return
6d6b46
@@ -29158,7 +29165,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op)
6d6b46
       if (output_indirect_p && !direct_p)
6d6b46
 	ix86_output_indirect_branch (call_op, xasm, true);
6d6b46
       else
6d6b46
-	output_asm_insn (xasm, &call_op);
6d6b46
+	{
6d6b46
+	  output_asm_insn (xasm, &call_op);
6d6b46
+	  if (!direct_p
6d6b46
+	      && (ix86_harden_sls & harden_sls_indirect_branch))
6d6b46
+	    return "int3";
6d6b46
+	}
6d6b46
       return "";
6d6b46
     }
6d6b46
 
6d6b46
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
6d6b46
index d9bd909a885..3ae48609e25 100644
6d6b46
--- a/gcc/config/i386/i386.opt
6d6b46
+++ b/gcc/config/i386/i386.opt
6d6b46
@@ -1055,3 +1055,23 @@ Support MOVDIRI built-in functions and code generation.
6d6b46
 mmovdir64b
6d6b46
 Target Report Mask(ISA_MOVDIR64B) Var(ix86_isa_flags2) Save
6d6b46
 Support MOVDIR64B built-in functions and code generation.
6d6b46
+
6d6b46
+mharden-sls=
6d6b46
+Target RejectNegative Joined Enum(harden_sls) Var(ix86_harden_sls) Init(harden_sls_none)
6d6b46
+Generate code to mitigate against straight line speculation.
6d6b46
+
6d6b46
+Enum
6d6b46
+Name(harden_sls) Type(enum harden_sls)
6d6b46
+Known choices for mitigation against straight line speculation with -mharden-sls=:
6d6b46
+
6d6b46
+EnumValue
6d6b46
+Enum(harden_sls) String(none) Value(harden_sls_none)
6d6b46
+
6d6b46
+EnumValue
6d6b46
+Enum(harden_sls) String(return) Value(harden_sls_return)
6d6b46
+
6d6b46
+EnumValue
6d6b46
+Enum(harden_sls) String(indirect-branch) Value(harden_sls_indirect_branch)
6d6b46
+
6d6b46
+EnumValue
6d6b46
+Enum(harden_sls) String(all) Value(harden_sls_all)
6d6b46
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
6d6b46
index 78ca7738df2..1e20efd6969 100644
6d6b46
--- a/gcc/doc/invoke.texi
6d6b46
+++ b/gcc/doc/invoke.texi
6d6b46
@@ -1284,7 +1284,7 @@ See RS/6000 and PowerPC Options.
6d6b46
 -mstack-protector-guard-symbol=@var{symbol} -mmitigate-rop @gol
6d6b46
 -mgeneral-regs-only -mcall-ms2sysv-xlogues @gol
6d6b46
 -mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol
6d6b46
--mindirect-branch-register}
6d6b46
+-mindirect-branch-register -mharden-sls=@var{choice}}
6d6b46
 
6d6b46
 @emph{x86 Windows Options}
6d6b46
 @gccoptlist{-mconsole  -mcygwin  -mno-cygwin  -mdll @gol
6d6b46
@@ -28036,6 +28036,14 @@ not be reachable in the large code model.
6d6b46
 @opindex -mindirect-branch-register
6d6b46
 Force indirect call and jump via register.
6d6b46
 
6d6b46
+@item -mharden-sls=@var{choice}
6d6b46
+@opindex mharden-sls
6d6b46
+Generate code to mitigate against straight line speculation (SLS) with
6d6b46
+@var{choice}.  The default is @samp{none} which disables all SLS
6d6b46
+hardening.  @samp{return} enables SLS hardening for function return.
6d6b46
+@samp{indirect-branch} enables SLS hardening for indirect branch.
6d6b46
+@samp{all} enables all SLS hardening.
6d6b46
+
6d6b46
 @end table
6d6b46
 
6d6b46
 These @samp{-m} switches are supported in addition to the above
6d6b46
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-1.c b/gcc/testsuite/gcc.target/i386/harden-sls-1.c
6d6b46
new file mode 100644
6d6b46
index 00000000000..6f70dc94a23
6d6b46
--- /dev/null
6d6b46
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-1.c
6d6b46
@@ -0,0 +1,14 @@
6d6b46
+/* { dg-do compile } */
6d6b46
+/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */
6d6b46
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
6d6b46
+
6d6b46
+extern void foo (void);
6d6b46
+
6d6b46
+void
6d6b46
+bar (void)
6d6b46
+{
6d6b46
+  foo ();
6d6b46
+}
6d6b46
+
6d6b46
+/* { dg-final { scan-assembler "jmp\[ \t\]+_?foo" } } */
6d6b46
+/* { dg-final { scan-assembler-not {int3} } } */
6d6b46
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-2.c b/gcc/testsuite/gcc.target/i386/harden-sls-2.c
6d6b46
new file mode 100644
6d6b46
index 00000000000..a7c59078d03
6d6b46
--- /dev/null
6d6b46
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-2.c
6d6b46
@@ -0,0 +1,14 @@
6d6b46
+/* { dg-do compile } */
6d6b46
+/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */
6d6b46
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
6d6b46
+
6d6b46
+extern void (*fptr) (void);
6d6b46
+
6d6b46
+void
6d6b46
+foo (void)
6d6b46
+{
6d6b46
+  fptr ();
6d6b46
+}
6d6b46
+
6d6b46
+/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */
6d6b46
+/* { dg-final { scan-assembler-times "int3" 1 } } */
6d6b46
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-3.c b/gcc/testsuite/gcc.target/i386/harden-sls-3.c
6d6b46
new file mode 100644
6d6b46
index 00000000000..1a6056b6d7b
6d6b46
--- /dev/null
6d6b46
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-3.c
6d6b46
@@ -0,0 +1,14 @@
6d6b46
+/* { dg-do compile } */
6d6b46
+/* { dg-options "-O2 -mindirect-branch=thunk -mharden-sls=all" } */
6d6b46
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
6d6b46
+
6d6b46
+extern void (*fptr) (void);
6d6b46
+
6d6b46
+void
6d6b46
+foo (void)
6d6b46
+{
6d6b46
+  fptr ();
6d6b46
+}
6d6b46
+
6d6b46
+/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */
6d6b46
+/* { dg-final { scan-assembler-times "int3" 2 } } */
6d6b46
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-4.c b/gcc/testsuite/gcc.target/i386/harden-sls-4.c
6d6b46
new file mode 100644
6d6b46
index 00000000000..f70dd1379d3
6d6b46
--- /dev/null
6d6b46
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-4.c
6d6b46
@@ -0,0 +1,16 @@
6d6b46
+/* { dg-do compile } */
6d6b46
+/* { dg-options "-O2 -mindirect-branch=keep -mharden-sls=all" } */
6d6b46
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
6d6b46
+
6d6b46
+extern void (*fptr) (void);
6d6b46
+
6d6b46
+void
6d6b46
+foo (void)
6d6b46
+{
6d6b46
+  fptr ();
6d6b46
+}
6d6b46
+
6d6b46
+/* { dg-final { scan-assembler "jmp\[ \t\]+\\*_?fptr" { target { ! x32 } } } } */
6d6b46
+/* { dg-final { scan-assembler "movl\[ \t\]+fptr\\(%rip\\), %eax" { target x32 } } } */
6d6b46
+/* { dg-final { scan-assembler "jmp\[ \t\]+\\*%rax" { target x32 } } } */
6d6b46
+/* { dg-final { scan-assembler-times "int3" 1 } } */
6d6b46
diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-5.c b/gcc/testsuite/gcc.target/i386/harden-sls-5.c
6d6b46
new file mode 100644
6d6b46
index 00000000000..613c44c6f82
6d6b46
--- /dev/null
6d6b46
+++ b/gcc/testsuite/gcc.target/i386/harden-sls-5.c
6d6b46
@@ -0,0 +1,17 @@
6d6b46
+/* { dg-do compile } */
6d6b46
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -mharden-sls=return" } */
6d6b46
+/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */
6d6b46
+
6d6b46
+typedef void (*dispatch_t)(long offset);
6d6b46
+
6d6b46
+dispatch_t dispatch;
6d6b46
+
6d6b46
+int
6d6b46
+male_indirect_jump (long offset)
6d6b46
+{
6d6b46
+  dispatch(offset);
6d6b46
+  return 0;
6d6b46
+}
6d6b46
+
6d6b46
+/* { dg-final { scan-assembler-times "ret" 1 } } */
6d6b46
+/* { dg-final { scan-assembler-times "int3" 1 } } */
6d6b46
-- 
6d6b46
2.36.1
6d6b46