* [Bug sanitizer/94325] [UBSAN] "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all
2020-03-25 12:56 [Bug c++/94325] New: [UBSAN] "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all jaroslaw.melzer.gcc at gmail dot com
@ 2020-03-25 13:09 ` marxin at gcc dot gnu.org
2020-03-25 13:58 ` [Bug sanitizer/94325] [8/9/10 Regression] UBSAN: " marxin at gcc dot gnu.org
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: marxin at gcc dot gnu.org @ 2020-03-25 13:09 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94325
Martin Liška <marxin at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Known to fail| |10.0, 9.3.0
Known to work| |7.4.0
Ever confirmed|0 |1
Keywords| |needs-bisection
Last reconfirmed| |2020-03-25
Status|UNCONFIRMED |NEW
--- Comment #1 from Martin Liška <marxin at gcc dot gnu.org> ---
Confirmed, I'm bisecting that.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug sanitizer/94325] [8/9/10 Regression] UBSAN: "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all
2020-03-25 12:56 [Bug c++/94325] New: [UBSAN] "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all jaroslaw.melzer.gcc at gmail dot com
2020-03-25 13:09 ` [Bug sanitizer/94325] " marxin at gcc dot gnu.org
@ 2020-03-25 13:58 ` marxin at gcc dot gnu.org
2020-04-01 9:00 ` rguenth at gcc dot gnu.org
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: marxin at gcc dot gnu.org @ 2020-03-25 13:58 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94325
Martin Liška <marxin at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jason at gcc dot gnu.org,
| |nathan at gcc dot gnu.org
Keywords|needs-bisection |
Summary|[UBSAN] "invalid vptr" |[8/9/10 Regression] UBSAN:
|false positive for virtual |"invalid vptr" false
|inheritance with |positive for virtual
|-fno-sanitize-recover=all |inheritance with
| |-fno-sanitize-recover=all
Known to fail| |8.4.0
--- Comment #2 from Martin Liška <marxin at gcc dot gnu.org> ---
Started with my r8-4602-g896f6b3dfa6fb337109f97bed8d74c1e030c965e.
Anyway, a help from C++ maintainer is more than welcomed.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug sanitizer/94325] [8/9/10 Regression] UBSAN: "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all
2020-03-25 12:56 [Bug c++/94325] New: [UBSAN] "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all jaroslaw.melzer.gcc at gmail dot com
2020-03-25 13:09 ` [Bug sanitizer/94325] " marxin at gcc dot gnu.org
2020-03-25 13:58 ` [Bug sanitizer/94325] [8/9/10 Regression] UBSAN: " marxin at gcc dot gnu.org
@ 2020-04-01 9:00 ` rguenth at gcc dot gnu.org
2020-04-06 11:27 ` jakub at gcc dot gnu.org
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: rguenth at gcc dot gnu.org @ 2020-04-01 9:00 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94325
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Target Milestone|--- |8.5
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug sanitizer/94325] [8/9/10 Regression] UBSAN: "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all
2020-03-25 12:56 [Bug c++/94325] New: [UBSAN] "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all jaroslaw.melzer.gcc at gmail dot com
` (2 preceding siblings ...)
2020-04-01 9:00 ` rguenth at gcc dot gnu.org
@ 2020-04-06 11:27 ` jakub at gcc dot gnu.org
2020-04-06 11:41 ` jakub at gcc dot gnu.org
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-04-06 11:27 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94325
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
sizeof (MD) == sizeof (void *), so the clearing of the vptr in DD::~DD() when
DE::~DE() is invoked later on looks wrong.
But, without -fsanitize=vptr this isn't done.
I've added that guard in PR87095, see
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87095#c3
for more details.
So, either we can just do what build_clobber_this does, which would be just:
--- gcc/cp/decl.c 2020-03-27 09:59:26.407083563 +0100
+++ gcc/cp/decl.c 2020-04-06 13:14:15.814200485 +0200
@@ -16662,10 +16662,7 @@ begin_destructor_body (void)
/* If the vptr is shared with some virtual nearly empty base,
don't clear it if not in charge, the dtor of the virtual
nearly empty base will do that later. */
- if (CLASSTYPE_VBASECLASSES (current_class_type)
- && CLASSTYPE_PRIMARY_BINFO (current_class_type)
- && BINFO_VIRTUAL_P
- (CLASSTYPE_PRIMARY_BINFO (current_class_type)))
+ if (CLASSTYPE_VBASECLASSES (current_class_type))
{
stmt = convert_to_void (stmt, ICV_STATEMENT,
tf_warning_or_error);
or try to narrow down the condition to cover this problematic case too, though
I'm afraid I have no idea what that would be.
Nathan/Jason, can I ask for help here?
A wild shot in the dark could be:
--- gcc/cp/decl.c.jj 2020-03-27 09:59:26.407083563 +0100
+++ gcc/cp/decl.c 2020-04-06 13:25:03.321511554 +0200
@@ -16662,14 +16662,20 @@ begin_destructor_body (void)
/* If the vptr is shared with some virtual nearly empty base,
don't clear it if not in charge, the dtor of the virtual
nearly empty base will do that later. */
- if (CLASSTYPE_VBASECLASSES (current_class_type)
- && CLASSTYPE_PRIMARY_BINFO (current_class_type)
- && BINFO_VIRTUAL_P
- (CLASSTYPE_PRIMARY_BINFO (current_class_type)))
+ if (CLASSTYPE_VBASECLASSES (current_class_type))
{
- stmt = convert_to_void (stmt, ICV_STATEMENT,
- tf_warning_or_error);
- stmt = build_if_in_charge (stmt);
+ tree c = current_class_type;
+ while (CLASSTYPE_PRIMARY_BINFO (c))
+ {
+ if (BINFO_VIRTUAL_P (CLASSTYPE_PRIMARY_BINFO (c)))
+ {
+ stmt = convert_to_void (stmt, ICV_STATEMENT,
+ tf_warning_or_error);
+ stmt = build_if_in_charge (stmt);
+ break;
+ }
+ c = BINFO_TYPE (CLASSTYPE_PRIMARY_BINFO (c));
+ }
}
finish_decl_cleanup (NULL_TREE, stmt);
}
just from the fact that the existing code seemed to DTRT for D::~D() where
CLASSTYPE_VBASECLASSES is non-NULL, CLASSTYPE_PRIMARY_BINFO too and
BINFO_VIRTUAL_P on that is set as well.
But in DD::~DD() the last condition doesn't hold, but BINFO_TYPE of the
CLASSTYPE_PRIMARY_BINFO is D which has this property.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug sanitizer/94325] [8/9/10 Regression] UBSAN: "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all
2020-03-25 12:56 [Bug c++/94325] New: [UBSAN] "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all jaroslaw.melzer.gcc at gmail dot com
` (3 preceding siblings ...)
2020-04-06 11:27 ` jakub at gcc dot gnu.org
@ 2020-04-06 11:41 ` jakub at gcc dot gnu.org
2020-04-08 13:31 ` cvs-commit at gcc dot gnu.org
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-04-06 11:41 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94325
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Created attachment 48210
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48210&action=edit
gcc10-pr94325.patch
The shot in the dark in whole patch form.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug sanitizer/94325] [8/9/10 Regression] UBSAN: "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all
2020-03-25 12:56 [Bug c++/94325] New: [UBSAN] "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all jaroslaw.melzer.gcc at gmail dot com
` (4 preceding siblings ...)
2020-04-06 11:41 ` jakub at gcc dot gnu.org
@ 2020-04-08 13:31 ` cvs-commit at gcc dot gnu.org
2020-04-08 13:33 ` [Bug sanitizer/94325] [8/9 " jakub at gcc dot gnu.org
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2020-04-08 13:31 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94325
--- Comment #5 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:
https://gcc.gnu.org/g:4cf6b06cb5b02c053738e2975e3b7a4b3c577401
commit r10-7620-g4cf6b06cb5b02c053738e2975e3b7a4b3c577401
Author: Jakub Jelinek <jakub@redhat.com>
Date: Wed Apr 8 15:30:16 2020 +0200
c++: Further fix for -fsanitize=vptr [PR94325]
For -fsanitize=vptr, we insert a NULL store into the vptr instead of just
adding a CLOBBER of this. build_clobber_this makes the CLOBBER conditional
on in_charge (implicit) parameter whenever CLASSTYPE_VBASECLASSES, but when
adding this conditionalization to the -fsanitize=vptr code in PR87095,
I wanted it to catch some more cases when the class has
CLASSTYPE_VBASECLASSES,
but the vptr is still not shared with something else, otherwise the
sanitization would be less effective.
The following testcase shows that the chosen test that
CLASSTYPE_PRIMARY_BINFO
is non-NULL and has BINFO_VIRTUAL_P set wasn't sufficient,
the D class has still sizeof(D) == sizeof(void*) and thus contains just
a single vptr, but while in B::~B() this results in the vptr not being
cleared, in C::~C() this condition isn't true, as CLASSTYPE_PRIMARY_BINFO
in that case is B and is not BINFO_VIRTUAL_P, so it clears the vptr, but
the
D::~D() dtor after invoking C::~C() invokes A::~A() with an already cleared
vptr, which is then reported.
The following patch is just a shot in the dark, keep looking through
CLASSTYPE_PRIMARY_BINFO until we find BINFO_VIRTUAL_P, but it works on the
existing testcase as well as this new one.
2020-04-08 Jakub Jelinek <jakub@redhat.com>
PR c++/94325
* decl.c (begin_destructor_body): For CLASSTYPE_VBASECLASSES class
dtors, if CLASSTYPE_PRIMARY_BINFO is non-NULL, but not
BINFO_VIRTUAL_P,
look at CLASSTYPE_PRIMARY_BINFO of its BINFO_TYPE if it is not
BINFO_VIRTUAL_P, and so on.
* g++.dg/ubsan/vptr-15.C: New test.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug sanitizer/94325] [8/9 Regression] UBSAN: "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all
2020-03-25 12:56 [Bug c++/94325] New: [UBSAN] "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all jaroslaw.melzer.gcc at gmail dot com
` (5 preceding siblings ...)
2020-04-08 13:31 ` cvs-commit at gcc dot gnu.org
@ 2020-04-08 13:33 ` jakub at gcc dot gnu.org
2020-09-16 19:20 ` cvs-commit at gcc dot gnu.org
2020-09-17 17:22 ` jakub at gcc dot gnu.org
8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-04-08 13:33 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94325
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Assignee|unassigned at gcc dot gnu.org |jakub at gcc dot gnu.org
Summary|[8/9/10 Regression] UBSAN: |[8/9 Regression] UBSAN:
|"invalid vptr" false |"invalid vptr" false
|positive for virtual |positive for virtual
|inheritance with |inheritance with
|-fno-sanitize-recover=all |-fno-sanitize-recover=all
Status|NEW |ASSIGNED
--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Fixed on the trunk so far.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug sanitizer/94325] [8/9 Regression] UBSAN: "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all
2020-03-25 12:56 [Bug c++/94325] New: [UBSAN] "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all jaroslaw.melzer.gcc at gmail dot com
` (6 preceding siblings ...)
2020-04-08 13:33 ` [Bug sanitizer/94325] [8/9 " jakub at gcc dot gnu.org
@ 2020-09-16 19:20 ` cvs-commit at gcc dot gnu.org
2020-09-17 17:22 ` jakub at gcc dot gnu.org
8 siblings, 0 replies; 10+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2020-09-16 19:20 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94325
--- Comment #7 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-9 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:
https://gcc.gnu.org/g:175f052446556d32e887e1658a5a92c3c2f3a6f5
commit r9-8875-g175f052446556d32e887e1658a5a92c3c2f3a6f5
Author: Jakub Jelinek <jakub@redhat.com>
Date: Wed Apr 8 15:30:16 2020 +0200
c++: Further fix for -fsanitize=vptr [PR94325]
For -fsanitize=vptr, we insert a NULL store into the vptr instead of just
adding a CLOBBER of this. build_clobber_this makes the CLOBBER conditional
on in_charge (implicit) parameter whenever CLASSTYPE_VBASECLASSES, but when
adding this conditionalization to the -fsanitize=vptr code in PR87095,
I wanted it to catch some more cases when the class has
CLASSTYPE_VBASECLASSES,
but the vptr is still not shared with something else, otherwise the
sanitization would be less effective.
The following testcase shows that the chosen test that
CLASSTYPE_PRIMARY_BINFO
is non-NULL and has BINFO_VIRTUAL_P set wasn't sufficient,
the D class has still sizeof(D) == sizeof(void*) and thus contains just
a single vptr, but while in B::~B() this results in the vptr not being
cleared, in C::~C() this condition isn't true, as CLASSTYPE_PRIMARY_BINFO
in that case is B and is not BINFO_VIRTUAL_P, so it clears the vptr, but
the
D::~D() dtor after invoking C::~C() invokes A::~A() with an already cleared
vptr, which is then reported.
The following patch is just a shot in the dark, keep looking through
CLASSTYPE_PRIMARY_BINFO until we find BINFO_VIRTUAL_P, but it works on the
existing testcase as well as this new one.
2020-04-08 Jakub Jelinek <jakub@redhat.com>
PR c++/94325
* decl.c (begin_destructor_body): For CLASSTYPE_VBASECLASSES class
dtors, if CLASSTYPE_PRIMARY_BINFO is non-NULL, but not
BINFO_VIRTUAL_P,
look at CLASSTYPE_PRIMARY_BINFO of its BINFO_TYPE if it is not
BINFO_VIRTUAL_P, and so on.
* g++.dg/ubsan/vptr-15.C: New test.
(cherry picked from commit 4cf6b06cb5b02c053738e2975e3b7a4b3c577401)
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug sanitizer/94325] [8/9 Regression] UBSAN: "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all
2020-03-25 12:56 [Bug c++/94325] New: [UBSAN] "invalid vptr" false positive for virtual inheritance with -fno-sanitize-recover=all jaroslaw.melzer.gcc at gmail dot com
` (7 preceding siblings ...)
2020-09-16 19:20 ` cvs-commit at gcc dot gnu.org
@ 2020-09-17 17:22 ` jakub at gcc dot gnu.org
8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2020-09-17 17:22 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94325
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|ASSIGNED |RESOLVED
Resolution|--- |FIXED
--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Fixed for 8.5 in r8-10484-g1298b488c37c44abf33cca6932e760ef69dd7815 and by the
above commit for 9.4+ too.
^ permalink raw reply [flat|nested] 10+ messages in thread