59 lines
3.1 KiB
Plaintext
59 lines
3.1 KiB
Plaintext
$OpenBSD: patch-include_llvm_CodeGen_MachineFrameInfo_h,v 1.5 2020/08/05 06:49:48 jca Exp $
|
|
|
|
- Add RETGUARD to clang for amd64. This security mechanism uses per-function
|
|
random cookies to protect access to function return instructions, with the
|
|
effect that the integrity of the return address is protected, and function
|
|
return instructions are harder to use in ROP gadgets.
|
|
|
|
On function entry the return address is combined with a per-function random
|
|
cookie and stored in the stack frame. The integrity of this value is verified
|
|
before function return, and if this check fails, the program aborts. In this way
|
|
RETGUARD is an improved stack protector, since the cookies are per-function. The
|
|
verification routine is constructed such that the binary space immediately
|
|
before each ret instruction is padded with int03 instructions, which makes these
|
|
return instructions difficult to use in ROP gadgets. In the kernel, this has the
|
|
effect of removing approximately 50% of total ROP gadgets, and 15% of unique
|
|
ROP gadgets compared to the 6.3 release kernel. Function epilogues are
|
|
essentially gadget free, leaving only the polymorphic gadgets that result from
|
|
jumping into the instruction stream partway through other instructions. Work to
|
|
remove these gadgets will continue through other mechanisms.
|
|
- Refactor retguard to make adding additional arches easier.
|
|
|
|
Index: include/llvm/CodeGen/MachineFrameInfo.h
|
|
--- include/llvm/CodeGen/MachineFrameInfo.h.orig
|
|
+++ include/llvm/CodeGen/MachineFrameInfo.h
|
|
@@ -273,6 +273,15 @@ class MachineFrameInfo { (private)
|
|
/// The frame index for the stack protector.
|
|
int StackProtectorIdx = -1;
|
|
|
|
+ struct ReturnProtector {
|
|
+ /// The register to use for return protector calculations
|
|
+ unsigned Register = 0;
|
|
+ /// Set to true if this function needs return protectors
|
|
+ bool Needed = false;
|
|
+ /// Does the return protector cookie need to be stored in frame
|
|
+ bool NeedsStore = true;
|
|
+ } RPI;
|
|
+
|
|
/// The frame index for the function context. Used for SjLj exceptions.
|
|
int FunctionContextIdx = -1;
|
|
|
|
@@ -353,6 +362,17 @@ class MachineFrameInfo { (private)
|
|
int getStackProtectorIndex() const { return StackProtectorIdx; }
|
|
void setStackProtectorIndex(int I) { StackProtectorIdx = I; }
|
|
bool hasStackProtectorIndex() const { return StackProtectorIdx != -1; }
|
|
+
|
|
+ /// Get / Set return protector calculation register
|
|
+ unsigned getReturnProtectorRegister() const { return RPI.Register; }
|
|
+ void setReturnProtectorRegister(unsigned I) { RPI.Register = I; }
|
|
+ bool hasReturnProtectorRegister() const { return RPI.Register != 0; }
|
|
+ /// Get / Set if this frame needs a return protector
|
|
+ void setReturnProtectorNeeded(bool I) { RPI.Needed = I; }
|
|
+ bool getReturnProtectorNeeded() const { return RPI.Needed; }
|
|
+ /// Get / Set if the return protector cookie needs to be stored in frame
|
|
+ void setReturnProtectorNeedsStore(bool I) { RPI.NeedsStore = I; }
|
|
+ bool getReturnProtectorNeedsStore() const { return RPI.NeedsStore; }
|
|
|
|
/// Return the index for the function context object.
|
|
/// This object is used for SjLj exceptions.
|