Commit 39f50da2 authored by serge_sans_paille's avatar serge_sans_paille Committed by serge-sans-paille
Browse files

Support -fstack-clash-protection for x86

Implement protection against the stack clash attack [0] through inline stack
probing.

Probe stack allocation every PAGE_SIZE during frame lowering or dynamic
allocation to make sure the page guard, if any, is touched when touching the
stack, in a similar manner to GCC[1].

This extends the existing `probe-stack' mechanism with a special value `inline-asm'.
Technically the former uses function call before stack allocation while this
patch provides inlined stack probes and chunk allocation.

Only implemented for x86.

[0] https://www.qualys.com/2017/06/19/stack-clash/stack-clash.txt
[1] https://gcc.gnu.org/ml/gcc-patches/2017-07/msg00556.html

Differential Revision: https://reviews.llvm.org/D68720
parent 56d81d45
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1917,6 +1917,10 @@ Use a strong heuristic to apply stack protectors to functions

Emit section containing metadata on function stack sizes

.. option:: -fstack-clash-protection, -fno-stack-clash-protection

Instrument stack allocation to prevent stack clash attacks (x86, non-Windows only).

.. option:: -fstandalone-debug, -fno-limit-debug-info, -fno-standalone-debug

Emit full debug info for all types used by the program
+4 −0
Original line number Diff line number Diff line
@@ -61,6 +61,10 @@ New Compiler Flags
------------------


- -fstack-clash-protection will provide a protection against the stack clash
  attack for x86 architecture through automatic probing of each page of
  allocated stack.

Deprecated Compiler Flags
-------------------------

+1 −0
Original line number Diff line number Diff line
@@ -150,6 +150,7 @@ CODEGENOPT(NoWarn , 1, 0) ///< Set when -Wa,--no-warn is enabled.
CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled.
CODEGENOPT(NoInlineLineTables, 1, 0) ///< Whether debug info should contain
                                     ///< inline line tables.
CODEGENOPT(StackClashProtector, 1, 0) ///< Set when -fstack-clash-protection is enabled.
CODEGENOPT(NoImplicitFloat   , 1, 0) ///< Set when -mno-implicit-float is enabled.
CODEGENOPT(NoInfsFPMath      , 1, 0) ///< Assume FP arguments, results not +-Inf.
CODEGENOPT(NoSignedZeros     , 1, 0) ///< Allow ignoring the signedness of FP zero
+4 −0
Original line number Diff line number Diff line
@@ -239,6 +239,10 @@ def note_invalid_subexpr_in_const_expr : Note<
let CategoryName = "Inline Assembly Issue" in {
  def err_asm_invalid_type_in_input : Error<
    "invalid type %0 in asm input for constraint '%1'">;

  def warn_stack_clash_protection_inline_asm : Warning<
    "Unable to protect inline asm that clobbers stack pointer against stack clash">,
    InGroup<DiagGroup<"stack-protector">>;
}

// Sema && Serialization
+2 −0
Original line number Diff line number Diff line
@@ -816,6 +816,8 @@ public:
  StringRef getNormalizedGCCRegisterName(StringRef Name,
                                         bool ReturnCanonical = false) const;

  virtual bool isSPRegName(StringRef) const { return false; }

  /// Extracts a register from the passed constraint (if it is a
  /// single-register constraint) and the asm label expression related to a
  /// variable in the input or output list of an inline asm statement.
Loading