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: Marek Polacek <polacek at redhat dot com>
- To: Martin Liška <mliska at suse dot cz>
- Cc: Nathan Sidwell <nathan at acm dot org>, Jakub Jelinek <jakub at redhat dot com>, Jason Merrill <jason at redhat dot com>, gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 3 Nov 2017 15:31:12 +0100
- Subject: Re: [PATCH] Zero vptr in dtor for -fsanitize=vptr.
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx07.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx07.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=polacek at redhat dot com
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com ABADBC0467C4
- References: <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>
On Fri, Nov 03, 2017 at 03:25:25PM +0100, Martin Liška 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?
> Martin
> From 098932be5472656c834b402038accb0b861afcc1 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 | 20 +++++++++++++++++++-
> gcc/testsuite/g++.dg/ubsan/vptr-12.C | 22 ++++++++++++++++++++++
> 2 files changed, 41 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 d88c78f348b..d45cc29e636 100644
> --- a/gcc/cp/decl.c
> +++ b/gcc/cp/decl.c
> @@ -15241,7 +15241,25 @@ 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)
> + {
> + 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..be5c074dfc1
> --- /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(\n|\r\n|\r)" }
I think the last dg-output shouldn't have any regexps at the end, so:
// { dg-output "0x\[0-9a-fA-F]*: note: object has invalid vptr" }
Marek