Blame SOURCES/gcc48-rh1469697-2.patch

8178f7
commit 6427208ee82548346a2f42a8ac83fdd2f823fde2
8178f7
Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4>
8178f7
Date:   Wed Sep 20 04:56:54 2017 +0000
8178f7
8178f7
            * common.opt (-fstack-clash-protection): New option.
8178f7
            * flag-types.h (enum stack_check_type): Note difference between
8178f7
            -fstack-check= and -fstack-clash-protection.
8178f7
            * params.def (PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE): New PARAM.
8178f7
            (PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL): Likewise.
8178f7
            * toplev.c (process_options): Issue warnings/errors for cases
8178f7
            not handled with -fstack-clash-protection.
8178f7
            * doc/invoke.texi (-fstack-clash-protection): Document new option.
8178f7
            (-fstack-check): Note additional problem with -fstack-check=generic.
8178f7
            Note that -fstack-check is primarily for Ada and refer users
8178f7
            to -fstack-clash-protection for stack-clash-protection.
8178f7
            Document new params for stack clash protection.
8178f7
    
8178f7
            * gcc.dg/stack-check-2.c: New test.
8178f7
            * lib/target-supports.exp
8178f7
            (check_effective_target_supports_stack_clash_protection): New function.
8178f7
            (check_effective_target_frame_pointer_for_non_leaf): Likewise.
8178f7
            (check_effective_target_caller_implicit_probes): Likewise.
8178f7
    
8178f7
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@252994 138bc75d-0d04-0410-961f-82ee72b054a4
8178f7
8178f7
diff --git a/gcc/common.opt b/gcc/common.opt
8178f7
index 16846c13b62..0c335cb12cd 100644
8178f7
--- a/gcc/common.opt
8178f7
+++ b/gcc/common.opt
8178f7
@@ -1911,13 +1911,18 @@ Common Report Var(flag_variable_expansion_in_unroller) Optimization
8178f7
 Apply variable expansion when loops are unrolled
8178f7
 
8178f7
 fstack-check=
8178f7
-Common Report RejectNegative Joined
8178f7
--fstack-check=[no|generic|specific]	Insert stack checking code into the program
8178f7
+Common Report RejectNegative Joined Optimization
8178f7
+-fstack-check=[no|generic|specific]	Insert stack checking code into the program.
8178f7
 
8178f7
 fstack-check
8178f7
 Common Alias(fstack-check=, specific, no)
8178f7
 Insert stack checking code into the program.  Same as -fstack-check=specific
8178f7
 
8178f7
+fstack-clash-protection
8178f7
+Common Report Var(flag_stack_clash_protection) Optimization
8178f7
+Insert code to probe each page of stack space as it is allocated to protect
8178f7
+from stack-clash style attacks.
8178f7
+
8178f7
 fstack-limit
8178f7
 Common Var(common_deferred_options) Defer
8178f7
 
8178f7
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
8178f7
index f7a15ca190e..313a6c5ff76 100644
8178f7
--- a/gcc/doc/invoke.texi
8178f7
+++ b/gcc/doc/invoke.texi
8178f7
@@ -9406,6 +9406,21 @@ compilation for profile feedback and one for compilation without.  The value
8178f7
 for compilation with profile feedback needs to be more conservative (higher) in
8178f7
 order to make tracer effective.
8178f7
 
8178f7
+@item stack-clash-protection-guard-size
8178f7
+Specify the size of the operating system provided stack guard as
8178f7
+2 raised to @var{num} bytes.  The default value is 12 (4096 bytes).
8178f7
+Acceptable values are between 12 and 30.  Higher values may reduce the
8178f7
+number of explicit probes, but a value larger than the operating system
8178f7
+provided guard will leave code vulnerable to stack clash style attacks.
8178f7
+
8178f7
+@item stack-clash-protection-probe-interval
8178f7
+Stack clash protection involves probing stack space as it is allocated.  This
8178f7
+param controls the maximum distance between probes into the stack as 2 raised
8178f7
+to @var{num} bytes.  Acceptable values are between 10 and 16 and defaults to
8178f7
+12.  Higher values may reduce the number of explicit probes, but a value
8178f7
+larger than the operating system provided guard will leave code vulnerable to
8178f7
+stack clash style attacks.
8178f7
+
8178f7
 @item max-cse-path-length
8178f7
 
8178f7
 The maximum number of basic blocks on path that CSE considers.
8178f7
@@ -20949,7 +20964,8 @@ target support in the compiler but comes with the following drawbacks:
8178f7
 @enumerate
8178f7
 @item
8178f7
 Modified allocation strategy for large objects: they are always
8178f7
-allocated dynamically if their size exceeds a fixed threshold.
8178f7
+allocated dynamically if their size exceeds a fixed threshold.  Note this
8178f7
+may change the semantics of some code.
8178f7
 
8178f7
 @item
8178f7
 Fixed limit on the size of the static frame of functions: when it is
8178f7
@@ -20964,6 +20980,27 @@ generic implementation, code performance is hampered.
8178f7
 Note that old-style stack checking is also the fallback method for
8178f7
 @code{specific} if no target support has been added in the compiler.
8178f7
 
8178f7
+@samp{-fstack-check=} is designed for Ada's needs to detect infinite recursion
8178f7
+and stack overflows.  @samp{specific} is an excellent choice when compiling
8178f7
+Ada code.  It is not generally sufficient to protect against stack-clash
8178f7
+attacks.  To protect against those you want @samp{-fstack-clash-protection}.
8178f7
+
8178f7
+@item -fstack-clash-protection
8178f7
+@opindex fstack-clash-protection
8178f7
+Generate code to prevent stack clash style attacks.  When this option is
8178f7
+enabled, the compiler will only allocate one page of stack space at a time
8178f7
+and each page is accessed immediately after allocation.  Thus, it prevents
8178f7
+allocations from jumping over any stack guard page provided by the
8178f7
+operating system.
8178f7
+
8178f7
+Most targets do not fully support stack clash protection.  However, on
8178f7
+those targets @option{-fstack-clash-protection} will protect dynamic stack
8178f7
+allocations.  @option{-fstack-clash-protection} may also provide limited
8178f7
+protection for static stack allocations if the target supports
8178f7
+@option{-fstack-check=specific}.
8178f7
+
8178f7
+
8178f7
+
8178f7
 @item -fstack-limit-register=@var{reg}
8178f7
 @itemx -fstack-limit-symbol=@var{sym}
8178f7
 @itemx -fno-stack-limit
8178f7
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
8178f7
index 4fc5d33348e..21e943d38fa 100644
8178f7
--- a/gcc/flag-types.h
8178f7
+++ b/gcc/flag-types.h
8178f7
@@ -139,7 +139,14 @@ enum excess_precision
8178f7
   EXCESS_PRECISION_STANDARD
8178f7
 };
8178f7
 
8178f7
-/* Type of stack check.  */
8178f7
+/* Type of stack check.
8178f7
+
8178f7
+   Stack checking is designed to detect infinite recursion and stack
8178f7
+   overflows for Ada programs.  Furthermore stack checking tries to ensure
8178f7
+   in that scenario that enough stack space is left to run a signal handler.
8178f7
+
8178f7
+   -fstack-check= does not prevent stack-clash style attacks.  For that
8178f7
+   you want -fstack-clash-protection.  */
8178f7
 enum stack_check_type
8178f7
 {
8178f7
   /* Do not check the stack.  */
8178f7
diff --git a/gcc/params.def b/gcc/params.def
8178f7
index e51b847a7c4..e668624b0cb 100644
8178f7
--- a/gcc/params.def
8178f7
+++ b/gcc/params.def
8178f7
@@ -208,6 +208,16 @@ DEFPARAM(PARAM_STACK_FRAME_GROWTH,
8178f7
 	 "Maximal stack frame growth due to inlining (in percent)",
8178f7
 	 1000, 0, 0)
8178f7
 
8178f7
+DEFPARAM(PARAM_STACK_CLASH_PROTECTION_GUARD_SIZE,
8178f7
+	 "stack-clash-protection-guard-size",
8178f7
+	 "Size of the stack guard expressed as a power of two.",
8178f7
+	 12, 12, 30)
8178f7
+
8178f7
+DEFPARAM(PARAM_STACK_CLASH_PROTECTION_PROBE_INTERVAL,
8178f7
+	 "stack-clash-protection-probe-interval",
8178f7
+	 "Interval in which to probe the stack expressed as a power of two.",
8178f7
+	 12, 10, 16)
8178f7
+
8178f7
 /* The GCSE optimization will be disabled if it would require
8178f7
    significantly more memory than this value.  */
8178f7
 DEFPARAM(PARAM_MAX_GCSE_MEMORY,
8178f7
diff --git a/gcc/testsuite/gcc.dg/stack-check-2.c b/gcc/testsuite/gcc.dg/stack-check-2.c
8178f7
new file mode 100644
8178f7
index 00000000000..196c4bbfbdd
8178f7
--- /dev/null
8178f7
+++ b/gcc/testsuite/gcc.dg/stack-check-2.c
8178f7
@@ -0,0 +1,66 @@
8178f7
+/* The goal here is to ensure that we never consider a call to a noreturn
8178f7
+   function as a potential tail call.
8178f7
+
8178f7
+   Right now GCC discovers potential tail calls by looking at the
8178f7
+   predecessors of the exit block.  A call to a non-return function
8178f7
+   has no successors and thus can never match that first filter.
8178f7
+
8178f7
+   But that could change one day and we want to catch it.  The problem
8178f7
+   is the compiler could potentially optimize a tail call to a nonreturn
8178f7
+   function, even if the caller has a frame.  That breaks the assumption
8178f7
+   that calls probe *sp when saving the return address that some targets
8178f7
+   depend on to elide stack probes.  */
8178f7
+
8178f7
+/* { dg-do compile } */
8178f7
+/* { dg-options "-O2 -fstack-clash-protection -fdump-tree-tailc -fdump-tree-optimized" } */
8178f7
+/* { dg-require-effective-target supports_stack_clash_protection } */
8178f7
+
8178f7
+extern void foo (void) __attribute__ ((__noreturn__));
8178f7
+
8178f7
+
8178f7
+void
8178f7
+test_direct_1 (void)
8178f7
+{
8178f7
+  foo ();
8178f7
+}
8178f7
+
8178f7
+void
8178f7
+test_direct_2 (void)
8178f7
+{
8178f7
+  return foo ();
8178f7
+}
8178f7
+
8178f7
+void (*indirect)(void)__attribute__ ((noreturn));
8178f7
+
8178f7
+
8178f7
+void
8178f7
+test_indirect_1 ()
8178f7
+{
8178f7
+  (*indirect)();
8178f7
+}
8178f7
+
8178f7
+void
8178f7
+test_indirect_2 (void)
8178f7
+{
8178f7
+  return (*indirect)();;
8178f7
+}
8178f7
+
8178f7
+
8178f7
+typedef void (*pvfn)() __attribute__ ((noreturn));
8178f7
+
8178f7
+void (*indirect_casted)(void);
8178f7
+
8178f7
+void
8178f7
+test_indirect_casted_1 ()
8178f7
+{
8178f7
+  (*(pvfn)indirect_casted)();
8178f7
+}
8178f7
+
8178f7
+void
8178f7
+test_indirect_casted_2 (void)
8178f7
+{
8178f7
+  return (*(pvfn)indirect_casted)();
8178f7
+}
8178f7
+/* { dg-final { scan-tree-dump-not "tail call" "tailc" } } */
8178f7
+/* { dg-final { scan-tree-dump-not "tail call" "optimized" } } */
8178f7
+
8178f7
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
8178f7
index ef371ad7efd..821cea9cb33 100644
8178f7
--- a/gcc/testsuite/lib/target-supports.exp
8178f7
+++ b/gcc/testsuite/lib/target-supports.exp
8178f7
@@ -5392,3 +5392,95 @@ proc check_effective_target_fenv_exceptions {} {
8178f7
 	}
8178f7
     } "-std=gnu99"]
8178f7
 }
8178f7
+
8178f7
+# Return 1 if the target supports the auto_inc_dec optimization pass.
8178f7
+proc check_effective_target_autoincdec { } {
8178f7
+    if { ![check_no_compiler_messages auto_incdec assembly { void f () { }
8178f7
+	 } "-O2 -fdump-rtl-auto_inc_dec" ] } {
8178f7
+      return 0
8178f7
+    }
8178f7
+
8178f7
+    set dumpfile [glob -nocomplain "auto_incdec[pid].c.\[0-9\]\[0-9\]\[0-9\]r.auto_inc_dec"]
8178f7
+    if { [file exists $dumpfile ] } {
8178f7
+	file delete $dumpfile
8178f7
+	return 1
8178f7
+    }
8178f7
+    return 0
8178f7
+}
8178f7
+
8178f7
+# Return 1 if the target has support for stack probing designed
8178f7
+# to avoid stack-clash style attacks.
8178f7
+#
8178f7
+# This is used to restrict the stack-clash mitigation tests to
8178f7
+# just those targets that have been explicitly supported.
8178f7
+# 
8178f7
+# In addition to the prologue work on those targets, each target's
8178f7
+# properties should be described in the functions below so that
8178f7
+# tests do not become a mess of unreadable target conditions.
8178f7
+# 
8178f7
+proc check_effective_target_supports_stack_clash_protection { } {
8178f7
+
8178f7
+   # Temporary until the target bits are fully ACK'd.
8178f7
+#  if { [istarget aarch*-*-*] || [istarget x86_64-*-*]
8178f7
+#       || [istarget i?86-*-*] || [istarget s390*-*-*]
8178f7
+#       || [istarget powerpc*-*-*] || [istarget rs6000*-*-*] } {
8178f7
+#	return 1
8178f7
+#  }
8178f7
+  return 0
8178f7
+}
8178f7
+
8178f7
+# Return 1 if the target creates a frame pointer for non-leaf functions
8178f7
+# Note we ignore cases where we apply tail call optimization here.
8178f7
+proc check_effective_target_frame_pointer_for_non_leaf { } {
8178f7
+  if { [istarget aarch*-*-*] } {
8178f7
+	return 1
8178f7
+  }
8178f7
+  return 0
8178f7
+}
8178f7
+
8178f7
+# Return 1 if the target's calling sequence or its ABI
8178f7
+# create implicit stack probes at or prior to function entry.
8178f7
+proc check_effective_target_caller_implicit_probes { } {
8178f7
+
8178f7
+  # On x86/x86_64 the call instruction itself pushes the return
8178f7
+  # address onto the stack.  That is an implicit probe of *sp.
8178f7
+  if { [istarget x86_64-*-*] || [istarget i?86-*-*] } {
8178f7
+	return 1
8178f7
+  }
8178f7
+
8178f7
+  # On PPC, the ABI mandates that the address of the outer
8178f7
+  # frame be stored at *sp.  Thus each allocation of stack
8178f7
+  # space is itself an implicit probe of *sp.
8178f7
+  if { [istarget powerpc*-*-*] || [istarget rs6000*-*-*] } {
8178f7
+	return 1
8178f7
+  }
8178f7
+
8178f7
+  # s390's ABI has a register save area allocated by the
8178f7
+  # caller for use by the callee.  The mere existence does
8178f7
+  # not constitute a probe by the caller, but when the slots
8178f7
+  # used by the callee those stores are implicit probes.
8178f7
+  if { [istarget s390*-*-*] } {
8178f7
+	return 1
8178f7
+  }
8178f7
+
8178f7
+  # Not strictly true on aarch64, but we have agreed that we will
8178f7
+  # consider any function that pushes SP more than 3kbytes into
8178f7
+  # the guard page as broken.  This essentially means that we can
8178f7
+  # consider the aarch64 as having a caller implicit probe at
8178f7
+  # *(sp + 1k).
8178f7
+  if { [istarget aarch64*-*-*] } {
8178f7
+	return 1;
8178f7
+  }
8178f7
+
8178f7
+  return 0
8178f7
+}
8178f7
+
8178f7
+# Targets that potentially realign the stack pointer often cause residual
8178f7
+# stack allocations and make it difficult to elimination loops or residual
8178f7
+# allocations for dynamic stack allocations
8178f7
+proc check_effective_target_callee_realigns_stack { } {
8178f7
+  if { [istarget x86_64-*-*] || [istarget i?86-*-*] } {
8178f7
+	return 1
8178f7
+  }
8178f7
+  return 0
8178f7
+}
8178f7
diff --git a/gcc/toplev.c b/gcc/toplev.c
8178f7
index 26f2ffb362c..1def163f8b9 100644
8178f7
--- a/gcc/toplev.c
8178f7
+++ b/gcc/toplev.c
8178f7
@@ -1520,6 +1520,28 @@ process_options (void)
8178f7
       flag_associative_math = 0;
8178f7
     }
8178f7
 
8178f7
+#ifndef STACK_GROWS_DOWNWARD
8178f7
+  /* -fstack-clash-protection is not currently supported on targets
8178f7
+     where the stack grows up.  */
8178f7
+  if (flag_stack_clash_protection)
8178f7
+    {
8178f7
+      warning_at (UNKNOWN_LOCATION, 0,
8178f7
+		  "%<-fstack-clash-protection%> is not supported on targets "
8178f7
+		  "where the stack grows from lower to higher addresses");
8178f7
+      flag_stack_clash_protection = 0;
8178f7
+    }
8178f7
+#endif
8178f7
+
8178f7
+  /* We can not support -fstack-check= and -fstack-clash-protection at
8178f7
+     the same time.  */
8178f7
+  if (flag_stack_check != NO_STACK_CHECK && flag_stack_clash_protection)
8178f7
+    {
8178f7
+      warning_at (UNKNOWN_LOCATION, 0,
8178f7
+		  "%<-fstack-check=%> and %<-fstack-clash_protection%> are "
8178f7
+		  "mutually exclusive.  Disabling %<-fstack-check=%>");
8178f7
+      flag_stack_check = NO_STACK_CHECK;
8178f7
+    }
8178f7
+
8178f7
   /* With -fcx-limited-range, we do cheap and quick complex arithmetic.  */
8178f7
   if (flag_cx_limited_range)
8178f7
     flag_complex_method = 0;