[compiler-rt] r219642 - Sanitize upcasts and conversion to virtual base.

Alexey Samsonov vonosmas at gmail.com
Mon Oct 13 16:59:00 PDT 2014


Author: samsonov
Date: Mon Oct 13 18:59:00 2014
New Revision: 219642

URL: http://llvm.org/viewvc/llvm-project?rev=219642&view=rev
Log:
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.

Added:
    compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp
Modified:
    compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc
    compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/misaligned.cpp

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=219642&r1=219641&r2=219642&view=diff
==============================================================================
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc (original)
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc Mon Oct 13 18:59:00 2014
@@ -30,10 +30,10 @@ static bool ignoreReport(SourceLocation
 }
 
 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,

Modified: compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/misaligned.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/misaligned.cpp?rev=219642&r1=219641&r2=219642&view=diff
==============================================================================
--- compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/misaligned.cpp (original)
+++ compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/misaligned.cpp Mon Oct 13 18:59:00 2014
@@ -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

Added: compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp?rev=219642&view=auto
==============================================================================
--- compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp (added)
+++ compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp Mon Oct 13 18:59:00 2014
@@ -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();
+}





More information about the llvm-commits mailing list