This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Zero vptr in dtor for -fsanitize=vptr.
- From: Martin Liška <mliska at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Jason Merrill <jason at redhat dot com>, Jakub Jelinek <jakub at redhat dot com>
- Date: Fri, 27 Oct 2017 12:47:12 +0200
- Subject: [PATCH] Zero vptr in dtor for -fsanitize=vptr.
- Authentication-results: sourceware.org; auth=none
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)" }
+