[compiler-rt] r335644 - CFI: Print DSO names for failed cross-DSO icalls

Vlad Tsyrklevich via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 26 11:51:05 PDT 2018


Author: vlad.tsyrklevich
Date: Tue Jun 26 11:51:04 2018
New Revision: 335644

URL: http://llvm.org/viewvc/llvm-project?rev=335644&view=rev
Log:
CFI: Print DSO names for failed cross-DSO icalls

Reviewers: pcc

Reviewed By: pcc

Subscribers: kubamracek, delcypher, llvm-commits, kcc, #sanitizers

Differential Revision: https://reviews.llvm.org/D48583

Added:
    compiler-rt/trunk/test/cfi/cross-dso-diagnostic.cpp
Modified:
    compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc
    compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc

Modified: compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc?rev=335644&r1=335643&r2=335644&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc Tue Jun 26 11:51:04 2018
@@ -660,6 +660,21 @@ static void handleCFIBadIcall(CFICheckFa
   if (!FName)
     FName = "(unknown)";
   Diag(FLoc, DL_Note, ET, "%0 defined here") << FName;
+
+  // If the failure involved different DSOs for the check location and icall
+  // target, report the DSO names.
+  const char *DstModule = FLoc.get()->info.module;
+  if (!DstModule)
+    DstModule = "(unknown)";
+
+  const char *SrcModule = Symbolizer::GetOrInit()->GetModuleNameForPc(Opts.pc);
+  if (!SrcModule)
+    SrcModule = "(unknown)";
+
+  if (internal_strcmp(SrcModule, DstModule))
+    Diag(Loc, DL_Note, ET,
+         "check failed in %0, destination function located in %1")
+        << SrcModule << DstModule;
 }
 
 namespace __ubsan {

Modified: compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc?rev=335644&r1=335643&r2=335644&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc Tue Jun 26 11:51:04 2018
@@ -137,16 +137,25 @@ void __ubsan_handle_cfi_bad_type(CFIChec
       << Data->Type << CheckKindStr << (void *)Vtable;
 
   // If possible, say what type it actually points to.
-  if (!DTI.isValid()) {
-    const char *module = Symbolizer::GetOrInit()->GetModuleNameForPc(Vtable);
-    if (module)
-      Diag(Vtable, DL_Note, ET, "invalid vtable in module %0") << module;
-    else
-      Diag(Vtable, DL_Note, ET, "invalid vtable");
-  } else {
+  if (!DTI.isValid())
+    Diag(Vtable, DL_Note, ET, "invalid vtable");
+  else
     Diag(Vtable, DL_Note, ET, "vtable is of type %0")
         << TypeName(DTI.getMostDerivedTypeName());
-  }
+
+  // If the failure involved different DSOs for the check location and vtable,
+  // report the DSO names.
+  const char *DstModule = Symbolizer::GetOrInit()->GetModuleNameForPc(Vtable);
+  if (!DstModule)
+    DstModule = "(unknown)";
+
+  const char *SrcModule = Symbolizer::GetOrInit()->GetModuleNameForPc(Opts.pc);
+  if (!SrcModule)
+    SrcModule = "(unknown)";
+
+  if (internal_strcmp(SrcModule, DstModule))
+    Diag(Loc, DL_Note, ET, "check failed in %0, vtable located in %1")
+        << SrcModule << DstModule;
 }
 }  // namespace __ubsan
 

Added: compiler-rt/trunk/test/cfi/cross-dso-diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/cfi/cross-dso-diagnostic.cpp?rev=335644&view=auto
==============================================================================
--- compiler-rt/trunk/test/cfi/cross-dso-diagnostic.cpp (added)
+++ compiler-rt/trunk/test/cfi/cross-dso-diagnostic.cpp Tue Jun 26 11:51:04 2018
@@ -0,0 +1,42 @@
+// Check that cross-DSO diagnostics print the names of both modules
+
+// RUN: %clangxx_cfi_diag -g -DSHARED_LIB -fPIC -shared -o %t_dso_suffix %s
+// RUN: %clangxx_cfi_diag -g -o %t_exe_suffix %s -ldl
+// RUN: %t_exe_suffix %t_dso_suffix 2>&1 | FileCheck %s
+
+// UNSUPPORTED: win32
+// REQUIRES: cxxabi
+
+#include <dlfcn.h>
+#include <stdio.h>
+
+struct S1 {
+  virtual void f1();
+};
+
+#ifdef SHARED_LIB
+
+void S1::f1() {}
+
+__attribute__((visibility("default"))) extern "C"
+void* dso_symbol() { return new S1(); }
+
+#else
+
+int main(int argc, char *argv[]) {
+  void *handle = dlopen(argv[1], RTLD_NOW);
+
+  // CHECK: runtime error: control flow integrity check for type 'void *()' failed during indirect function call
+  // CHECK: dso_symbol defined here
+  // CHECK: check failed in {{.*}}_exe_suffix, destination function located in {{.*}}_dso_suffix
+  void* (*fp)(void) =
+      reinterpret_cast<void*(*)(void)>(dlsym(handle, "dso_symbol"));
+  void *S = fp(); // trigger cfi-icall failure
+
+  // CHECK: runtime error: control flow integrity check for type 'S1' failed during cast to unrelated type
+  // CHECK: invalid vtable
+  // CHECK: check failed in {{.*}}_exe_suffix, vtable located in {{.*}}_dso_suffix
+  S1 *Scast = reinterpret_cast<S1*>(S); // trigger cfi-unrelated-cast failure
+}
+
+#endif // SHARED_LIB




More information about the llvm-commits mailing list