From e57064428566724b7786f5e22553a06cc5f5887f Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 9 Jul 2015 19:56:14 +0000 Subject: CFI: Emit correct bit set information if RTTI is disabled under MS ABI. We were previously creating bit set entries at virtual table offset sizeof(void*) unconditionally under the Microsoft C++ ABI. This is incorrect if RTTI data is disabled; in that case the "address point" is at offset 0. This change modifies bit set emission to take into account whether RTTI data is being emitted. Also make a start on a blacklisting scheme for records. Differential Revision: http://reviews.llvm.org/D11048 llvm-svn: 241845 --- clang/lib/CodeGen/CGClass.cpp | 3 +-- clang/lib/CodeGen/CGVTables.cpp | 8 ++++++-- clang/lib/CodeGen/CodeGenModule.h | 4 ++++ clang/lib/CodeGen/MicrosoftCXXABI.cpp | 30 +++++++++++++++++++----------- 4 files changed, 30 insertions(+), 15 deletions(-) (limited to 'clang/lib/CodeGen') diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 145a0e67543..f2feb8b21c9 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -2207,8 +2207,7 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc) { - // FIXME: Add blacklisting scheme. - if (RD->isInStdNamespace()) + if (CGM.IsCFIBlacklistedRecord(RD)) return; SanitizerScope SanScope(this); diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 969629fb584..64930628949 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -841,6 +841,11 @@ void CodeGenModule::EmitDeferredVTables() { DeferredVTables.clear(); } +bool CodeGenModule::IsCFIBlacklistedRecord(const CXXRecordDecl *RD) { + // FIXME: Make this user configurable. + return RD->isInStdNamespace(); +} + void CodeGenModule::EmitVTableBitSetEntries(llvm::GlobalVariable *VTable, const VTableLayout &VTLayout) { if (!LangOpts.Sanitize.has(SanitizerKind::CFIVCall) && @@ -855,8 +860,7 @@ void CodeGenModule::EmitVTableBitSetEntries(llvm::GlobalVariable *VTable, std::vector BitsetEntries; // Create a bit set entry for each address point. for (auto &&AP : VTLayout.getAddressPoints()) { - // FIXME: Add blacklisting scheme. - if (AP.first.getBase()->isInStdNamespace()) + if (IsCFIBlacklistedRecord(AP.first.getBase())) continue; BitsetEntries.push_back(CreateVTableBitSetEntry( diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 9a295feaffa..dd167a29f5a 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1126,6 +1126,10 @@ public: /// \param D Threadprivate declaration. void EmitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D); + /// Returns whether the given record is blacklisted from control flow + /// integrity checks. + bool IsCFIBlacklistedRecord(const CXXRecordDecl *RD); + /// Emit bit set entries for the given vtable using the given layout if /// vptr CFI is enabled. void EmitVTableBitSetEntries(llvm::GlobalVariable *VTable, diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 8d8f70f199f..3433990e128 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -1466,20 +1466,27 @@ void MicrosoftCXXABI::emitVTableBitSetEntries(VPtrInfo *Info, llvm::NamedMDNode *BitsetsMD = CGM.getModule().getOrInsertNamedMetadata("llvm.bitsets"); - CharUnits PointerWidth = getContext().toCharUnitsFromBits( - getContext().getTargetInfo().getPointerWidth(0)); - // FIXME: Add blacklisting scheme. + // The location of the first virtual function pointer in the virtual table, + // aka the "address point" on Itanium. This is at offset 0 if RTTI is + // disabled, or sizeof(void*) if RTTI is enabled. + CharUnits AddressPoint = + getContext().getLangOpts().RTTIData + ? getContext().toCharUnitsFromBits( + getContext().getTargetInfo().getPointerWidth(0)) + : CharUnits::Zero(); if (Info->PathToBaseWithVPtr.empty()) { - BitsetsMD->addOperand( - CGM.CreateVTableBitSetEntry(VTable, PointerWidth, RD)); + if (!CGM.IsCFIBlacklistedRecord(RD)) + BitsetsMD->addOperand( + CGM.CreateVTableBitSetEntry(VTable, AddressPoint, RD)); return; } // Add a bitset entry for the least derived base belonging to this vftable. - BitsetsMD->addOperand(CGM.CreateVTableBitSetEntry( - VTable, PointerWidth, Info->PathToBaseWithVPtr.back())); + if (!CGM.IsCFIBlacklistedRecord(Info->PathToBaseWithVPtr.back())) + BitsetsMD->addOperand(CGM.CreateVTableBitSetEntry( + VTable, AddressPoint, Info->PathToBaseWithVPtr.back())); // Add a bitset entry for each derived class that is laid out at the same // offset as the least derived base. @@ -1497,14 +1504,15 @@ void MicrosoftCXXABI::emitVTableBitSetEntries(VPtrInfo *Info, Offset = VBI->second.VBaseOffset; if (!Offset.isZero()) return; - BitsetsMD->addOperand( - CGM.CreateVTableBitSetEntry(VTable, PointerWidth, DerivedRD)); + if (!CGM.IsCFIBlacklistedRecord(DerivedRD)) + BitsetsMD->addOperand( + CGM.CreateVTableBitSetEntry(VTable, AddressPoint, DerivedRD)); } // Finally do the same for the most derived class. - if (Info->FullOffsetInMDC.isZero()) + if (Info->FullOffsetInMDC.isZero() && !CGM.IsCFIBlacklistedRecord(RD)) BitsetsMD->addOperand( - CGM.CreateVTableBitSetEntry(VTable, PointerWidth, RD)); + CGM.CreateVTableBitSetEntry(VTable, AddressPoint, RD)); } void MicrosoftCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT, -- cgit v1.2.3