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

Reply via email to