This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Zero vptr in dtor for -fsanitize=vptr.
- From: Martin Liška <mliska at suse dot cz>
- To: Jason Merrill <jason at redhat dot com>
- Cc: Nathan Sidwell <nathan at acm dot org>, Jakub Jelinek <jakub at redhat dot com>, gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 6 Nov 2017 09:27:07 +0100
- Subject: Re: [PATCH] Zero vptr in dtor for -fsanitize=vptr.
- Authentication-results: sourceware.org; auth=none
- References: <1d468e04-9f25-65f4-04a1-51b35abb3582@suse.cz> <20171027105212.GC14653@tucnak> <63fcd2b6-44d0-cb4b-d518-99eb496c1686@suse.cz> <20171027112600.GD14653@tucnak> <c28079ae-8d28-113a-8c02-7e60e86b52bb@suse.cz> <20171027135259.GG14653@tucnak> <CADzB+2kAqgX6dfhuNvcvAKatjQxRnvxTBQ2ZvD84WRubr_EFWA@mail.gmail.com> <20171027181831.GH14653@tucnak> <a0aaef40-f741-034d-10cb-45fedc4616f7@acm.org> <20171027183428.GI14653@tucnak> <3ee8c949-aa07-a998-a082-34fb2b4f5c73@acm.org> <f6376de4-a151-3f22-afa8-c357f73c3c11@suse.cz> <CADzB+2kqJpzDF0LhiTAVKauq9YLWRGetECm-rVfY=7URxHPHug@mail.gmail.com>
On 11/03/2017 04:21 PM, Jason Merrill wrote:
> On Fri, Nov 3, 2017 at 10:25 AM, Martin Liška <mliska@suse.cz> wrote:
>> On 10/27/2017 09:44 PM, Nathan Sidwell wrote:
>>> On 10/27/2017 02:34 PM, Jakub Jelinek wrote:
>>>
>>>> But when singly inheriting a polymorphic base and thus mapped to the same
>>>> vptr all but the last dtor will not be in charge, right?
>>>
>>> Correct.
>>>
>>>> So, if using build_clobber_this for this, instead of clobbering what we
>>>> clobber we'd just clear the single vptr (couldn't clobber the rest, even
>>>> if before the store, because that would make the earlier other vptr stores
>>>> dead).
>>>
>>> ok (I'd not looked at the patch to see if in chargeness was signficant)
>>>
>>> nathan
>>>
>>
>> Hello.
>>
>> I'm sending v2 which only zeros vptr of object.
>>
>> Ready to be installed after finishing tests?
>
> Surely we also want to check TYPE_CONTAINS_VPTR_P.
>
> Jason
>
Done that in attached patch.
Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
Ready to be installed?
Martin
>From 882becbc5446f304a9445281c6f778b80086ce39 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Thu, 19 Oct 2017 11:10:19 +0200
Subject: [PATCH] Zero vptr in dtor for -fsanitize=vptr.
gcc/cp/ChangeLog:
2017-11-03 Martin Liska <mliska@suse.cz>
* decl.c (begin_destructor_body): In case of VPTR sanitization
(with disabled recovery), zero vptr in order to catch virtual calls
after lifetime of an object.
gcc/testsuite/ChangeLog:
2017-10-27 Martin Liska <mliska@suse.cz>
* g++.dg/ubsan/vptr-12.C: New test.
---
gcc/cp/decl.c | 21 ++++++++++++++++++++-
gcc/testsuite/g++.dg/ubsan/vptr-12.C | 22 ++++++++++++++++++++++
2 files changed, 42 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 0ce8f2d3435..48d2760afde 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -15247,7 +15247,26 @@ begin_destructor_body (void)
if (flag_lifetime_dse
/* Clobbering an empty base is harmful if it overlays real data. */
&& !is_empty_class (current_class_type))
- finish_decl_cleanup (NULL_TREE, build_clobber_this ());
+ {
+ if (sanitize_flags_p (SANITIZE_VPTR)
+ && (flag_sanitize_recover & SANITIZE_VPTR) == 0
+ && TYPE_CONTAINS_VPTR_P (current_class_type))
+ {
+ tree binfo = TYPE_BINFO (current_class_type);
+ tree ref
+ = cp_build_indirect_ref (current_class_ptr, RO_NULL,
+ tf_warning_or_error);
+
+ tree vtbl_ptr = build_vfield_ref (ref, TREE_TYPE (binfo));
+ tree vtbl = build_zero_cst (TREE_TYPE (vtbl_ptr));
+ tree stmt = cp_build_modify_expr (input_location, vtbl_ptr,
+ NOP_EXPR, vtbl,
+ tf_warning_or_error);
+ finish_decl_cleanup (NULL_TREE, stmt);
+ }
+ else
+ finish_decl_cleanup (NULL_TREE, build_clobber_this ());
+ }
/* And insert cleanups for our bases and members so that they
will be properly destroyed if we throw. */
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..f23bbc3fd10
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/vptr-12.C
@@ -0,0 +1,22 @@
+// { 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:16:\[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" }
--
2.14.3