llvm.org GIT mirror llvm / 2b58ce5
Initial checkin for stack protectors. Here's what it does: * The prologue is modified to read the __stack_chk_guard global and insert it onto the stack. * The epilogue is modified to read the stored guard from the stack and compare it to the original __stack_chk_guard value. If they differ, then the __stack_chk_fail() function is called. * The stack protector needs to be first on the stack (after the parameters) to catch any stack-smashing activities. Front-end support will follow after a round of beta testing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58673 91177308-0d34-0410-b5e6-96231b3b80d8 Bill Wendling 11 years ago
3 changed file(s) with 239 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
190190
191191 /// createStackSlotColoringPass - This pass performs stack slot coloring.
192192 FunctionPass *createStackSlotColoringPass();
193
193
194 /// createStackProtectorPass - This pass adds stack protectors to functions.
195 FunctionPass *createStackProtectorPass(int Level);
196
194197 } // End llvm namespace
195198
196199 #endif
5959 EnableFastISelOption("fast-isel", cl::Hidden,
6060 cl::desc("Enable the experimental \"fast\" instruction selector"));
6161
62 // Enable stack protectors.
63 static cl::opt
64 EnableStackProtector("enable-stack-protector", cl::init(0),
65 cl::desc("Use ProPolice as a stack protection method."));
66
6267 FileModel::Model
6368 LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
6469 raw_ostream &Out,
164169 if (!Fast)
165170 PM.add(createCodeGenPreparePass(getTargetLowering()));
166171
172 PM.add(createStackProtectorPass(EnableStackProtector));
173
167174 if (PrintISelInput)
168175 PM.add(createPrintFunctionPass("\n\n"
169176 "*** Final LLVM Code input to ISel ***\n",
0 //===-- StackProtector.cpp - Stack Protector Insertion --------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This pass inserts stack protectors into functions which need them. The stack
10 // protectors this uses are the type that ProPolice used. A variable with a
11 // random value in it is stored onto the stack before the local variables are
12 // allocated. Upon exitting the block, the stored value is checked. If it's
13 // changed, then there was some sort of violation and the program aborts.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #define DEBUG_TYPE "stack-protector"
18 #include "llvm/CodeGen/Passes.h"
19 #include "llvm/Constants.h"
20 #include "llvm/DerivedTypes.h"
21 #include "llvm/Function.h"
22 #include "llvm/Instructions.h"
23 #include "llvm/Module.h"
24 #include "llvm/Pass.h"
25 #include "llvm/ADT/APInt.h"
26 #include "llvm/Support/CommandLine.h"
27 using namespace llvm;
28
29 // Enable stack protectors.
30 static cl::opt
31 SSPBufferSize("ssp-buffer-size", cl::init(8),
32 cl::desc("The lower bound for a buffer to be considered for "
33 "stack smashing protection."));
34
35 namespace {
36 class VISIBILITY_HIDDEN StackProtector : public FunctionPass {
37 // Level == 0 -- Stack protectors are off.
38 // Level == 1 -- Stack protectors are on only for some functions.
39 // Level == 2 -- Stack protectors are on for all functions.
40 int Level;
41
42 /// FailBB - Holds the basic block to jump to when the stack protector check
43 /// fails.
44 BasicBlock *FailBB;
45
46 /// StackProtFrameSlot - The place on the stack that the stack protector
47 /// guard is kept.
48 AllocaInst *StackProtFrameSlot;
49
50 /// StackGuardVar - The global variable for the stack guard.
51 GlobalVariable *StackGuardVar;
52
53 Function *F;
54 Module *M;
55
56 /// InsertStackProtectorPrologue - Insert code into the entry block that
57 /// stores the __stack_chk_guard variable onto the stack.
58 void InsertStackProtectorPrologue();
59
60 /// InsertStackProtectorEpilogue - Insert code before the return
61 /// instructions checking the stack value that was stored in the
62 /// prologue. If it isn't the same as the original value, then call a
63 /// "failure" function.
64 void InsertStackProtectorEpilogue();
65
66 /// CreateFailBB - Create a basic block to jump to when the stack protector
67 /// check fails.
68 void CreateFailBB();
69
70 /// RequiresStackProtector - Check whether or not this function needs a
71 /// stack protector based upon the stack protector level.
72 bool RequiresStackProtector();
73 public:
74 static char ID; // Pass identification, replacement for typeid.
75 StackProtector(int lvl = 0) : FunctionPass(&ID), Level(lvl), FailBB(0) {}
76
77 virtual bool runOnFunction(Function &Fn);
78 };
79 } // end anonymous namespace
80
81 char StackProtector::ID = 0;
82 static RegisterPass
83 X("stack-protector", "Insert stack protectors");
84
85 FunctionPass *llvm::createStackProtectorPass(int lvl) {
86 return new StackProtector(lvl);
87 }
88
89 bool StackProtector::runOnFunction(Function &Fn) {
90 F = &Fn;
91 M = F->getParent();
92
93 if (!RequiresStackProtector()) return false;
94
95 InsertStackProtectorPrologue();
96 InsertStackProtectorEpilogue();
97
98 // Cleanup.
99 FailBB = 0;
100 StackProtFrameSlot = 0;
101 StackGuardVar = 0;
102 return true;
103 }
104
105 /// InsertStackProtectorPrologue - Insert code into the entry block that stores
106 /// the __stack_chk_guard variable onto the stack.
107 void StackProtector::InsertStackProtectorPrologue() {
108 BasicBlock &Entry = F->getEntryBlock();
109 Instruction &InsertPt = Entry.front();
110
111 const char *StackGuardStr = "__stack_chk_guard";
112 StackGuardVar = M->getNamedGlobal(StackGuardStr);
113
114 if (!StackGuardVar)
115 StackGuardVar = new GlobalVariable(PointerType::getUnqual(Type::Int8Ty),
116 false, GlobalValue::ExternalLinkage,
117 0, StackGuardStr, M);
118
119 StackProtFrameSlot = new AllocaInst(PointerType::getUnqual(Type::Int8Ty),
120 "StackProt_Frame", &InsertPt);
121 LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", true, &InsertPt);
122 new StoreInst(LI, StackProtFrameSlot, true, &InsertPt);
123 }
124
125 /// InsertStackProtectorEpilogue - Insert code before the return instructions
126 /// checking the stack value that was stored in the prologue. If it isn't the
127 /// same as the original value, then call a "failure" function.
128 void StackProtector::InsertStackProtectorEpilogue() {
129 // Create the basic block to jump to when the guard check fails.
130 CreateFailBB();
131
132 Function::iterator I = F->begin(), E = F->end();
133 std::vector ReturnBBs;
134 ReturnBBs.reserve(F->size());
135
136 for (; I != E; ++I)
137 if (isa((*I).getTerminator()))
138 ReturnBBs.push_back(I);
139
140 if (ReturnBBs.empty()) return; // Odd, but could happen. . .
141
142 // Loop through the basic blocks that have return instructions. Convert this:
143 //
144 // return:
145 // ...
146 // ret ...
147 //
148 // into this:
149 //
150 // return:
151 // ...
152 // %1 = load __stack_chk_guard
153 // %2 = load
154 // %3 = cmp i1 %1, %2
155 // br i1 %3, label %SPRet, label %CallStackCheckFailBlk
156 //
157 // SPRet:
158 // ret ...
159 //
160 // CallStackCheckFailBlk:
161 // call void @__stack_chk_fail()
162 // unreachable
163 //
164 for (std::vector::iterator
165 II = ReturnBBs.begin(), IE = ReturnBBs.end(); II != IE; ++II) {
166 BasicBlock *BB = *II;
167 ReturnInst *RI = cast(BB->getTerminator());
168 Function::iterator InsPt = BB; ++InsPt; // Insertion point for new BB.
169
170 BasicBlock *NewBB = BasicBlock::Create("SPRet", F, InsPt);
171
172 // Move the return instruction into the new basic block.
173 RI->removeFromParent();
174 NewBB->getInstList().insert(NewBB->begin(), RI);
175
176 LoadInst *LI2 = new LoadInst(StackGuardVar, "", false, BB);
177 LoadInst *LI1 = new LoadInst(StackProtFrameSlot, "", true, BB);
178 ICmpInst *Cmp = new ICmpInst(CmpInst::ICMP_EQ, LI1, LI2, "", BB);
179 BranchInst::Create(NewBB, FailBB, Cmp, BB);
180 }
181 }
182
183 /// CreateFailBB - Create a basic block to jump to when the stack protector
184 /// check fails.
185 void StackProtector::CreateFailBB() {
186 assert(!FailBB && "Failure basic block already created?!");
187 FailBB = BasicBlock::Create("CallStackCheckFailBlk", F);
188 std::vector Params;
189 Constant *StackChkFail =
190 M->getOrInsertFunction("__stack_chk_fail",
191 FunctionType::get(Type::VoidTy, Params, false));
192 CallInst::Create(StackChkFail, "", FailBB);
193 new UnreachableInst(FailBB);
194 }
195
196 /// RequiresStackProtector - Check whether or not this function needs a stack
197 /// protector based upon the stack protector level.
198 bool StackProtector::RequiresStackProtector() {
199 switch (Level) {
200 default: return false;
201 case 2: return true;
202 case 1: {
203 // If the size of the local variables allocated on the stack is greater than
204 // SSPBufferSize, then we require a stack protector.
205 uint64_t StackSize = 0;
206
207 for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
208 BasicBlock *BB = I;
209
210 for (BasicBlock::iterator
211 II = BB->begin(), IE = BB->end(); II != IE; ++II)
212 if (AllocaInst *AI = dyn_cast(II))
213 if (ConstantInt *CI = dyn_cast(AI->getArraySize())) {
214 const APInt &Size = CI->getValue();
215 StackSize += Size.getZExtValue() * 8;
216 }
217 }
218
219 if (SSPBufferSize <= StackSize)
220 return true;
221
222 return false;
223 }
224 }
225 }
226
227 // [EOF] StackProtector.cpp