Cross-DSO control flow integrity (Clang part).

Clang-side cross-DSO CFI.

* Adds a command line flag -f[no-]sanitize-cfi-cross-dso.
* Links a runtime library when enabled.
* Emits __cfi_slowpath calls is bitset test fails.
* Emits extra hash-based bitsets for external CFI checks.
* Sets a module flag to enable __cfi_check generation during LTO.

This mode does not yet support diagnostics.

llvm-svn: 255694
This commit is contained in:
Evgeniy Stepanov
2015-12-15 23:00:20 +00:00
parent 67849d56c3
commit fd6f92d5cb
20 changed files with 489 additions and 52 deletions

View File

@@ -2552,15 +2552,22 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
SanitizerScope SanScope(this);
llvm::Value *BitSetName = llvm::MetadataAsValue::get(
getLLVMContext(),
CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0)));
llvm::Metadata *MD =
CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
llvm::Value *BitSetName = llvm::MetadataAsValue::get(getLLVMContext(), MD);
llvm::Value *CastedVTable = Builder.CreateBitCast(VTable, Int8PtrTy);
llvm::Value *BitSetTest =
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::bitset_test),
{CastedVTable, BitSetName});
if (CGM.getCodeGenOpts().SanitizeCfiCrossDso) {
if (auto TypeId = CGM.CreateCfiIdForTypeMetadata(MD)) {
EmitCfiSlowPathCheck(BitSetTest, TypeId, CastedVTable);
return;
}
}
SanitizerMask M;
switch (TCK) {
case CFITCK_VCall:
@@ -2578,9 +2585,9 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
}
llvm::Constant *StaticData[] = {
EmitCheckSourceLocation(Loc),
EmitCheckTypeDescriptor(QualType(RD->getTypeForDecl(), 0)),
llvm::ConstantInt::get(Int8Ty, TCK),
EmitCheckSourceLocation(Loc),
EmitCheckTypeDescriptor(QualType(RD->getTypeForDecl(), 0)),
llvm::ConstantInt::get(Int8Ty, TCK),
};
EmitCheck(std::make_pair(BitSetTest, M), "cfi_bad_type", StaticData,
CastedVTable);