StackProtector.cpp revision 2b58ce5ab4e22e796303d68fb246d4031cb5d4ca
1e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//===-- StackProtector.cpp - Stack Protector Insertion --------------------===//
2e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//
3e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//                     The LLVM Compiler Infrastructure
4e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//
5e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// This file is distributed under the University of Illinois Open Source
6e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// License. See LICENSE.TXT for details.
7e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//
8e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//===----------------------------------------------------------------------===//
9e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//
10e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// This pass inserts stack protectors into functions which need them. The stack
11e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// protectors this uses are the type that ProPolice used. A variable with a
12e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// random value in it is stored onto the stack before the local variables are
13e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// allocated. Upon exitting the block, the stored value is checked. If it's
14e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// changed, then there was some sort of violation and the program aborts.
15e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//
16e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott//===----------------------------------------------------------------------===//
17e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
18e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#define DEBUG_TYPE "stack-protector"
19e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include "llvm/CodeGen/Passes.h"
20e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include "llvm/Constants.h"
21e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include "llvm/DerivedTypes.h"
22e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include "llvm/Function.h"
23e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include "llvm/Instructions.h"
24e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include "llvm/Module.h"
25e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include "llvm/Pass.h"
26e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include "llvm/ADT/APInt.h"
27e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott#include "llvm/Support/CommandLine.h"
28e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottusing namespace llvm;
29e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
30e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott// Enable stack protectors.
31e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic cl::opt<unsigned>
32e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick ScottSSPBufferSize("ssp-buffer-size", cl::init(8),
33e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott              cl::desc("The lower bound for a buffer to be considered for "
34e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott                       "stack smashing protection."));
35e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
36e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottnamespace {
37e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  class VISIBILITY_HIDDEN StackProtector : public FunctionPass {
38e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    // Level == 0  --  Stack protectors are off.
39e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    // Level == 1  --  Stack protectors are on only for some functions.
40e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    // Level == 2  --  Stack protectors are on for all functions.
41e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    int Level;
42e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
43e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    /// FailBB - Holds the basic block to jump to when the stack protector check
44e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    /// fails.
45e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    BasicBlock *FailBB;
46e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
47e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    /// StackProtFrameSlot - The place on the stack that the stack protector
48e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    /// guard is kept.
49e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    AllocaInst *StackProtFrameSlot;
50e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
51e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    /// StackGuardVar - The global variable for the stack guard.
52e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    GlobalVariable *StackGuardVar;
53e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
54e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    Function *F;
55e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    Module *M;
56e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
57e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    /// InsertStackProtectorPrologue - Insert code into the entry block that
58e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    /// stores the __stack_chk_guard variable onto the stack.
59e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    void InsertStackProtectorPrologue();
60e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
61e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    /// InsertStackProtectorEpilogue - Insert code before the return
62e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    /// instructions checking the stack value that was stored in the
63e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    /// prologue. If it isn't the same as the original value, then call a
64e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    /// "failure" function.
65e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    void InsertStackProtectorEpilogue();
66e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
67e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    /// CreateFailBB - Create a basic block to jump to when the stack protector
68e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    /// check fails.
69e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    void CreateFailBB();
70e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
71e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    /// RequiresStackProtector - Check whether or not this function needs a
72e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    /// stack protector based upon the stack protector level.
73e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    bool RequiresStackProtector();
74e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  public:
75e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    static char ID;             // Pass identification, replacement for typeid.
76e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    StackProtector(int lvl = 0) : FunctionPass(&ID), Level(lvl), FailBB(0) {}
77e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
78e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott    virtual bool runOnFunction(Function &Fn);
79e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  };
80e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott} // end anonymous namespace
81e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
82e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottchar StackProtector::ID = 0;
83e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottstatic RegisterPass<StackProtector>
84e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick ScottX("stack-protector", "Insert stack protectors");
85e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
86e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick ScottFunctionPass *llvm::createStackProtectorPass(int lvl) {
87e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return new StackProtector(lvl);
88e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
89e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
90e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottbool StackProtector::runOnFunction(Function &Fn) {
91e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  F = &Fn;
92e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  M = F->getParent();
93e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
94e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  if (!RequiresStackProtector()) return false;
95e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
96e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  InsertStackProtectorPrologue();
97e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  InsertStackProtectorEpilogue();
98e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
99e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  // Cleanup.
100e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  FailBB = 0;
101e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  StackProtFrameSlot = 0;
102e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  StackGuardVar = 0;
103e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  return true;
104e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott}
105e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
106e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott/// InsertStackProtectorPrologue - Insert code into the entry block that stores
107e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott/// the __stack_chk_guard variable onto the stack.
108e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scottvoid StackProtector::InsertStackProtectorPrologue() {
109e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  BasicBlock &Entry = F->getEntryBlock();
110e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  Instruction &InsertPt = Entry.front();
111e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
112e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  const char *StackGuardStr = "__stack_chk_guard";
113e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  StackGuardVar = M->getNamedGlobal(StackGuardStr);
114e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott
115e46c9386c4f79aa40185f79a19fc5b2a7ef528b3Patrick Scott  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
229