[compiler-rt] r246817 - Test triangle inheritance member poisoning.

Naomi Musgrave via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 3 16:06:13 PDT 2015


Author: nmusgrave
Date: Thu Sep  3 18:06:13 2015
New Revision: 246817

URL: http://llvm.org/viewvc/llvm-project?rev=246817&view=rev
Log:
Test triangle inheritance member poisoning.

Summary: Verify that all members are poisoned.

Reviewers: eugenis, kcc

Differential Revision: http://reviews.llvm.org/D12023

Test virtual functions and virtual bases poisoning proper size.

Runtime testing of destroying diamond inheritance.

Explicit testing for 0 optimizations.

Simplify test to only test interesting values.

Test poisoning on multiple inheritance with nontrivial and trivial members.

Removed unnecessary header.

Testing (anonymous/)bit fields.

Revised object instantiation in test to avoid undefined behavior.

Added:
    compiler-rt/trunk/test/msan/dtor-bit-fields.cc
    compiler-rt/trunk/test/msan/dtor-multiple-inheritance-trivial-class-members.cc
    compiler-rt/trunk/test/msan/dtor-multiple-inheritance.cc
    compiler-rt/trunk/test/msan/dtor-trivial-class-members.cc
Modified:
    compiler-rt/trunk/test/msan/dtor-derived-class.cc

Added: compiler-rt/trunk/test/msan/dtor-bit-fields.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/msan/dtor-bit-fields.cc?rev=246817&view=auto
==============================================================================
--- compiler-rt/trunk/test/msan/dtor-bit-fields.cc (added)
+++ compiler-rt/trunk/test/msan/dtor-bit-fields.cc Thu Sep  3 18:06:13 2015
@@ -0,0 +1,70 @@
+// RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t
+
+// RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t
+
+// RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t
+
+#include <sanitizer/msan_interface.h>
+#include <assert.h>
+
+// TODO: remove empty dtors when msan use-after-dtor poisons
+// for trivial classes with undeclared dtors
+
+// 24 bytes total
+struct Packed {
+  // Packed into 4 bytes
+  unsigned int a : 1;
+  unsigned int b : 1;
+  // Force alignment to next 4 bytes
+  unsigned int   : 0;
+  unsigned int c : 1;
+  // Force alignment, 8 more bytes
+  double d = 5.0;
+  // 4 bytes
+  unsigned int e : 1;
+  ~Packed() {}
+};
+
+// 1 byte total
+struct Empty {
+  unsigned int : 0;
+  ~Empty() {}
+};
+
+// 4 byte total
+struct Simple {
+  unsigned int a : 1;
+  ~Simple() {}
+};
+
+struct Anon {
+  unsigned int a : 1;
+  unsigned int b : 2;
+  unsigned int   : 0;
+  unsigned int c : 1;
+  ~Anon() {}
+};
+
+int main() {
+  Packed *p = new Packed();
+  p->~Packed();
+  for (int i = 0; i < 4; i++)
+    assert(__msan_test_shadow(((char*)p) + i, sizeof(char)) != -1);
+  assert(__msan_test_shadow(&p->d, sizeof(double)) != -1);
+  assert(__msan_test_shadow(((char*)(&p->d)) + sizeof(double), sizeof(char)) !=
+         -1);
+
+  Empty *e = new Empty();
+  e->~Empty();
+  assert(__msan_test_shadow(e, sizeof(*e)) != -1);
+
+  Simple *s = new Simple();
+  s->~Simple();
+  assert(__msan_test_shadow(s, sizeof(*s)) != -1);
+
+  Anon *a = new Anon();
+  a->~Anon();
+  assert(__msan_test_shadow(a, sizeof(*a)) != -1);
+
+  return 0;
+}

Modified: compiler-rt/trunk/test/msan/dtor-derived-class.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/msan/dtor-derived-class.cc?rev=246817&r1=246816&r2=246817&view=diff
==============================================================================
--- compiler-rt/trunk/test/msan/dtor-derived-class.cc (original)
+++ compiler-rt/trunk/test/msan/dtor-derived-class.cc Thu Sep  3 18:06:13 2015
@@ -1,28 +1,20 @@
-
-// RUN: %clangxx_msan %s -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
-
+// RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
 // RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
-
 // RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1  %run %t >%t.out 2>&1
 
-#include <stdio.h>
 #include <sanitizer/msan_interface.h>
 #include <assert.h>
 
 struct Base {
   int x;
-  Base() {
-    x = 5;
-  }
-  virtual ~Base() { }
+  Base() { x = 5; }
+  virtual ~Base() {}
 };
 
-struct Derived:public Base {
+struct Derived : public Base {
   int y;
-  Derived() {
-    y = 10;
-  }
-  ~Derived() { }
+  Derived() { y = 10; }
+  ~Derived() {}
 };
 
 int main() {
@@ -38,7 +30,7 @@ int main() {
   Base *b = new Derived();
   b->~Base();
 
-  // Verify that local pointer is unpoisoned, and thate the object's
+  // Verify that local pointer is unpoisoned, and that the object's
   // members are.
   assert(__msan_test_shadow(&b, sizeof(b)) == -1);
   assert(__msan_test_shadow(&b->x, sizeof(b->x)) != -1);

Added: compiler-rt/trunk/test/msan/dtor-multiple-inheritance-trivial-class-members.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/msan/dtor-multiple-inheritance-trivial-class-members.cc?rev=246817&view=auto
==============================================================================
--- compiler-rt/trunk/test/msan/dtor-multiple-inheritance-trivial-class-members.cc (added)
+++ compiler-rt/trunk/test/msan/dtor-multiple-inheritance-trivial-class-members.cc Thu Sep  3 18:06:13 2015
@@ -0,0 +1,152 @@
+// RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
+
+// RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
+
+// RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
+
+#include <sanitizer/msan_interface.h>
+#include <assert.h>
+
+template <class T> class Vector {
+public:
+  int size;
+  ~Vector() {
+    assert(__msan_test_shadow(&this->size, sizeof(this->size)) == -1);
+  }
+};
+
+struct VirtualBase {
+public:
+  Vector<int> virtual_v;
+  int virtual_a;
+  // Pointer to subclass member
+  int *intermediate_a_ptr;
+
+  VirtualBase() {
+    virtual_v.size = 1;
+    virtual_a = 9;
+  }
+  void set_ptr(int *intermediate_a) {
+    this->intermediate_a_ptr = intermediate_a;
+  }
+  virtual ~VirtualBase() {
+    assert(__msan_test_shadow(&virtual_v, sizeof(virtual_v)) == -1);
+    assert(__msan_test_shadow(&virtual_a, sizeof(virtual_a)) == -1);
+    // Derived class member is poisoned
+    assert(__msan_test_shadow(intermediate_a_ptr,
+                              sizeof(*intermediate_a_ptr)) != -1);
+  }
+};
+
+struct Intermediate : virtual public VirtualBase {
+public:
+  int intermediate_a;
+
+  Intermediate() { intermediate_a = 5; }
+  virtual ~Intermediate() {
+    assert(__msan_test_shadow(&this->intermediate_a,
+                              sizeof(this->intermediate_a)) == -1);
+    // Members inherited from VirtualBase unpoisoned
+    assert(__msan_test_shadow(&virtual_v, sizeof(virtual_v)) == -1);
+    assert(__msan_test_shadow(&virtual_a, sizeof(virtual_a)) == -1);
+    assert(__msan_test_shadow(intermediate_a_ptr,
+                              sizeof(*intermediate_a_ptr)) == -1);
+  }
+};
+
+struct Base {
+  int base_a;
+  Vector<int> base_v;
+  double base_b;
+  // Pointers to subclass members
+  int *derived_a_ptr;
+  Vector<int> *derived_v1_ptr;
+  Vector<int> *derived_v2_ptr;
+  double *derived_b_ptr;
+  double *derived_c_ptr;
+
+  Base(int *derived_a, Vector<int> *derived_v1, Vector<int> *derived_v2,
+       double *derived_b, double *derived_c) {
+    base_a = 2;
+    base_v.size = 1;
+    base_b = 13.2324;
+    derived_a_ptr = derived_a;
+    derived_v1_ptr = derived_v1;
+    derived_v2_ptr = derived_v2;
+    derived_b_ptr = derived_b;
+    derived_c_ptr = derived_c;
+  }
+  virtual ~Base() {
+    assert(__msan_test_shadow(&base_a, sizeof(base_a)) == -1);
+    assert(__msan_test_shadow(&base_v, sizeof(base_v)) == -1);
+    assert(__msan_test_shadow(&base_b, sizeof(base_b)) == -1);
+    // Derived class members are poisoned
+    assert(__msan_test_shadow(derived_a_ptr, sizeof(*derived_a_ptr)) != -1);
+    assert(__msan_test_shadow(derived_v1_ptr, sizeof(*derived_v1_ptr)) != -1);
+    assert(__msan_test_shadow(derived_v2_ptr, sizeof(*derived_v2_ptr)) != -1);
+    assert(__msan_test_shadow(derived_b_ptr, sizeof(*derived_b_ptr)) != -1);
+    assert(__msan_test_shadow(derived_c_ptr, sizeof(*derived_c_ptr)) != -1);
+  }
+};
+
+struct Derived : public Base, public Intermediate {
+  int derived_a;
+  Vector<int> derived_v1;
+  Vector<int> derived_v2;
+  double derived_b;
+  double derived_c;
+
+  Derived()
+      : Base(&derived_a, &derived_v1, &derived_v2, &derived_b, &derived_c) {
+    derived_a = 5;
+    derived_v1.size = 1;
+    derived_v2.size = 1;
+    derived_b = 7;
+    derived_c = 10;
+  }
+  ~Derived() {
+    assert(__msan_test_shadow(&derived_a, sizeof(derived_a)) == -1);
+    assert(__msan_test_shadow(&derived_v1, sizeof(derived_v1)) == -1);
+    assert(__msan_test_shadow(&derived_v2, sizeof(derived_v2)) == -1);
+    assert(__msan_test_shadow(&derived_b, sizeof(derived_b)) == -1);
+    assert(__msan_test_shadow(&derived_c, sizeof(derived_c)) == -1);
+  }
+};
+
+int main() {
+  Derived *d = new Derived();
+  d->set_ptr(&d->intermediate_a);
+
+  // Keep track of members of VirtualBase, since the virtual base table
+  // is inaccessible after destruction
+  Vector<int> *temp_virtual_v = &d->virtual_v;
+  int *temp_virtual_a = &d->virtual_a;
+  int **temp_intermediate_a_ptr = &d->intermediate_a_ptr;
+
+  d->~Derived();
+  assert(__msan_test_shadow(&d->derived_a, sizeof(d->derived_a)) != -1);
+  assert(__msan_test_shadow(&d->derived_v1, sizeof(d->derived_v1)) != -1);
+  assert(__msan_test_shadow(&d->derived_v2, sizeof(d->derived_v2)) != -1);
+  assert(__msan_test_shadow(&d->derived_b, sizeof(d->derived_b)) != -1);
+  assert(__msan_test_shadow(&d->derived_c, sizeof(d->derived_c)) != -1);
+
+  // Inherited from base
+  assert(__msan_test_shadow(&d->base_a, sizeof(d->base_a)) != -1);
+  assert(__msan_test_shadow(&d->base_v, sizeof(d->base_v)) != -1);
+  assert(__msan_test_shadow(&d->base_b, sizeof(d->base_b)) != -1);
+  assert(__msan_test_shadow(&d->derived_a_ptr, sizeof(d->derived_a_ptr)) != -1);
+  assert(__msan_test_shadow(&d->derived_v1_ptr, sizeof(d->derived_v1_ptr)) !=
+         -1);
+  assert(__msan_test_shadow(&d->derived_v2_ptr, sizeof(d->derived_v2_ptr)) !=
+         -1);
+  assert(__msan_test_shadow(&d->derived_b_ptr, sizeof(d->derived_b_ptr)) != -1);
+  assert(__msan_test_shadow(&d->derived_c_ptr, sizeof(d->derived_c_ptr)) != -1);
+
+  // Inherited from intermediate
+  assert(__msan_test_shadow(temp_virtual_v, sizeof(*temp_virtual_v)) != -1);
+  assert(__msan_test_shadow(temp_virtual_a, sizeof(*temp_virtual_a)) != -1);
+  assert(__msan_test_shadow(temp_intermediate_a_ptr,
+                            sizeof(*temp_intermediate_a_ptr)) != -1);
+
+  return 0;
+}

Added: compiler-rt/trunk/test/msan/dtor-multiple-inheritance.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/msan/dtor-multiple-inheritance.cc?rev=246817&view=auto
==============================================================================
--- compiler-rt/trunk/test/msan/dtor-multiple-inheritance.cc (added)
+++ compiler-rt/trunk/test/msan/dtor-multiple-inheritance.cc Thu Sep  3 18:06:13 2015
@@ -0,0 +1,96 @@
+// Defines diamond multiple inheritance structure
+//   A
+//  / \
+// B   C
+//  \ /
+//   Derived
+
+// RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
+
+// RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
+
+// RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
+
+#include <sanitizer/msan_interface.h>
+#include <assert.h>
+
+class A {
+public:
+  int x;
+  int *y_ptr;
+  int *z_ptr;
+  int *w_ptr;
+  A() { x = 5; }
+  void set_ptrs(int *y_ptr, int *z_ptr, int *w_ptr) {
+    this->y_ptr = y_ptr;
+    this->z_ptr = z_ptr;
+    this->w_ptr = w_ptr;
+  }
+  virtual ~A() {
+    assert(__msan_test_shadow(&this->x, sizeof(this->x) == -1));
+    // bad access subclass member
+    assert(__msan_test_shadow(this->y_ptr, sizeof(*this->y_ptr)) != -1);
+    assert(__msan_test_shadow(this->z_ptr, sizeof(*this->z_ptr)) != -1);
+    assert(__msan_test_shadow(this->w_ptr, sizeof(*this->w_ptr)) != -1);
+  }
+};
+
+struct B : virtual public A {
+public:
+  int y;
+  B() { y = 10; }
+  virtual ~B() {
+    assert(__msan_test_shadow(&this->x, sizeof(this->x)) == -1);
+    assert(__msan_test_shadow(&this->y, sizeof(this->y)) == -1);
+    assert(__msan_test_shadow(this->y_ptr, sizeof(*this->y_ptr)) == -1);
+
+    // memory in subclasses is poisoned
+    assert(__msan_test_shadow(this->z_ptr, sizeof(*this->z_ptr)) != -1);
+    assert(__msan_test_shadow(this->w_ptr, sizeof(*this->w_ptr)) != -1);
+  }
+};
+
+struct C : virtual public A {
+public:
+  int z;
+  C() { z = 15; }
+  virtual ~C() {
+    assert(__msan_test_shadow(&this->x, sizeof(this->x)) == -1);
+    assert(__msan_test_shadow(&this->z, sizeof(this->z)) == -1);
+    assert(__msan_test_shadow(this->y_ptr, sizeof(*this->y_ptr)) == -1);
+    assert(__msan_test_shadow(this->z_ptr, sizeof(*this->z_ptr) == -1));
+
+    // memory in subclasses is poisoned
+    assert(__msan_test_shadow(this->w_ptr, sizeof(*this->w_ptr)) != -1);
+  }
+};
+
+class Derived : public B, public C {
+public:
+  int w;
+  Derived() { w = 10; }
+  ~Derived() {
+    assert(__msan_test_shadow(&this->x, sizeof(this->x)) == -1);
+    assert(__msan_test_shadow(&this->y, sizeof(this->y)) == -1);
+    assert(__msan_test_shadow(&this->w, sizeof(this->w)) == -1);
+  }
+};
+
+int main() {
+  Derived *d = new Derived();
+  d->set_ptrs(&d->y, &d->z, &d->w);
+
+  // Order of destruction: Derived, C, B, A
+  d->~Derived();
+  // Verify that local pointer is unpoisoned, and that the object's
+  // members are.
+  assert(__msan_test_shadow(&d, sizeof(d)) == -1);
+  assert(__msan_test_shadow(&d->x, sizeof(d->x)) != -1);
+  assert(__msan_test_shadow(&d->y, sizeof(d->y)) != -1);
+  assert(__msan_test_shadow(&d->z, sizeof(d->z)) != -1);
+  assert(__msan_test_shadow(&d->w, sizeof(d->w)) != -1);
+  assert(__msan_test_shadow(&d->y_ptr, sizeof(d->y_ptr)) != -1);
+  assert(__msan_test_shadow(&d->z_ptr, sizeof(d->z_ptr)) != -1);
+  assert(__msan_test_shadow(&d->w_ptr, sizeof(d->w_ptr)) != -1);
+  return 0;
+}

Added: compiler-rt/trunk/test/msan/dtor-trivial-class-members.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/msan/dtor-trivial-class-members.cc?rev=246817&view=auto
==============================================================================
--- compiler-rt/trunk/test/msan/dtor-trivial-class-members.cc (added)
+++ compiler-rt/trunk/test/msan/dtor-trivial-class-members.cc Thu Sep  3 18:06:13 2015
@@ -0,0 +1,55 @@
+// RUN: %clangxx_msan %s -O0 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
+
+// RUN: %clangxx_msan %s -O1 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
+
+// RUN: %clangxx_msan %s -O2 -fsanitize=memory -fsanitize-memory-use-after-dtor -o %t && MSAN_OPTIONS=poison_in_dtor=1 %run %t >%t.out 2>&1
+
+#include <sanitizer/msan_interface.h>
+#include <assert.h>
+#include <stdio.h>
+
+template <class T>
+class Vector {
+public:
+  int size;
+  ~Vector() {
+    printf("~V %p %lu\n", &size, sizeof(size));
+    assert(__msan_test_shadow(&this->size, sizeof(this->size)) == -1);
+  }
+};
+
+struct Derived {
+  int derived_a;
+  Vector<int> derived_v1;
+  Vector<int> derived_v2;
+  double derived_b;
+  double derived_c;
+  Derived() {
+    derived_a = 5;
+    derived_v1.size = 1;
+    derived_v2.size = 1;
+    derived_b = 7;
+    derived_c = 10;
+  }
+  ~Derived() {
+    printf("~D %p %p %p %lu\n", &derived_a, &derived_v1, &derived_c, sizeof(*this));
+    assert(__msan_test_shadow(&derived_a, sizeof(derived_a)) == -1);
+    assert(__msan_test_shadow(&derived_v1, sizeof(derived_v1)) == -1);
+    assert(__msan_test_shadow(&derived_v2, sizeof(derived_v2)) == -1);
+    assert(__msan_test_shadow(&derived_b, sizeof(derived_b)) == -1);
+    assert(__msan_test_shadow(&derived_c, sizeof(derived_c)) == -1);
+  }
+};
+
+int main() {
+  Derived *d = new Derived();
+  d->~Derived();
+
+  assert(__msan_test_shadow(&d->derived_a, sizeof(d->derived_a)) != -1);
+  assert(__msan_test_shadow(&d->derived_v1, sizeof(d->derived_v1)) != -1);
+  assert(__msan_test_shadow(&d->derived_v2, sizeof(d->derived_v2)) != -1);
+  assert(__msan_test_shadow(&d->derived_b, sizeof(d->derived_b)) != -1);
+  assert(__msan_test_shadow(&d->derived_c, sizeof(d->derived_c)) != -1);
+
+  return 0;
+}




More information about the llvm-commits mailing list