This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Zero vptr in dtor for -fsanitize=vptr.


Hello.

This is small improvement that can catch a virtual call after a lifetime
scope of an object.


Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.

Ready to be installed?
Martin

gcc/cp/ChangeLog:

2017-10-27  Martin Liska  <mliska@suse.cz>

	* decl.c (begin_destructor_body): In case of disabled recovery,
	we can zero object in order to catch virtual calls after
	an object lifetime.

gcc/testsuite/ChangeLog:

2017-10-27  Martin Liska  <mliska@suse.cz>

	* g++.dg/ubsan/vptr-12.C: New test.
---
 gcc/cp/decl.c                        |  3 ++-
 gcc/testsuite/g++.dg/ubsan/vptr-12.C | 26 ++++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/ubsan/vptr-12.C


diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 15a8d283353..69636e30008 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -15281,7 +15281,8 @@ begin_destructor_body (void)
 	  /* Clobbering an empty base is harmful if it overlays real data.  */
 	  && !is_empty_class (current_class_type))
 	{
-	  if (sanitize_flags_p (SANITIZE_VPTR))
+	  if (sanitize_flags_p (SANITIZE_VPTR)
+	      && (flag_sanitize_recover & SANITIZE_VPTR) == 0)
 	    {
 	      tree fndecl = builtin_decl_explicit (BUILT_IN_MEMSET);
 	      tree call = build_call_expr (fndecl, 3,
diff --git a/gcc/testsuite/g++.dg/ubsan/vptr-12.C b/gcc/testsuite/g++.dg/ubsan/vptr-12.C
new file mode 100644
index 00000000000..96c8473d757
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/vptr-12.C
@@ -0,0 +1,26 @@
+// { dg-do run }
+// { dg-shouldfail "ubsan" }
+// { dg-options "-fsanitize=vptr -fno-sanitize-recover=vptr" }
+
+struct MyClass
+{
+  virtual ~MyClass () {}
+  virtual void
+  Doit ()
+  {
+  }
+};
+
+int
+main ()
+{
+  MyClass *c = new MyClass;
+  c->~MyClass ();
+  c->Doit ();
+
+  return 0;
+}
+
+// { dg-output "\[^\n\r]*vptr-12.C:19:\[0-9]*: runtime error: member call on address 0x\[0-9a-fA-F]* which does not point to an object of type 'MyClass'(\n|\r\n|\r)" }
+// { dg-output "0x\[0-9a-fA-F]*: note: object has invalid vptr(\n|\r\n|\r)" }
+


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]