xref: /llvm-project/llvm/lib/CodeGen/StackProtector.cpp (revision 64adc71e9ab12af3d4079a7481cc35f7d528817d)
1 //===-- 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. A variable
11 // with a random value in it is stored onto the stack before the local variables
12 // are allocated. Upon exiting 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 #include "llvm/Target/TargetData.h"
28 #include "llvm/Target/TargetLowering.h"
29 using namespace llvm;
30 
31 // Enable stack protectors.
32 static cl::opt<unsigned>
33 SSPBufferSize("stack-protector-buffer-size", cl::init(8),
34               cl::desc("The lower bound for a buffer to be considered for "
35                        "stack smashing protection."));
36 
37 namespace {
38   class VISIBILITY_HIDDEN StackProtector : public FunctionPass {
39     /// Level - The level of stack protection.
40     SSP::StackProtectorLevel Level;
41 
42     /// TLI - Keep a pointer of a TargetLowering to consult for determining
43     /// target type sizes.
44     const TargetLowering *TLI;
45 
46     /// FailBB - Holds the basic block to jump to when the stack protector check
47     /// fails.
48     BasicBlock *FailBB;
49 
50     /// StackProtFrameSlot - The place on the stack that the stack protector
51     /// guard is kept.
52     AllocaInst *StackProtFrameSlot;
53 
54     /// StackGuardVar - The global variable for the stack guard.
55     GlobalVariable *StackGuardVar;
56 
57     Function *F;
58     Module *M;
59 
60     /// InsertStackProtectorPrologue - Insert code into the entry block that
61     /// stores the __stack_chk_guard variable onto the stack.
62     void InsertStackProtectorPrologue();
63 
64     /// InsertStackProtectorEpilogue - Insert code before the return
65     /// instructions checking the stack value that was stored in the
66     /// prologue. If it isn't the same as the original value, then call a
67     /// "failure" function.
68     void InsertStackProtectorEpilogue();
69 
70     /// CreateFailBB - Create a basic block to jump to when the stack protector
71     /// check fails.
72     void CreateFailBB();
73 
74     /// RequiresStackProtector - Check whether or not this function needs a
75     /// stack protector based upon the stack protector level.
76     bool RequiresStackProtector() const;
77   public:
78     static char ID;             // Pass identification, replacement for typeid.
79     StackProtector() : FunctionPass(&ID), Level(SSP::OFF), TLI(0), FailBB(0) {}
80     StackProtector(SSP::StackProtectorLevel lvl, const TargetLowering *tli)
81       : FunctionPass(&ID), Level(lvl), TLI(tli), FailBB(0) {}
82 
83     virtual bool runOnFunction(Function &Fn);
84   };
85 } // end anonymous namespace
86 
87 char StackProtector::ID = 0;
88 static RegisterPass<StackProtector>
89 X("stack-protector", "Insert stack protectors");
90 
91 FunctionPass *llvm::createStackProtectorPass(SSP::StackProtectorLevel lvl,
92                                              const TargetLowering *tli) {
93   return new StackProtector(lvl, tli);
94 }
95 
96 bool StackProtector::runOnFunction(Function &Fn) {
97   F = &Fn;
98   M = F->getParent();
99 
100   if (!RequiresStackProtector()) return false;
101 
102   InsertStackProtectorPrologue();
103   InsertStackProtectorEpilogue();
104 
105   // Cleanup.
106   FailBB = 0;
107   StackProtFrameSlot = 0;
108   StackGuardVar = 0;
109   return true;
110 }
111 
112 /// InsertStackProtectorPrologue - Insert code into the entry block that stores
113 /// the __stack_chk_guard variable onto the stack.
114 void StackProtector::InsertStackProtectorPrologue() {
115   BasicBlock &Entry = F->getEntryBlock();
116   Instruction &InsertPt = Entry.front();
117 
118   const char *StackGuardStr = "__stack_chk_guard";
119   StackGuardVar = M->getNamedGlobal(StackGuardStr);
120 
121   if (!StackGuardVar)
122     StackGuardVar = new GlobalVariable(PointerType::getUnqual(Type::Int8Ty),
123                                        false, GlobalValue::ExternalLinkage,
124                                        0, StackGuardStr, M);
125 
126   StackProtFrameSlot = new AllocaInst(PointerType::getUnqual(Type::Int8Ty),
127                                       "StackProt_Frame", &InsertPt);
128   LoadInst *LI = new LoadInst(StackGuardVar, "StackGuard", false, &InsertPt);
129   new StoreInst(LI, StackProtFrameSlot, false, &InsertPt);
130 }
131 
132 /// InsertStackProtectorEpilogue - Insert code before the return instructions
133 /// checking the stack value that was stored in the prologue. If it isn't the
134 /// same as the original value, then call a "failure" function.
135 void StackProtector::InsertStackProtectorEpilogue() {
136   // Create the basic block to jump to when the guard check fails.
137   CreateFailBB();
138 
139   Function::iterator I = F->begin(), E = F->end();
140   std::vector<BasicBlock*> ReturnBBs;
141   ReturnBBs.reserve(F->size());
142 
143   for (; I != E; ++I)
144     if (isa<ReturnInst>(I->getTerminator()))
145       ReturnBBs.push_back(I);
146 
147   if (ReturnBBs.empty()) return; // Odd, but could happen. . .
148 
149   // Loop through the basic blocks that have return instructions. Convert this:
150   //
151   //   return:
152   //     ...
153   //     ret ...
154   //
155   // into this:
156   //
157   //   return:
158   //     ...
159   //     %1 = load __stack_chk_guard
160   //     %2 = load <stored stack guard>
161   //     %3 = cmp i1 %1, %2
162   //     br i1 %3, label %SPRet, label %CallStackCheckFailBlk
163   //
164   //   SPRet:
165   //     ret ...
166   //
167   //   CallStackCheckFailBlk:
168   //     call void @__stack_chk_fail()
169   //     unreachable
170   //
171   for (std::vector<BasicBlock*>::iterator
172          II = ReturnBBs.begin(), IE = ReturnBBs.end(); II != IE; ++II) {
173     BasicBlock *BB = *II;
174     ReturnInst *RI = cast<ReturnInst>(BB->getTerminator());
175     Function::iterator InsPt = BB; ++InsPt; // Insertion point for new BB.
176 
177     BasicBlock *NewBB = BasicBlock::Create("SPRet", F, InsPt);
178 
179     // Move the return instruction into the new basic block.
180     RI->removeFromParent();
181     NewBB->getInstList().insert(NewBB->begin(), RI);
182 
183     LoadInst *LI2 = new LoadInst(StackGuardVar, "", false, BB);
184     LoadInst *LI1 = new LoadInst(StackProtFrameSlot, "", true, BB);
185     ICmpInst *Cmp = new ICmpInst(CmpInst::ICMP_EQ, LI1, LI2, "", BB);
186     BranchInst::Create(NewBB, FailBB, Cmp, BB);
187   }
188 }
189 
190 /// CreateFailBB - Create a basic block to jump to when the stack protector
191 /// check fails.
192 void StackProtector::CreateFailBB() {
193   assert(!FailBB && "Failure basic block already created?!");
194   FailBB = BasicBlock::Create("CallStackCheckFailBlk", F);
195   std::vector<const Type*> Params;
196   Constant *StackChkFail =
197     M->getOrInsertFunction("__stack_chk_fail", Type::VoidTy, NULL);
198   CallInst::Create(StackChkFail, "", FailBB);
199   new UnreachableInst(FailBB);
200 }
201 
202 /// RequiresStackProtector - Check whether or not this function needs a stack
203 /// protector based upon the stack protector level.
204 bool StackProtector::RequiresStackProtector() const {
205   switch (Level) {
206   default: return false;
207   case SSP::ALL: return true;
208   case SSP::SOME: {
209     // If the size of the local variables allocated on the stack is greater than
210     // SSPBufferSize, then we require a stack protector.
211     uint64_t StackSize = 0;
212     const TargetData *TD = TLI->getTargetData();
213 
214     for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
215       BasicBlock *BB = I;
216 
217       for (BasicBlock::iterator
218              II = BB->begin(), IE = BB->end(); II != IE; ++II)
219         if (AllocaInst *AI = dyn_cast<AllocaInst>(II)) {
220           if (ConstantInt *CI = dyn_cast<ConstantInt>(AI->getArraySize())) {
221             uint64_t Bytes = TD->getTypeSizeInBits(AI->getAllocatedType()) / 8;
222             const APInt &Size = CI->getValue();
223             StackSize += Bytes * Size.getZExtValue();
224 
225             if (SSPBufferSize <= StackSize)
226               return true;
227           }
228         }
229     }
230 
231     return false;
232   }
233   }
234 }
235