diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2015-09-10 02:17:40 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2015-09-10 02:17:40 +0000 |
commit | 2c7f7e31c4c0afc84f8614a48ef7e1449b458c58 (patch) | |
tree | c086262a5904b3d67a23e8baa1d5ae186989ad56 /clang/lib/CodeGen/CGExpr.cpp | |
parent | d3b904d440fee3c869d8c8a2c33dffd8bc82b384 (diff) | |
download | bcm5719-llvm-2c7f7e31c4c0afc84f8614a48ef7e1449b458c58.tar.gz bcm5719-llvm-2c7f7e31c4c0afc84f8614a48ef7e1449b458c58.zip |
CFI: Introduce -fsanitize=cfi-icall flag.
This flag causes the compiler to emit bit set entries for functions as well
as runtime bitset checks at indirect call sites. Depends on the new function
bitset mechanism.
Differential Revision: http://reviews.llvm.org/D11857
llvm-svn: 247238
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 8339444c20e..5e6c4de4087 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -3780,6 +3780,29 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee, } } + // If we are checking indirect calls and this call is indirect, check that the + // function pointer is a member of the bit set for the function type. + if (SanOpts.has(SanitizerKind::CFIICall) && + (!TargetDecl || !isa<FunctionDecl>(TargetDecl))) { + SanitizerScope SanScope(this); + + llvm::Value *BitSetName = llvm::MetadataAsValue::get( + getLLVMContext(), + CGM.CreateMetadataIdentifierForType(QualType(FnType, 0))); + + llvm::Value *CastedCallee = Builder.CreateBitCast(Callee, Int8PtrTy); + llvm::Value *BitSetTest = + Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::bitset_test), + {CastedCallee, BitSetName}); + + llvm::Constant *StaticData[] = { + EmitCheckSourceLocation(E->getLocStart()), + EmitCheckTypeDescriptor(QualType(FnType, 0)), + }; + EmitCheck(std::make_pair(BitSetTest, SanitizerKind::CFIICall), + "cfi_bad_icall", StaticData, CastedCallee); + } + CallArgList Args; if (Chain) Args.add(RValue::get(Builder.CreateBitCast(Chain, CGM.VoidPtrTy)), |