[PATCH] D48583: CFI: Print DSO names for failed cross-DSO icalls

Vlad Tsyrklevich via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 25 21:08:51 PDT 2018


vlad.tsyrklevich updated this revision to Diff 152833.
vlad.tsyrklevich added a comment.

- Print cross-DSO diagnostic for C++ CFI failures as well


Repository:
  rCRT Compiler Runtime

https://reviews.llvm.org/D48583

Files:
  lib/ubsan/ubsan_handlers.cc
  lib/ubsan/ubsan_handlers_cxx.cc
  test/cfi/cross-dso-diagnostic.cpp


Index: test/cfi/cross-dso-diagnostic.cpp
===================================================================
--- /dev/null
+++ test/cfi/cross-dso-diagnostic.cpp
@@ -0,0 +1,29 @@
+// Check that cross-DSO diagnostics print the names of both modules
+
+// RUN: %clangxx_cfi_diag -g -o %t %s -ldl
+// RUN: %t 2>&1 | FileCheck %s
+
+// REQUIRES: cxxabi
+
+#include <dlfcn.h>
+#include <stdio.h>
+
+struct S1 {
+  virtual void f1();
+};
+
+void S1::f1() {}
+
+int main() {
+  // CHECK: runtime error: control flow integrity check for type 'void (int)' failed during indirect function call
+  // CHECK: getpid defined here
+  // CHECK: check failed in {{.*}}, destination function located in {{.*}}
+  void (*fp)(int) =
+      reinterpret_cast<void(*)(int)>(dlsym(RTLD_DEFAULT, "getpid"));
+  fp(1); // 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 {{.*}}, vtable located in {{.*}}
+  S1 *S = reinterpret_cast<S1*>(fp); // trigger cfi-unrelated-cast failure
+}
Index: lib/ubsan/ubsan_handlers_cxx.cc
===================================================================
--- lib/ubsan/ubsan_handlers_cxx.cc
+++ lib/ubsan/ubsan_handlers_cxx.cc
@@ -137,16 +137,25 @@
       << 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
 
Index: lib/ubsan/ubsan_handlers.cc
===================================================================
--- lib/ubsan/ubsan_handlers.cc
+++ lib/ubsan/ubsan_handlers.cc
@@ -660,6 +660,20 @@
   if (!FName)
     FName = "(unknown)";
   Diag(FLoc, DL_Note, ET, "%0 defined here") << FName;
+
+  // If the failure occurred due to a cross-DSO icall, 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 {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48583.152833.patch
Type: text/x-patch
Size: 3240 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180626/f5bd79de/attachment.bin>


More information about the llvm-commits mailing list