Skip to content

Commit e745cf9

Browse files
committedJun 26, 2018
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 llvm-svn: 335644
1 parent c85ca4c commit e745cf9

File tree

3 files changed

+74
-8
lines changed

3 files changed

+74
-8
lines changed
 

‎compiler-rt/lib/ubsan/ubsan_handlers.cc

+15
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,21 @@ static void handleCFIBadIcall(CFICheckFailData *Data, ValueHandle Function,
660660
if (!FName)
661661
FName = "(unknown)";
662662
Diag(FLoc, DL_Note, ET, "%0 defined here") << FName;
663+
664+
// If the failure involved different DSOs for the check location and icall
665+
// target, report the DSO names.
666+
const char *DstModule = FLoc.get()->info.module;
667+
if (!DstModule)
668+
DstModule = "(unknown)";
669+
670+
const char *SrcModule = Symbolizer::GetOrInit()->GetModuleNameForPc(Opts.pc);
671+
if (!SrcModule)
672+
SrcModule = "(unknown)";
673+
674+
if (internal_strcmp(SrcModule, DstModule))
675+
Diag(Loc, DL_Note, ET,
676+
"check failed in %0, destination function located in %1")
677+
<< SrcModule << DstModule;
663678
}
664679

665680
namespace __ubsan {

‎compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc

+17-8
Original file line numberDiff line numberDiff line change
@@ -137,16 +137,25 @@ void __ubsan_handle_cfi_bad_type(CFICheckFailData *Data, ValueHandle Vtable,
137137
<< Data->Type << CheckKindStr << (void *)Vtable;
138138

139139
// If possible, say what type it actually points to.
140-
if (!DTI.isValid()) {
141-
const char *module = Symbolizer::GetOrInit()->GetModuleNameForPc(Vtable);
142-
if (module)
143-
Diag(Vtable, DL_Note, ET, "invalid vtable in module %0") << module;
144-
else
145-
Diag(Vtable, DL_Note, ET, "invalid vtable");
146-
} else {
140+
if (!DTI.isValid())
141+
Diag(Vtable, DL_Note, ET, "invalid vtable");
142+
else
147143
Diag(Vtable, DL_Note, ET, "vtable is of type %0")
148144
<< TypeName(DTI.getMostDerivedTypeName());
149-
}
145+
146+
// If the failure involved different DSOs for the check location and vtable,
147+
// report the DSO names.
148+
const char *DstModule = Symbolizer::GetOrInit()->GetModuleNameForPc(Vtable);
149+
if (!DstModule)
150+
DstModule = "(unknown)";
151+
152+
const char *SrcModule = Symbolizer::GetOrInit()->GetModuleNameForPc(Opts.pc);
153+
if (!SrcModule)
154+
SrcModule = "(unknown)";
155+
156+
if (internal_strcmp(SrcModule, DstModule))
157+
Diag(Loc, DL_Note, ET, "check failed in %0, vtable located in %1")
158+
<< SrcModule << DstModule;
150159
}
151160
} // namespace __ubsan
152161

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Check that cross-DSO diagnostics print the names of both modules
2+
3+
// RUN: %clangxx_cfi_diag -g -DSHARED_LIB -fPIC -shared -o %t_dso_suffix %s
4+
// RUN: %clangxx_cfi_diag -g -o %t_exe_suffix %s -ldl
5+
// RUN: %t_exe_suffix %t_dso_suffix 2>&1 | FileCheck %s
6+
7+
// UNSUPPORTED: win32
8+
// REQUIRES: cxxabi
9+
10+
#include <dlfcn.h>
11+
#include <stdio.h>
12+
13+
struct S1 {
14+
virtual void f1();
15+
};
16+
17+
#ifdef SHARED_LIB
18+
19+
void S1::f1() {}
20+
21+
__attribute__((visibility("default"))) extern "C"
22+
void* dso_symbol() { return new S1(); }
23+
24+
#else
25+
26+
int main(int argc, char *argv[]) {
27+
void *handle = dlopen(argv[1], RTLD_NOW);
28+
29+
// CHECK: runtime error: control flow integrity check for type 'void *()' failed during indirect function call
30+
// CHECK: dso_symbol defined here
31+
// CHECK: check failed in {{.*}}_exe_suffix, destination function located in {{.*}}_dso_suffix
32+
void* (*fp)(void) =
33+
reinterpret_cast<void*(*)(void)>(dlsym(handle, "dso_symbol"));
34+
void *S = fp(); // trigger cfi-icall failure
35+
36+
// CHECK: runtime error: control flow integrity check for type 'S1' failed during cast to unrelated type
37+
// CHECK: invalid vtable
38+
// CHECK: check failed in {{.*}}_exe_suffix, vtable located in {{.*}}_dso_suffix
39+
S1 *Scast = reinterpret_cast<S1*>(S); // trigger cfi-unrelated-cast failure
40+
}
41+
42+
#endif // SHARED_LIB

0 commit comments

Comments
 (0)
Please sign in to comment.