Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 1 | //===-- SafeStack.cpp - Safe Stack 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 splits the stack into the safe stack (kept as-is for LLVM backend) |
| 11 | // and the unsafe stack (explicitly allocated and managed through the runtime |
| 12 | // support library). |
| 13 | // |
| 14 | // http://clang.llvm.org/docs/SafeStack.html |
| 15 | // |
| 16 | //===----------------------------------------------------------------------===// |
| 17 | |
| 18 | #include "llvm/Transforms/Instrumentation.h" |
| 19 | #include "llvm/ADT/Statistic.h" |
| 20 | #include "llvm/ADT/Triple.h" |
| 21 | #include "llvm/Analysis/AliasAnalysis.h" |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 22 | #include "llvm/CodeGen/Passes.h" |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 23 | #include "llvm/IR/Constants.h" |
| 24 | #include "llvm/IR/DataLayout.h" |
| 25 | #include "llvm/IR/DerivedTypes.h" |
| 26 | #include "llvm/IR/DIBuilder.h" |
| 27 | #include "llvm/IR/Function.h" |
| 28 | #include "llvm/IR/InstIterator.h" |
| 29 | #include "llvm/IR/Instructions.h" |
| 30 | #include "llvm/IR/IntrinsicInst.h" |
| 31 | #include "llvm/IR/Intrinsics.h" |
| 32 | #include "llvm/IR/IRBuilder.h" |
| 33 | #include "llvm/IR/Module.h" |
| 34 | #include "llvm/Pass.h" |
| 35 | #include "llvm/Support/CommandLine.h" |
| 36 | #include "llvm/Support/Debug.h" |
| 37 | #include "llvm/Support/Format.h" |
| 38 | #include "llvm/Support/MathExtras.h" |
| 39 | #include "llvm/Support/raw_os_ostream.h" |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 40 | #include "llvm/Target/TargetLowering.h" |
| 41 | #include "llvm/Target/TargetSubtargetInfo.h" |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 42 | #include "llvm/Transforms/Utils/Local.h" |
| 43 | #include "llvm/Transforms/Utils/ModuleUtils.h" |
| 44 | |
| 45 | using namespace llvm; |
| 46 | |
| 47 | #define DEBUG_TYPE "safestack" |
| 48 | |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 49 | static const char *const kUnsafeStackPtrVar = "__safestack_unsafe_stack_ptr"; |
| 50 | static const char *const kUnsafeStackPtrAddrFn = "__safestack_pointer_address"; |
| 51 | |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 52 | namespace llvm { |
| 53 | |
| 54 | STATISTIC(NumFunctions, "Total number of functions"); |
| 55 | STATISTIC(NumUnsafeStackFunctions, "Number of functions with unsafe stack"); |
| 56 | STATISTIC(NumUnsafeStackRestorePointsFunctions, |
| 57 | "Number of functions that use setjmp or exceptions"); |
| 58 | |
| 59 | STATISTIC(NumAllocas, "Total number of allocas"); |
| 60 | STATISTIC(NumUnsafeStaticAllocas, "Number of unsafe static allocas"); |
| 61 | STATISTIC(NumUnsafeDynamicAllocas, "Number of unsafe dynamic allocas"); |
| 62 | STATISTIC(NumUnsafeStackRestorePoints, "Number of setjmps and landingpads"); |
| 63 | |
| 64 | } // namespace llvm |
| 65 | |
| 66 | namespace { |
| 67 | |
| 68 | /// Check whether a given alloca instruction (AI) should be put on the safe |
| 69 | /// stack or not. The function analyzes all uses of AI and checks whether it is |
| 70 | /// only accessed in a memory safe way (as decided statically). |
| 71 | bool IsSafeStackAlloca(const AllocaInst *AI) { |
| 72 | // Go through all uses of this alloca and check whether all accesses to the |
| 73 | // allocated object are statically known to be memory safe and, hence, the |
| 74 | // object can be placed on the safe stack. |
| 75 | |
| 76 | SmallPtrSet<const Value *, 16> Visited; |
| 77 | SmallVector<const Instruction *, 8> WorkList; |
| 78 | WorkList.push_back(AI); |
| 79 | |
| 80 | // A DFS search through all uses of the alloca in bitcasts/PHI/GEPs/etc. |
| 81 | while (!WorkList.empty()) { |
| 82 | const Instruction *V = WorkList.pop_back_val(); |
| 83 | for (const Use &UI : V->uses()) { |
| 84 | auto I = cast<const Instruction>(UI.getUser()); |
| 85 | assert(V == UI.get()); |
| 86 | |
| 87 | switch (I->getOpcode()) { |
| 88 | case Instruction::Load: |
| 89 | // Loading from a pointer is safe. |
| 90 | break; |
| 91 | case Instruction::VAArg: |
| 92 | // "va-arg" from a pointer is safe. |
| 93 | break; |
| 94 | case Instruction::Store: |
| 95 | if (V == I->getOperand(0)) |
| 96 | // Stored the pointer - conservatively assume it may be unsafe. |
| 97 | return false; |
| 98 | // Storing to the pointee is safe. |
| 99 | break; |
| 100 | |
| 101 | case Instruction::GetElementPtr: |
| 102 | if (!cast<const GetElementPtrInst>(I)->hasAllConstantIndices()) |
| 103 | // GEP with non-constant indices can lead to memory errors. |
| 104 | // This also applies to inbounds GEPs, as the inbounds attribute |
| 105 | // represents an assumption that the address is in bounds, rather than |
| 106 | // an assertion that it is. |
| 107 | return false; |
| 108 | |
| 109 | // We assume that GEP on static alloca with constant indices is safe, |
| 110 | // otherwise a compiler would detect it and warn during compilation. |
| 111 | |
| 112 | if (!isa<const ConstantInt>(AI->getArraySize())) |
| 113 | // However, if the array size itself is not constant, the access |
| 114 | // might still be unsafe at runtime. |
| 115 | return false; |
| 116 | |
| 117 | /* fallthrough */ |
| 118 | |
| 119 | case Instruction::BitCast: |
| 120 | case Instruction::IntToPtr: |
| 121 | case Instruction::PHI: |
| 122 | case Instruction::PtrToInt: |
| 123 | case Instruction::Select: |
| 124 | // The object can be safe or not, depending on how the result of the |
| 125 | // instruction is used. |
| 126 | if (Visited.insert(I).second) |
| 127 | WorkList.push_back(cast<const Instruction>(I)); |
| 128 | break; |
| 129 | |
| 130 | case Instruction::Call: |
| 131 | case Instruction::Invoke: { |
| 132 | // FIXME: add support for memset and memcpy intrinsics. |
| 133 | ImmutableCallSite CS(I); |
| 134 | |
| 135 | // LLVM 'nocapture' attribute is only set for arguments whose address |
| 136 | // is not stored, passed around, or used in any other non-trivial way. |
| 137 | // We assume that passing a pointer to an object as a 'nocapture' |
| 138 | // argument is safe. |
| 139 | // FIXME: a more precise solution would require an interprocedural |
| 140 | // analysis here, which would look at all uses of an argument inside |
| 141 | // the function being called. |
| 142 | ImmutableCallSite::arg_iterator B = CS.arg_begin(), E = CS.arg_end(); |
| 143 | for (ImmutableCallSite::arg_iterator A = B; A != E; ++A) |
| 144 | if (A->get() == V && !CS.doesNotCapture(A - B)) |
| 145 | // The parameter is not marked 'nocapture' - unsafe. |
| 146 | return false; |
| 147 | continue; |
| 148 | } |
| 149 | |
| 150 | default: |
| 151 | // The object is unsafe if it is used in any other way. |
| 152 | return false; |
| 153 | } |
| 154 | } |
| 155 | } |
| 156 | |
| 157 | // All uses of the alloca are safe, we can place it on the safe stack. |
| 158 | return true; |
| 159 | } |
| 160 | |
| 161 | /// The SafeStack pass splits the stack of each function into the |
| 162 | /// safe stack, which is only accessed through memory safe dereferences |
| 163 | /// (as determined statically), and the unsafe stack, which contains all |
| 164 | /// local variables that are accessed in unsafe ways. |
| 165 | class SafeStack : public FunctionPass { |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 166 | const TargetMachine *TM; |
| 167 | const TargetLoweringBase *TLI; |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 168 | const DataLayout *DL; |
| 169 | |
| 170 | Type *StackPtrTy; |
| 171 | Type *IntPtrTy; |
| 172 | Type *Int32Ty; |
| 173 | Type *Int8Ty; |
| 174 | |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 175 | Value *UnsafeStackPtr = nullptr; |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 176 | |
| 177 | /// Unsafe stack alignment. Each stack frame must ensure that the stack is |
| 178 | /// aligned to this value. We need to re-align the unsafe stack if the |
| 179 | /// alignment of any object on the stack exceeds this value. |
| 180 | /// |
| 181 | /// 16 seems like a reasonable upper bound on the alignment of objects that we |
| 182 | /// might expect to appear on the stack on most common targets. |
| 183 | enum { StackAlignment = 16 }; |
| 184 | |
| 185 | /// \brief Build a constant representing a pointer to the unsafe stack |
| 186 | /// pointer. |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 187 | Value *getOrCreateUnsafeStackPtr(IRBuilder<> &IRB, Function &F); |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 188 | |
| 189 | /// \brief Find all static allocas, dynamic allocas, return instructions and |
| 190 | /// stack restore points (exception unwind blocks and setjmp calls) in the |
| 191 | /// given function and append them to the respective vectors. |
| 192 | void findInsts(Function &F, SmallVectorImpl<AllocaInst *> &StaticAllocas, |
| 193 | SmallVectorImpl<AllocaInst *> &DynamicAllocas, |
| 194 | SmallVectorImpl<ReturnInst *> &Returns, |
| 195 | SmallVectorImpl<Instruction *> &StackRestorePoints); |
| 196 | |
| 197 | /// \brief Allocate space for all static allocas in \p StaticAllocas, |
| 198 | /// replace allocas with pointers into the unsafe stack and generate code to |
| 199 | /// restore the stack pointer before all return instructions in \p Returns. |
| 200 | /// |
| 201 | /// \returns A pointer to the top of the unsafe stack after all unsafe static |
| 202 | /// allocas are allocated. |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 203 | Value *moveStaticAllocasToUnsafeStack(IRBuilder<> &IRB, Function &F, |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 204 | ArrayRef<AllocaInst *> StaticAllocas, |
| 205 | ArrayRef<ReturnInst *> Returns); |
| 206 | |
| 207 | /// \brief Generate code to restore the stack after all stack restore points |
| 208 | /// in \p StackRestorePoints. |
| 209 | /// |
| 210 | /// \returns A local variable in which to maintain the dynamic top of the |
| 211 | /// unsafe stack if needed. |
| 212 | AllocaInst * |
| 213 | createStackRestorePoints(Function &F, |
| 214 | ArrayRef<Instruction *> StackRestorePoints, |
| 215 | Value *StaticTop, bool NeedDynamicTop); |
| 216 | |
| 217 | /// \brief Replace all allocas in \p DynamicAllocas with code to allocate |
| 218 | /// space dynamically on the unsafe stack and store the dynamic unsafe stack |
| 219 | /// top to \p DynamicTop if non-null. |
| 220 | void moveDynamicAllocasToUnsafeStack(Function &F, Value *UnsafeStackPtr, |
| 221 | AllocaInst *DynamicTop, |
| 222 | ArrayRef<AllocaInst *> DynamicAllocas); |
| 223 | |
| 224 | public: |
| 225 | static char ID; // Pass identification, replacement for typeid. |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 226 | SafeStack(const TargetMachine *TM) |
| 227 | : FunctionPass(ID), TM(TM), TLI(nullptr), DL(nullptr) { |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 228 | initializeSafeStackPass(*PassRegistry::getPassRegistry()); |
| 229 | } |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 230 | SafeStack() : SafeStack(nullptr) {} |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 231 | |
Hans Wennborg | aa15bff | 2015-09-10 16:49:58 +0000 | [diff] [blame] | 232 | void getAnalysisUsage(AnalysisUsage &AU) const override { |
Chandler Carruth | 7b560d4 | 2015-09-09 17:55:00 +0000 | [diff] [blame] | 233 | AU.addRequired<AAResultsWrapperPass>(); |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 234 | } |
| 235 | |
Hans Wennborg | aa15bff | 2015-09-10 16:49:58 +0000 | [diff] [blame] | 236 | bool doInitialization(Module &M) override { |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 237 | DL = &M.getDataLayout(); |
| 238 | |
| 239 | StackPtrTy = Type::getInt8PtrTy(M.getContext()); |
| 240 | IntPtrTy = DL->getIntPtrType(M.getContext()); |
| 241 | Int32Ty = Type::getInt32Ty(M.getContext()); |
| 242 | Int8Ty = Type::getInt8Ty(M.getContext()); |
| 243 | |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 244 | return false; |
| 245 | } |
| 246 | |
Hans Wennborg | aa15bff | 2015-09-10 16:49:58 +0000 | [diff] [blame] | 247 | bool runOnFunction(Function &F) override; |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 248 | }; // class SafeStack |
| 249 | |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 250 | Value *SafeStack::getOrCreateUnsafeStackPtr(IRBuilder<> &IRB, Function &F) { |
| 251 | Module &M = *F.getParent(); |
| 252 | Triple TargetTriple(M.getTargetTriple()); |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 253 | |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 254 | unsigned Offset; |
| 255 | unsigned AddressSpace; |
| 256 | // Check if the target keeps the unsafe stack pointer at a fixed offset. |
| 257 | if (TLI && TLI->getSafeStackPointerLocation(Offset, AddressSpace)) { |
| 258 | Constant *OffsetVal = |
| 259 | ConstantInt::get(Type::getInt32Ty(F.getContext()), Offset); |
| 260 | return ConstantExpr::getIntToPtr(OffsetVal, |
| 261 | StackPtrTy->getPointerTo(AddressSpace)); |
Evgeniy Stepanov | ce2e16f | 2015-09-23 01:03:51 +0000 | [diff] [blame] | 262 | } |
Evgeniy Stepanov | 8d0e301 | 2015-09-23 01:23:22 +0000 | [diff] [blame] | 263 | |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 264 | // Android provides a libc function that returns the stack pointer address. |
| 265 | if (TargetTriple.getEnvironment() == llvm::Triple::Android) { |
| 266 | Value *Fn = M.getOrInsertFunction(kUnsafeStackPtrAddrFn, |
| 267 | StackPtrTy->getPointerTo(0), nullptr); |
| 268 | return IRB.CreateCall(Fn); |
| 269 | } else { |
| 270 | // Otherwise, declare a thread-local variable with a magic name. |
| 271 | auto UnsafeStackPtr = |
| 272 | dyn_cast_or_null<GlobalVariable>(M.getNamedValue(kUnsafeStackPtrVar)); |
| 273 | |
| 274 | if (!UnsafeStackPtr) { |
| 275 | // The global variable is not defined yet, define it ourselves. |
| 276 | // We use the initial-exec TLS model because we do not support the |
| 277 | // variable living anywhere other than in the main executable. |
| 278 | UnsafeStackPtr = new GlobalVariable( |
| 279 | /*Module=*/M, /*Type=*/StackPtrTy, |
| 280 | /*isConstant=*/false, /*Linkage=*/GlobalValue::ExternalLinkage, |
| 281 | /*Initializer=*/0, /*Name=*/kUnsafeStackPtrVar, |
| 282 | /*InsertBefore=*/nullptr, |
| 283 | /*ThreadLocalMode=*/GlobalValue::InitialExecTLSModel); |
| 284 | } else { |
| 285 | // The variable exists, check its type and attributes. |
| 286 | if (UnsafeStackPtr->getValueType() != StackPtrTy) { |
| 287 | report_fatal_error(Twine(kUnsafeStackPtrVar) + " must have void* type"); |
| 288 | } |
| 289 | |
| 290 | if (!UnsafeStackPtr->isThreadLocal()) { |
| 291 | report_fatal_error(Twine(kUnsafeStackPtrVar) + " must be thread-local"); |
| 292 | } |
| 293 | } |
| 294 | return UnsafeStackPtr; |
| 295 | } |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 296 | } |
| 297 | |
| 298 | void SafeStack::findInsts(Function &F, |
| 299 | SmallVectorImpl<AllocaInst *> &StaticAllocas, |
| 300 | SmallVectorImpl<AllocaInst *> &DynamicAllocas, |
| 301 | SmallVectorImpl<ReturnInst *> &Returns, |
| 302 | SmallVectorImpl<Instruction *> &StackRestorePoints) { |
Nico Rieck | 7819951 | 2015-08-06 19:10:45 +0000 | [diff] [blame] | 303 | for (Instruction &I : instructions(&F)) { |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 304 | if (auto AI = dyn_cast<AllocaInst>(&I)) { |
| 305 | ++NumAllocas; |
| 306 | |
| 307 | if (IsSafeStackAlloca(AI)) |
| 308 | continue; |
| 309 | |
| 310 | if (AI->isStaticAlloca()) { |
| 311 | ++NumUnsafeStaticAllocas; |
| 312 | StaticAllocas.push_back(AI); |
| 313 | } else { |
| 314 | ++NumUnsafeDynamicAllocas; |
| 315 | DynamicAllocas.push_back(AI); |
| 316 | } |
| 317 | } else if (auto RI = dyn_cast<ReturnInst>(&I)) { |
| 318 | Returns.push_back(RI); |
| 319 | } else if (auto CI = dyn_cast<CallInst>(&I)) { |
| 320 | // setjmps require stack restore. |
| 321 | if (CI->getCalledFunction() && CI->canReturnTwice()) |
| 322 | StackRestorePoints.push_back(CI); |
| 323 | } else if (auto LP = dyn_cast<LandingPadInst>(&I)) { |
| 324 | // Exception landing pads require stack restore. |
| 325 | StackRestorePoints.push_back(LP); |
| 326 | } else if (auto II = dyn_cast<IntrinsicInst>(&I)) { |
| 327 | if (II->getIntrinsicID() == Intrinsic::gcroot) |
| 328 | llvm::report_fatal_error( |
| 329 | "gcroot intrinsic not compatible with safestack attribute"); |
| 330 | } |
| 331 | } |
| 332 | } |
| 333 | |
| 334 | AllocaInst * |
| 335 | SafeStack::createStackRestorePoints(Function &F, |
| 336 | ArrayRef<Instruction *> StackRestorePoints, |
| 337 | Value *StaticTop, bool NeedDynamicTop) { |
| 338 | if (StackRestorePoints.empty()) |
| 339 | return nullptr; |
| 340 | |
| 341 | IRBuilder<> IRB(StaticTop |
| 342 | ? cast<Instruction>(StaticTop)->getNextNode() |
| 343 | : (Instruction *)F.getEntryBlock().getFirstInsertionPt()); |
| 344 | |
| 345 | // We need the current value of the shadow stack pointer to restore |
| 346 | // after longjmp or exception catching. |
| 347 | |
| 348 | // FIXME: On some platforms this could be handled by the longjmp/exception |
| 349 | // runtime itself. |
| 350 | |
| 351 | AllocaInst *DynamicTop = nullptr; |
| 352 | if (NeedDynamicTop) |
| 353 | // If we also have dynamic alloca's, the stack pointer value changes |
| 354 | // throughout the function. For now we store it in an alloca. |
| 355 | DynamicTop = IRB.CreateAlloca(StackPtrTy, /*ArraySize=*/nullptr, |
| 356 | "unsafe_stack_dynamic_ptr"); |
| 357 | |
| 358 | if (!StaticTop) |
| 359 | // We need the original unsafe stack pointer value, even if there are |
| 360 | // no unsafe static allocas. |
| 361 | StaticTop = IRB.CreateLoad(UnsafeStackPtr, false, "unsafe_stack_ptr"); |
| 362 | |
| 363 | if (NeedDynamicTop) |
| 364 | IRB.CreateStore(StaticTop, DynamicTop); |
| 365 | |
| 366 | // Restore current stack pointer after longjmp/exception catch. |
| 367 | for (Instruction *I : StackRestorePoints) { |
| 368 | ++NumUnsafeStackRestorePoints; |
| 369 | |
| 370 | IRB.SetInsertPoint(cast<Instruction>(I->getNextNode())); |
| 371 | Value *CurrentTop = DynamicTop ? IRB.CreateLoad(DynamicTop) : StaticTop; |
| 372 | IRB.CreateStore(CurrentTop, UnsafeStackPtr); |
| 373 | } |
| 374 | |
| 375 | return DynamicTop; |
| 376 | } |
| 377 | |
| 378 | Value * |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 379 | SafeStack::moveStaticAllocasToUnsafeStack(IRBuilder<> &IRB, Function &F, |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 380 | ArrayRef<AllocaInst *> StaticAllocas, |
| 381 | ArrayRef<ReturnInst *> Returns) { |
| 382 | if (StaticAllocas.empty()) |
| 383 | return nullptr; |
| 384 | |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 385 | DIBuilder DIB(*F.getParent()); |
| 386 | |
| 387 | // We explicitly compute and set the unsafe stack layout for all unsafe |
| 388 | // static alloca instructions. We save the unsafe "base pointer" in the |
| 389 | // prologue into a local variable and restore it in the epilogue. |
| 390 | |
| 391 | // Load the current stack pointer (we'll also use it as a base pointer). |
| 392 | // FIXME: use a dedicated register for it ? |
| 393 | Instruction *BasePointer = |
| 394 | IRB.CreateLoad(UnsafeStackPtr, false, "unsafe_stack_ptr"); |
| 395 | assert(BasePointer->getType() == StackPtrTy); |
| 396 | |
| 397 | for (ReturnInst *RI : Returns) { |
| 398 | IRB.SetInsertPoint(RI); |
| 399 | IRB.CreateStore(BasePointer, UnsafeStackPtr); |
| 400 | } |
| 401 | |
| 402 | // Compute maximum alignment among static objects on the unsafe stack. |
| 403 | unsigned MaxAlignment = 0; |
| 404 | for (AllocaInst *AI : StaticAllocas) { |
| 405 | Type *Ty = AI->getAllocatedType(); |
| 406 | unsigned Align = |
| 407 | std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment()); |
| 408 | if (Align > MaxAlignment) |
| 409 | MaxAlignment = Align; |
| 410 | } |
| 411 | |
| 412 | if (MaxAlignment > StackAlignment) { |
| 413 | // Re-align the base pointer according to the max requested alignment. |
| 414 | assert(isPowerOf2_32(MaxAlignment)); |
| 415 | IRB.SetInsertPoint(cast<Instruction>(BasePointer->getNextNode())); |
| 416 | BasePointer = cast<Instruction>(IRB.CreateIntToPtr( |
| 417 | IRB.CreateAnd(IRB.CreatePtrToInt(BasePointer, IntPtrTy), |
| 418 | ConstantInt::get(IntPtrTy, ~uint64_t(MaxAlignment - 1))), |
| 419 | StackPtrTy)); |
| 420 | } |
| 421 | |
| 422 | // Allocate space for every unsafe static AllocaInst on the unsafe stack. |
| 423 | int64_t StaticOffset = 0; // Current stack top. |
| 424 | for (AllocaInst *AI : StaticAllocas) { |
| 425 | IRB.SetInsertPoint(AI); |
| 426 | |
| 427 | auto CArraySize = cast<ConstantInt>(AI->getArraySize()); |
| 428 | Type *Ty = AI->getAllocatedType(); |
| 429 | |
| 430 | uint64_t Size = DL->getTypeAllocSize(Ty) * CArraySize->getZExtValue(); |
| 431 | if (Size == 0) |
| 432 | Size = 1; // Don't create zero-sized stack objects. |
| 433 | |
| 434 | // Ensure the object is properly aligned. |
| 435 | unsigned Align = |
| 436 | std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment()); |
| 437 | |
| 438 | // Add alignment. |
| 439 | // NOTE: we ensure that BasePointer itself is aligned to >= Align. |
| 440 | StaticOffset += Size; |
| 441 | StaticOffset = RoundUpToAlignment(StaticOffset, Align); |
| 442 | |
| 443 | Value *Off = IRB.CreateGEP(BasePointer, // BasePointer is i8* |
| 444 | ConstantInt::get(Int32Ty, -StaticOffset)); |
| 445 | Value *NewAI = IRB.CreateBitCast(Off, AI->getType(), AI->getName()); |
| 446 | if (AI->hasName() && isa<Instruction>(NewAI)) |
| 447 | cast<Instruction>(NewAI)->takeName(AI); |
| 448 | |
| 449 | // Replace alloc with the new location. |
| 450 | replaceDbgDeclareForAlloca(AI, NewAI, DIB, /*Deref=*/true); |
| 451 | AI->replaceAllUsesWith(NewAI); |
| 452 | AI->eraseFromParent(); |
| 453 | } |
| 454 | |
| 455 | // Re-align BasePointer so that our callees would see it aligned as |
| 456 | // expected. |
| 457 | // FIXME: no need to update BasePointer in leaf functions. |
| 458 | StaticOffset = RoundUpToAlignment(StaticOffset, StackAlignment); |
| 459 | |
| 460 | // Update shadow stack pointer in the function epilogue. |
| 461 | IRB.SetInsertPoint(cast<Instruction>(BasePointer->getNextNode())); |
| 462 | |
| 463 | Value *StaticTop = |
| 464 | IRB.CreateGEP(BasePointer, ConstantInt::get(Int32Ty, -StaticOffset), |
| 465 | "unsafe_stack_static_top"); |
| 466 | IRB.CreateStore(StaticTop, UnsafeStackPtr); |
| 467 | return StaticTop; |
| 468 | } |
| 469 | |
| 470 | void SafeStack::moveDynamicAllocasToUnsafeStack( |
| 471 | Function &F, Value *UnsafeStackPtr, AllocaInst *DynamicTop, |
| 472 | ArrayRef<AllocaInst *> DynamicAllocas) { |
| 473 | DIBuilder DIB(*F.getParent()); |
| 474 | |
| 475 | for (AllocaInst *AI : DynamicAllocas) { |
| 476 | IRBuilder<> IRB(AI); |
| 477 | |
| 478 | // Compute the new SP value (after AI). |
| 479 | Value *ArraySize = AI->getArraySize(); |
| 480 | if (ArraySize->getType() != IntPtrTy) |
| 481 | ArraySize = IRB.CreateIntCast(ArraySize, IntPtrTy, false); |
| 482 | |
| 483 | Type *Ty = AI->getAllocatedType(); |
| 484 | uint64_t TySize = DL->getTypeAllocSize(Ty); |
| 485 | Value *Size = IRB.CreateMul(ArraySize, ConstantInt::get(IntPtrTy, TySize)); |
| 486 | |
| 487 | Value *SP = IRB.CreatePtrToInt(IRB.CreateLoad(UnsafeStackPtr), IntPtrTy); |
| 488 | SP = IRB.CreateSub(SP, Size); |
| 489 | |
| 490 | // Align the SP value to satisfy the AllocaInst, type and stack alignments. |
| 491 | unsigned Align = std::max( |
| 492 | std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment()), |
| 493 | (unsigned)StackAlignment); |
| 494 | |
| 495 | assert(isPowerOf2_32(Align)); |
| 496 | Value *NewTop = IRB.CreateIntToPtr( |
| 497 | IRB.CreateAnd(SP, ConstantInt::get(IntPtrTy, ~uint64_t(Align - 1))), |
| 498 | StackPtrTy); |
| 499 | |
| 500 | // Save the stack pointer. |
| 501 | IRB.CreateStore(NewTop, UnsafeStackPtr); |
| 502 | if (DynamicTop) |
| 503 | IRB.CreateStore(NewTop, DynamicTop); |
| 504 | |
| 505 | Value *NewAI = IRB.CreateIntToPtr(SP, AI->getType()); |
| 506 | if (AI->hasName() && isa<Instruction>(NewAI)) |
| 507 | NewAI->takeName(AI); |
| 508 | |
| 509 | replaceDbgDeclareForAlloca(AI, NewAI, DIB, /*Deref=*/true); |
| 510 | AI->replaceAllUsesWith(NewAI); |
| 511 | AI->eraseFromParent(); |
| 512 | } |
| 513 | |
| 514 | if (!DynamicAllocas.empty()) { |
| 515 | // Now go through the instructions again, replacing stacksave/stackrestore. |
| 516 | for (inst_iterator It = inst_begin(&F), Ie = inst_end(&F); It != Ie;) { |
| 517 | Instruction *I = &*(It++); |
| 518 | auto II = dyn_cast<IntrinsicInst>(I); |
| 519 | if (!II) |
| 520 | continue; |
| 521 | |
| 522 | if (II->getIntrinsicID() == Intrinsic::stacksave) { |
| 523 | IRBuilder<> IRB(II); |
| 524 | Instruction *LI = IRB.CreateLoad(UnsafeStackPtr); |
| 525 | LI->takeName(II); |
| 526 | II->replaceAllUsesWith(LI); |
| 527 | II->eraseFromParent(); |
| 528 | } else if (II->getIntrinsicID() == Intrinsic::stackrestore) { |
| 529 | IRBuilder<> IRB(II); |
| 530 | Instruction *SI = IRB.CreateStore(II->getArgOperand(0), UnsafeStackPtr); |
| 531 | SI->takeName(II); |
| 532 | assert(II->use_empty()); |
| 533 | II->eraseFromParent(); |
| 534 | } |
| 535 | } |
| 536 | } |
| 537 | } |
| 538 | |
| 539 | bool SafeStack::runOnFunction(Function &F) { |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 540 | DEBUG(dbgs() << "[SafeStack] Function: " << F.getName() << "\n"); |
| 541 | |
| 542 | if (!F.hasFnAttribute(Attribute::SafeStack)) { |
| 543 | DEBUG(dbgs() << "[SafeStack] safestack is not requested" |
| 544 | " for this function\n"); |
| 545 | return false; |
| 546 | } |
| 547 | |
| 548 | if (F.isDeclaration()) { |
| 549 | DEBUG(dbgs() << "[SafeStack] function definition" |
| 550 | " is not available\n"); |
| 551 | return false; |
| 552 | } |
| 553 | |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 554 | auto AA = &getAnalysis<AAResultsWrapperPass>().getAAResults(); |
| 555 | |
| 556 | TLI = TM ? TM->getSubtargetImpl(F)->getTargetLowering() : nullptr; |
| 557 | |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 558 | { |
| 559 | // Make sure the regular stack protector won't run on this function |
| 560 | // (safestack attribute takes precedence). |
| 561 | AttrBuilder B; |
| 562 | B.addAttribute(Attribute::StackProtect) |
| 563 | .addAttribute(Attribute::StackProtectReq) |
| 564 | .addAttribute(Attribute::StackProtectStrong); |
| 565 | F.removeAttributes( |
| 566 | AttributeSet::FunctionIndex, |
| 567 | AttributeSet::get(F.getContext(), AttributeSet::FunctionIndex, B)); |
| 568 | } |
| 569 | |
| 570 | if (AA->onlyReadsMemory(&F)) { |
| 571 | // XXX: we don't protect against information leak attacks for now. |
| 572 | DEBUG(dbgs() << "[SafeStack] function only reads memory\n"); |
| 573 | return false; |
| 574 | } |
| 575 | |
| 576 | ++NumFunctions; |
| 577 | |
| 578 | SmallVector<AllocaInst *, 16> StaticAllocas; |
| 579 | SmallVector<AllocaInst *, 4> DynamicAllocas; |
| 580 | SmallVector<ReturnInst *, 4> Returns; |
| 581 | |
| 582 | // Collect all points where stack gets unwound and needs to be restored |
| 583 | // This is only necessary because the runtime (setjmp and unwind code) is |
| 584 | // not aware of the unsafe stack and won't unwind/restore it prorerly. |
| 585 | // To work around this problem without changing the runtime, we insert |
| 586 | // instrumentation to restore the unsafe stack pointer when necessary. |
| 587 | SmallVector<Instruction *, 4> StackRestorePoints; |
| 588 | |
| 589 | // Find all static and dynamic alloca instructions that must be moved to the |
| 590 | // unsafe stack, all return instructions and stack restore points. |
| 591 | findInsts(F, StaticAllocas, DynamicAllocas, Returns, StackRestorePoints); |
| 592 | |
| 593 | if (StaticAllocas.empty() && DynamicAllocas.empty() && |
| 594 | StackRestorePoints.empty()) |
| 595 | return false; // Nothing to do in this function. |
| 596 | |
| 597 | if (!StaticAllocas.empty() || !DynamicAllocas.empty()) |
| 598 | ++NumUnsafeStackFunctions; // This function has the unsafe stack. |
| 599 | |
| 600 | if (!StackRestorePoints.empty()) |
| 601 | ++NumUnsafeStackRestorePointsFunctions; |
| 602 | |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 603 | IRBuilder<> IRB(F.begin()->getFirstInsertionPt()); |
| 604 | UnsafeStackPtr = getOrCreateUnsafeStackPtr(IRB, F); |
Peter Collingbourne | de26a91 | 2015-06-22 20:26:54 +0000 | [diff] [blame] | 605 | |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 606 | // The top of the unsafe stack after all unsafe static allocas are allocated. |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 607 | Value *StaticTop = moveStaticAllocasToUnsafeStack(IRB, F, StaticAllocas, Returns); |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 608 | |
| 609 | // Safe stack object that stores the current unsafe stack top. It is updated |
| 610 | // as unsafe dynamic (non-constant-sized) allocas are allocated and freed. |
| 611 | // This is only needed if we need to restore stack pointer after longjmp |
| 612 | // or exceptions, and we have dynamic allocations. |
| 613 | // FIXME: a better alternative might be to store the unsafe stack pointer |
| 614 | // before setjmp / invoke instructions. |
| 615 | AllocaInst *DynamicTop = createStackRestorePoints( |
| 616 | F, StackRestorePoints, StaticTop, !DynamicAllocas.empty()); |
| 617 | |
| 618 | // Handle dynamic allocas. |
| 619 | moveDynamicAllocasToUnsafeStack(F, UnsafeStackPtr, DynamicTop, |
| 620 | DynamicAllocas); |
| 621 | |
| 622 | DEBUG(dbgs() << "[SafeStack] safestack applied\n"); |
| 623 | return true; |
| 624 | } |
| 625 | |
| 626 | } // end anonymous namespace |
| 627 | |
| 628 | char SafeStack::ID = 0; |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 629 | INITIALIZE_TM_PASS_BEGIN(SafeStack, "safe-stack", |
| 630 | "Safe Stack instrumentation pass", false, false) |
| 631 | INITIALIZE_TM_PASS_END(SafeStack, "safe-stack", |
| 632 | "Safe Stack instrumentation pass", false, false) |
Peter Collingbourne | 82437bf | 2015-06-15 21:07:11 +0000 | [diff] [blame] | 633 | |
Evgeniy Stepanov | a2002b0 | 2015-09-23 18:07:56 +0000 | [diff] [blame^] | 634 | FunctionPass *llvm::createSafeStackPass(const llvm::TargetMachine *TM) { |
| 635 | return new SafeStack(TM); |
| 636 | } |