egoktas created this revision. egoktas created this object with visibility "All Users".
User can explicitly specify classlinks in a sanitizer blacklist file. During compilation with Control-Flow Integrity (CFI), the specified classes will be linked so that (vtables of) the class type Y can be used at virtual callsites that have the class type X. An example of a classlink in the sanitizer blacklist file would be: classlink:_ZTS1X=_ZTS1Y Note that this is a one-way link. For example, if (vtables of) the class type X can be used at a virtual callsite with the class type Y, then the following line specifying the classlink should be added to the sanitizer blacklist file: classlink:_ZTS1Y=_ZTS1X This is a solution for the CFI errors that can occur when there is no inheritance link between two classes but one class is used as the other at runtime. This patch requires the new function "getEntriesInSection" in SpecialCaseList which is submitted for revision under Differential https://reviews.llvm.org/D34231. https://reviews.llvm.org/D34233 Files: include/clang/Basic/SanitizerBlacklist.h lib/Basic/SanitizerBlacklist.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGVTables.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h
Index: lib/CodeGen/CodeGenModule.h =================================================================== --- lib/CodeGen/CodeGenModule.h +++ lib/CodeGen/CodeGenModule.h @@ -33,6 +33,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringSet.h" #include "llvm/IR/Module.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Transforms/Utils/SanitizerStats.h" @@ -1204,6 +1205,8 @@ /// Create and attach type metadata for the given vtable. void AddVTableTypeMetadata(llvm::GlobalVariable *VTable, CharUnits Offset, const CXXRecordDecl *RD); + void AddVTableTypeMetadata(llvm::GlobalVariable *VTable, CharUnits Offset, + llvm::Metadata *MD); /// \brief Get the declaration of std::terminate for the platform. llvm::Constant *getTerminateFn(); @@ -1213,6 +1216,9 @@ llvm::Value * createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF); + void GetSupplementalClasslinks(const CXXRecordDecl *BaseClass, + llvm::StringSet<> &SupplementalClasslinks); + /// Get target specific null pointer. /// \param T is the LLVM type of the null pointer. /// \param QT is the clang QualType of the null pointer. Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -4417,6 +4417,12 @@ const CXXRecordDecl *RD) { llvm::Metadata *MD = CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0)); + AddVTableTypeMetadata(VTable, Offset, MD); +} + +void CodeGenModule::AddVTableTypeMetadata(llvm::GlobalVariable *VTable, + CharUnits Offset, + llvm::Metadata *MD) { VTable->addTypeMetadata(Offset.getQuantity(), MD); if (CodeGenOpts.SanitizeCfiCrossDso) @@ -4475,3 +4481,16 @@ "__translate_sampler_initializer"), {C}); } + +void +CodeGenModule::GetSupplementalClasslinks(const CXXRecordDecl *BaseClass, + llvm::StringSet<> &SupplementalClasslinks){ + std::string mangledClassName; + llvm::raw_string_ostream Out(mangledClassName); + getCXXABI().getMangleContext().mangleTypeName( + QualType(BaseClass->getTypeForDecl(), 0), Out); + Out.flush(); + + getContext().getSanitizerBlacklist().getSupplementalClasslinks( + mangledClassName, SupplementalClasslinks); +} Index: lib/CodeGen/CGVTables.cpp =================================================================== --- lib/CodeGen/CGVTables.cpp +++ lib/CodeGen/CGVTables.cpp @@ -986,7 +986,20 @@ return E1.second < E2.second; }); - for (auto BitsetEntry : BitsetEntries) + for (auto BitsetEntry : BitsetEntries){ + const CXXRecordDecl *BaseClassOfVTable = BitsetEntry.first; AddVTableTypeMetadata(VTable, PointerWidth * BitsetEntry.second, - BitsetEntry.first); + BaseClassOfVTable); + + // Check if user has defined supplemental class links for BaseClass. + llvm::StringSet<> SupplementalClasslinks; + GetSupplementalClasslinks(BaseClassOfVTable, SupplementalClasslinks); + for (auto I = SupplementalClasslinks.begin(), + E = SupplementalClasslinks.end(); I != E; I++){ + llvm::Metadata* LinkedClassMD = llvm::MDString::get(getLLVMContext(), + I->getKey()); + AddVTableTypeMetadata(VTable, PointerWidth * BitsetEntry.second, + LinkedClassMD); + } + } } Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -2486,6 +2486,17 @@ StringRef(), StringRef(), None, Buffer, None); + // Add mangled name of the type + if(isExternallyVisible(T->getLinkage())){ + std::string OutName; + llvm::raw_string_ostream Out(OutName); + CGM.getCXXABI().getMangleContext().mangleTypeName(T, Out); + + Buffer += '('; + Buffer += Out.str().c_str(); + Buffer += ')'; + } + llvm::Constant *Components[] = { Builder.getInt16(TypeKind), Builder.getInt16(TypeInfo), llvm::ConstantDataArray::getString(getLLVMContext(), Buffer) Index: lib/Basic/SanitizerBlacklist.cpp =================================================================== --- lib/Basic/SanitizerBlacklist.cpp +++ lib/Basic/SanitizerBlacklist.cpp @@ -44,3 +44,9 @@ isBlacklistedFile(SM.getFilename(SM.getFileLoc(Loc)), Category); } +void SanitizerBlacklist::getSupplementalClasslinks(StringRef mangledClassName, + llvm::StringSet<> &SupplementalClasslinks) const { + SCL->getEntriesInSection("classlink", SupplementalClasslinks, + mangledClassName); +} + Index: include/clang/Basic/SanitizerBlacklist.h =================================================================== --- include/clang/Basic/SanitizerBlacklist.h +++ include/clang/Basic/SanitizerBlacklist.h @@ -18,6 +18,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSet.h" #include "llvm/Support/SpecialCaseList.h" #include <memory> @@ -39,6 +40,8 @@ StringRef Category = StringRef()) const; bool isBlacklistedLocation(SourceLocation Loc, StringRef Category = StringRef()) const; + void getSupplementalClasslinks(StringRef mangledClassName, + llvm::StringSet<> &SupplementalClasslinks) const; }; } // end namespace clang
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits