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