[ubsan] Null-check pointers in -fsanitize=vptr (PR33881)
The instrumentation generated by -fsanitize=vptr does not null check a
user pointer before loading from it. This causes crashes in the face of
UB member calls (this=nullptr), i.e it's causing user programs to crash
only after UBSan is turned on.
The fix is to make run-time null checking a prerequisite for enabling
-fsanitize=vptr, and to then teach UBSan to reuse these run-time null
checks to make -fsanitize=vptr safe.
Testing: check-clang, check-ubsan, a stage2 ubsan-enabled build
Differential Revision: https://reviews.llvm.org/D35735
https://bugs.llvm.org/show_bug.cgi?id=33881
llvm-svn: 309007
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index f119174..41f6d19 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -306,6 +306,13 @@
Kinds &= ~Vptr;
}
+ // Disable -fsanitize=vptr if -fsanitize=null is not enabled (the vptr
+ // instrumentation is broken without run-time null checks).
+ if ((Kinds & Vptr) && !(Kinds & Null)) {
+ Kinds &= ~Vptr;
+ D.Diag(diag::warn_drv_disabling_vptr_no_null_check);
+ }
+
// Check that LTO is enabled if we need it.
if ((Kinds & NeedsLTO) && !D.isUsingLTO()) {
D.Diag(diag::err_drv_argument_only_allowed_with)