diff options
author | Alexey Samsonov <vonosmas@gmail.com> | 2014-10-13 23:59:00 +0000 |
---|---|---|
committer | Alexey Samsonov <vonosmas@gmail.com> | 2014-10-13 23:59:00 +0000 |
commit | eb47d8a2c880611d79a468d04f287e868b8e241a (patch) | |
tree | cba22a0d20aed83e80a543af4d842bd5e93cc560 /compiler-rt | |
parent | 0809b2ddc3a8661a55f818dbed8ea71a86e3802a (diff) | |
download | bcm5719-llvm-eb47d8a2c880611d79a468d04f287e868b8e241a.tar.gz bcm5719-llvm-eb47d8a2c880611d79a468d04f287e868b8e241a.zip |
Sanitize upcasts and conversion to virtual base.
This change adds UBSan check to upcasts. Namely, when we
perform derived-to-base conversion, we:
1) check that the pointer-to-derived has suitable alignment
and underlying storage, if this pointer is non-null.
2) if vptr-sanitizer is enabled, and we perform conversion to
virtual base, we check that pointer-to-derived has a matching vptr.
llvm-svn: 219642
Diffstat (limited to 'compiler-rt')
-rw-r--r-- | compiler-rt/lib/ubsan/ubsan_handlers.cc | 6 | ||||
-rw-r--r-- | compiler-rt/test/ubsan/TestCases/TypeCheck/misaligned.cpp | 17 | ||||
-rw-r--r-- | compiler-rt/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp | 16 |
3 files changed, 35 insertions, 4 deletions
diff --git a/compiler-rt/lib/ubsan/ubsan_handlers.cc b/compiler-rt/lib/ubsan/ubsan_handlers.cc index f8365a7d2fe..a0ecff94359 100644 --- a/compiler-rt/lib/ubsan/ubsan_handlers.cc +++ b/compiler-rt/lib/ubsan/ubsan_handlers.cc @@ -30,10 +30,10 @@ static bool ignoreReport(SourceLocation SLoc, ReportOptions Opts) { } namespace __ubsan { - const char *TypeCheckKinds[] = { +const char *TypeCheckKinds[] = { "load of", "store to", "reference binding to", "member access within", - "member call on", "constructor call on", "downcast of", "downcast of" - }; + "member call on", "constructor call on", "downcast of", "downcast of", + "upcast of", "cast to virtual base of"}; } static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer, diff --git a/compiler-rt/test/ubsan/TestCases/TypeCheck/misaligned.cpp b/compiler-rt/test/ubsan/TestCases/TypeCheck/misaligned.cpp index d5d70f2e552..79f5136db96 100644 --- a/compiler-rt/test/ubsan/TestCases/TypeCheck/misaligned.cpp +++ b/compiler-rt/test/ubsan/TestCases/TypeCheck/misaligned.cpp @@ -1,11 +1,12 @@ // RUN: %clangxx -fsanitize=alignment -g %s -O3 -o %t -// RUN: %run %t l0 && %run %t s0 && %run %t r0 && %run %t m0 && %run %t f0 && %run %t n0 +// RUN: %run %t l0 && %run %t s0 && %run %t r0 && %run %t m0 && %run %t f0 && %run %t n0 && %run %t u0 // RUN: %run %t l1 2>&1 | FileCheck %s --check-prefix=CHECK-LOAD --strict-whitespace // RUN: %run %t s1 2>&1 | FileCheck %s --check-prefix=CHECK-STORE // RUN: %run %t r1 2>&1 | FileCheck %s --check-prefix=CHECK-REFERENCE // RUN: %run %t m1 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER // RUN: %run %t f1 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN // RUN: %run %t n1 2>&1 | FileCheck %s --check-prefix=CHECK-NEW +// RUN: %run %t u1 2>&1 | FileCheck %s --check-prefix=CHECK-UPCAST // RUN: UBSAN_OPTIONS=print_stacktrace=1 %run %t l1 2>&1 | FileCheck %s --check-prefix=CHECK-LOAD --check-prefix=CHECK-%os-STACK-LOAD // RUN: %clangxx -fsanitize=alignment -fno-sanitize-recover %s -O3 -o %t @@ -20,12 +21,17 @@ struct S { int k; }; +struct T : S { + int t; +}; + int main(int, char **argv) { char c[] __attribute__((aligned(8))) = { 0, 0, 0, 0, 1, 2, 3, 4, 5 }; // Pointer value may be unspecified here, but behavior is not undefined. int *p = (int*)&c[4 + argv[1][1] - '0']; S *s = (S*)p; + T *t = (T*)p; void *wild = reinterpret_cast<void *>(0x123L); @@ -81,6 +87,15 @@ int main(int, char **argv) { // CHECK-NEW-NEXT: {{^ \^}} return (new (s) S)->k && 0; + case 'u': { + // CHECK-UPCAST: misaligned.cpp:[[@LINE+4]]:17: runtime error: upcast of misaligned address [[PTR:0x[0-9a-f]*]] for type 'T', which requires 4 byte alignment + // CHECK-UPCAST-NEXT: [[PTR]]: note: pointer points here + // CHECK-UPCAST-NEXT: {{^ 00 00 00 01 02 03 04 05}} + // CHECK-UPCAST-NEXT: {{^ \^}} + S *s2 = (S*)t; + return s2->f(); + } + case 'w': // CHECK-WILD: misaligned.cpp:[[@LINE+3]]:35: runtime error: member access within misaligned address 0x000000000123 for type 'S', which requires 4 byte alignment // CHECK-WILD-NEXT: 0x000000000123: note: pointer points here diff --git a/compiler-rt/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp b/compiler-rt/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp new file mode 100644 index 00000000000..d5130fe23ae --- /dev/null +++ b/compiler-rt/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp @@ -0,0 +1,16 @@ +// RUN: %clangxx -fsanitize=vptr -fno-sanitize-recover -g %s -O3 -o %t +// RUN: not %run %t 2>&1 | FileCheck %s + +struct S { virtual int f() { return 0; } }; +struct T : virtual S {}; + +struct Foo { virtual int f() { return 0; } }; + +int main(int argc, char **argv) { + Foo foo; + T *t = (T*)&foo; + S *s = t; + // CHECK: vptr-virtual-base.cpp:[[@LINE-1]]:10: runtime error: cast to virtual base of address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T' + // CHECK-NEXT: [[PTR]]: note: object is of type 'Foo' + return s->f(); +} |