• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // RUN: %clangxx -std=c++11 -frtti -fsanitize=vptr -g %s -O3 -o %t
2 // RUN: %run %t &> %t.log
3 // RUN: cat %t.log | not count 0 && FileCheck --input-file %t.log %s || cat %t.log | count 0
4 
5 // REQUIRES: cxxabi
6 
7 #include <sys/mman.h>
8 #include <unistd.h>
9 
10 class Base {
11 public:
12   int i;
print()13   virtual void print() {}
14 };
15 
16 class Derived : public Base {
17 public:
print()18   void print() {}
19 };
20 
21 
main()22 int main() {
23   int page_size = getpagesize();
24 
25   void *non_accessible = mmap(nullptr, page_size * 2, PROT_NONE,
26                               MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
27 
28   if (non_accessible == MAP_FAILED)
29     return 0;
30 
31   void *accessible = mmap((char*)non_accessible + page_size, page_size,
32                           PROT_READ | PROT_WRITE,
33                           MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
34   if (accessible == MAP_FAILED)
35     return 0;
36 
37   char *c = new char[sizeof(Derived)];
38 
39   // The goal is to trigger a condition when Vptr points to accessible memory,
40   // but VptrPrefix does not. That has been triggering SIGSEGV in UBSan code.
41   void **vtable_ptr = reinterpret_cast<void **>(c);
42   *vtable_ptr = (void*)accessible;
43 
44   Derived *list = (Derived *)c;
45 
46 // CHECK: PR33221.cpp:[[@LINE+2]]:19: runtime error: member access within address {{.*}} which does not point to an object of type 'Base'
47 // CHECK-NEXT: invalid vptr
48   int foo = list->i;
49   return 0;
50 }
51