Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(800)

Side by Side Diff: lib/Transforms/MinSFI/SandboxIndirectCalls.cpp

Issue 1151093004: Changes from 3.7 merge to files not in upstream (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-llvm.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 //===- SandboxIndirectCalls.cpp - Apply CFI to indirect function calls ----===// 1 //===- SandboxIndirectCalls.cpp - Apply CFI to indirect function calls ----===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // The LLVM Compiler Infrastructure
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This is a pass which applies basic control-flow integrity enforcement to 10 // This is a pass which applies basic control-flow integrity enforcement to
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 }; 60 };
61 } // namespace 61 } // namespace
62 62
63 static inline size_t RoundToPowerOf2(size_t n) { 63 static inline size_t RoundToPowerOf2(size_t n) {
64 if (isPowerOf2_64(n)) 64 if (isPowerOf2_64(n))
65 return n; 65 return n;
66 else 66 else
67 return NextPowerOf2(n); 67 return NextPowerOf2(n);
68 } 68 }
69 69
70 static inline bool IsPtrToIntUse(const Function::user_iterator &FuncUser) { 70 static inline bool IsPtrToIntUse(const Use &FuncUse) {
71 if (isa<PtrToIntInst>(*FuncUser)) 71 if (isa<PtrToIntInst>(FuncUse.getUser()))
72 return true; 72 return true;
73 else if (ConstantExpr *Expr = dyn_cast<ConstantExpr>(*FuncUser)) 73 else if (auto *Expr = dyn_cast<ConstantExpr>(FuncUse.getUser()))
74 return Expr->getOpcode() == Instruction::PtrToInt; 74 return Expr->getOpcode() == Instruction::PtrToInt;
75 else 75 else
76 return false; 76 return false;
77 } 77 }
78 78
79 // Function use is a direct call if the user is a call instruction and 79 // Function use is a direct call if the user is a call instruction and
80 // the function is its last operand. 80 // the function is its last operand.
81 static inline bool IsDirectCallUse(const Function::user_iterator &FuncUser) { 81 static inline bool IsDirectCallUse(const Use &FuncUse) {
82 if (CallInst *Call = dyn_cast<CallInst>(*FuncUser)) 82 if (auto *Call = dyn_cast<CallInst>(FuncUse.getUser())) {
83 return FuncUser.getOperandNo() == Call->getNumArgOperands(); 83 return FuncUse.getOperandNo() == Call->getNumOperands() - 1;
84 else 84 }
85 return false; 85 return false;
86 } 86 }
87 87
88 bool SandboxIndirectCalls::runOnModule(Module &M) { 88 bool SandboxIndirectCalls::runOnModule(Module &M) {
89 typedef SmallVector<Constant*, 16> FunctionVector; 89 typedef SmallVector<Constant*, 16> FunctionVector;
90 DataLayout DL(&M); 90 DataLayout DL(&M);
91 Type *I32 = Type::getInt32Ty(M.getContext()); 91 Type *I32 = Type::getInt32Ty(M.getContext());
92 Type *IntPtrType = DL.getIntPtrType(M.getContext()); 92 Type *IntPtrType = DL.getIntPtrType(M.getContext());
93 93
94 // First, we find all address-taken functions and assign each an index. 94 // First, we find all address-taken functions and assign each an index.
95 // Pointers in code are then immediately replaced with these indices, even 95 // Pointers in code are then immediately replaced with these indices, even
96 // though the tables have not been created yet. 96 // though the tables have not been created yet.
97 FunctionVector AddrTakenFuncs; 97 FunctionVector AddrTakenFuncs;
98 for (Module::iterator Func = M.begin(), E = M.end(); Func != E; ++Func) { 98 for (Module::iterator Func = M.begin(), E = M.end(); Func != E; ++Func) {
99 bool HasIndirectUse = false; 99 bool HasIndirectUse = false;
100 Constant *Index = ConstantInt::get(IntPtrType, AddrTakenFuncs.size() + 1); 100 Constant *Index = ConstantInt::get(IntPtrType, AddrTakenFuncs.size() + 1);
101 for (Function::user_iterator User = Func->user_begin(), 101 for (auto &Use : Func->uses()) {
102 E = Func->user_end(); 102 if (IsPtrToIntUse(Use)) {
103 User != E; ++User) {
104 if (IsPtrToIntUse(User)) {
105 HasIndirectUse = true; 103 HasIndirectUse = true;
106 (*User)->replaceAllUsesWith(Index); 104 Use.getUser()->replaceAllUsesWith(Index);
107 if (Instruction *UserInst = dyn_cast<Instruction>(*User)) 105 if (auto *UserInst = dyn_cast<Instruction>(Use.getUser()))
108 UserInst->eraseFromParent(); 106 UserInst->eraseFromParent();
109 } else if (!IsDirectCallUse(User)) { 107 } else if (!IsDirectCallUse(Use)) {
110 report_fatal_error("SandboxIndirectCalls: Invalid reference to " 108 report_fatal_error("SandboxIndirectCalls: Invalid reference to "
111 "function @" + Func->getName()); 109 "function @" + Func->getName());
112 } 110 }
113 } 111 }
114 112
115 if (HasIndirectUse) 113 if (HasIndirectUse)
116 AddrTakenFuncs.push_back(Func); 114 AddrTakenFuncs.push_back(Func);
117 } 115 }
118 116
119 // Return if no address-taken functions have been found. 117 // Return if no address-taken functions have been found.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 if (IntToPtrInst *Cast = dyn_cast<IntToPtrInst>(Callee)) { 167 if (IntToPtrInst *Cast = dyn_cast<IntToPtrInst>(Callee)) {
170 Value *FuncIndex = Cast->getOperand(0); 168 Value *FuncIndex = Cast->getOperand(0);
171 PointerType *FuncType = cast<PointerType>(Cast->getType()); 169 PointerType *FuncType = cast<PointerType>(Cast->getType());
172 Constant *GlobalVar = TableGlobals[FuncType]; 170 Constant *GlobalVar = TableGlobals[FuncType];
173 171
174 Value *FuncPtr; 172 Value *FuncPtr;
175 if (GlobalVar) { 173 if (GlobalVar) {
176 Instruction *MaskedIndex = 174 Instruction *MaskedIndex =
177 BinaryOperator::CreateAnd(FuncIndex, IndexMask, "", Call); 175 BinaryOperator::CreateAnd(FuncIndex, IndexMask, "", Call);
178 Value *Indexes[] = { ConstantInt::get(I32, 0), MaskedIndex }; 176 Value *Indexes[] = { ConstantInt::get(I32, 0), MaskedIndex };
179 Instruction *TableElemPtr = 177 Instruction *TableElemPtr = GetElementPtrInst::Create(
180 GetElementPtrInst::Create(GlobalVar, Indexes, "", Call); 178 cast<PointerType>(GlobalVar->getType())->getElementType(),
179 GlobalVar, Indexes, "", Call);
181 FuncPtr = CopyDebug(new LoadInst(TableElemPtr, "", Call), Cast); 180 FuncPtr = CopyDebug(new LoadInst(TableElemPtr, "", Call), Cast);
182 } else { 181 } else {
183 // There is no function table for this signature, i.e. the module 182 // There is no function table for this signature, i.e. the module
184 // does not contain a function which could be called at this site. 183 // does not contain a function which could be called at this site.
185 // We replace the pointer with a null and put a trap in front of 184 // We replace the pointer with a null and put a trap in front of
186 // the call because it should never be called. 185 // the call because it should never be called.
187 CallInst::Create(Intrinsic::getDeclaration(&M, Intrinsic::trap), 186 CallInst::Create(Intrinsic::getDeclaration(&M, Intrinsic::trap),
188 "", Call); 187 "", Call);
189 FuncPtr = ConstantPointerNull::get(FuncType); 188 FuncPtr = ConstantPointerNull::get(FuncType);
190 } 189 }
(...skipping 10 matching lines...) Expand all
201 return true; 200 return true;
202 } 201 }
203 202
204 char SandboxIndirectCalls::ID = 0; 203 char SandboxIndirectCalls::ID = 0;
205 INITIALIZE_PASS(SandboxIndirectCalls, "minsfi-sandbox-indirect-calls", 204 INITIALIZE_PASS(SandboxIndirectCalls, "minsfi-sandbox-indirect-calls",
206 "Add CFI to indirect calls", false, false) 205 "Add CFI to indirect calls", false, false)
207 206
208 ModulePass *llvm::createSandboxIndirectCallsPass() { 207 ModulePass *llvm::createSandboxIndirectCallsPass() {
209 return new SandboxIndirectCalls(); 208 return new SandboxIndirectCalls();
210 } 209 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698