public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug sanitizer/67515] New: "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list
@ 2015-09-09 11:49 rogero at howzatt dot demon.co.uk
  2015-09-09 12:37 ` [Bug sanitizer/67515] " redi at gcc dot gnu.org
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: rogero at howzatt dot demon.co.uk @ 2015-09-09 11:49 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67515

            Bug ID: 67515
           Summary: "invalid vptr" false positive or crash from ubsan for
                    non-virtual call in initializer list
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: sanitizer
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rogero at howzatt dot demon.co.uk
                CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
                    jakub at gcc dot gnu.org, kcc at gcc dot gnu.org
  Target Milestone: ---

Created attachment 36312
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36312&action=edit
Sample program showing the false positive and the seg fault

ubsan produces a warning at runtime from the attached code and then crashes.

The crash is provoked by performing a placement new with a pre-populated
buffer, but can occur 'in the wild' depending on what the memory contents are
at runtime.

Fails with trunk (as at 2015-09-08 using http://melpon.org/wandbox/) and gcc
5.2.0

(This may possibly be related to pr67258)


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug sanitizer/67515] "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list
  2015-09-09 11:49 [Bug sanitizer/67515] New: "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list rogero at howzatt dot demon.co.uk
@ 2015-09-09 12:37 ` redi at gcc dot gnu.org
  2015-09-09 12:41 ` redi at gcc dot gnu.org
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2015-09-09 12:37 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67515

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
12.6.2 [class.base.init] p16 says this is undefined (and has a very similar
example).


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug sanitizer/67515] "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list
  2015-09-09 11:49 [Bug sanitizer/67515] New: "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list rogero at howzatt dot demon.co.uk
  2015-09-09 12:37 ` [Bug sanitizer/67515] " redi at gcc dot gnu.org
@ 2015-09-09 12:41 ` redi at gcc dot gnu.org
  2015-09-09 12:51 ` trippels at gcc dot gnu.org
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: redi at gcc dot gnu.org @ 2015-09-09 12:41 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67515

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
A message about a vptr is a bit mis-leading for non-virtual call, so maybe that
could be improved, but in essence 'this' is not well-defined at that point.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug sanitizer/67515] "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list
  2015-09-09 11:49 [Bug sanitizer/67515] New: "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list rogero at howzatt dot demon.co.uk
  2015-09-09 12:37 ` [Bug sanitizer/67515] " redi at gcc dot gnu.org
  2015-09-09 12:41 ` redi at gcc dot gnu.org
@ 2015-09-09 12:51 ` trippels at gcc dot gnu.org
  2015-09-09 13:09 ` rogero at howzatt dot demon.co.uk
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: trippels at gcc dot gnu.org @ 2015-09-09 12:51 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67515

Markus Trippelsdorf <trippels at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|RESOLVED                    |REOPENED
   Last reconfirmed|                            |2015-09-09
                 CC|                            |trippels at gcc dot gnu.org
         Resolution|INVALID                     |---
     Ever confirmed|0                           |1

--- Comment #3 from Markus Trippelsdorf <trippels at gcc dot gnu.org> ---
markus@x4 tmp % cat ub.ii
extern "C" void memset(void *, int, int);
struct A {
  A(int) {}
};
struct test : A {
  test() : A(m_fn1()) {}
  int m_fn1() { return 0; }
  virtual ~test() {}
};

int a[8];
void *operator new(unsigned long, void *p2) { return p2; }

int main() {
  test b;
  memset(a, '\x7f', sizeof 0);
  new (a) test;
}
markus@x4 tmp % clang++ -fsanitize=undefined -O3 ub.ii -Wall -Wextra
markus@x4 tmp % ./a.out
markus@x4 tmp % g++ -fsanitize=undefined -O3 ub.ii -Wall -Wextra
markus@x4 tmp % ./a.out
ub.ii:6:19: runtime error: member call on address 0x7ffddf2a17b0 which does not
point to an object of type 'test'
0x7ffddf2a17b0: note: object has invalid vptr
 00 00 00 00  a0 18 2a df fd 7f 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00
00 00 00  f0 04 42 02
              ^~~~~~~~~~~~~~~~~~~~~~~
              invalid vptr
[1]    31199 segmentation fault  ./a.out


(In reply to Jonathan Wakely from comment #2)
> A message about a vptr is a bit mis-leading for non-virtual call, so maybe
> that could be improved, but in essence 'this' is not well-defined at that
> point.

But it shouldn't segfault in __ubsan::checkDynamicType().


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug sanitizer/67515] "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list
  2015-09-09 11:49 [Bug sanitizer/67515] New: "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list rogero at howzatt dot demon.co.uk
                   ` (2 preceding siblings ...)
  2015-09-09 12:51 ` trippels at gcc dot gnu.org
@ 2015-09-09 13:09 ` rogero at howzatt dot demon.co.uk
  2015-09-09 13:10 ` trippels at gcc dot gnu.org
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: rogero at howzatt dot demon.co.uk @ 2015-09-09 13:09 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67515

--- Comment #4 from Roger Orr <rogero at howzatt dot demon.co.uk> ---
Ah - apologies -- I'd got the example by stripping down a call in boost::format
and didn't do a full enough check that the code was well formed: I'll report
that UB to boost.

However as Markus says the seg fault remains troublesome.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug sanitizer/67515] "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list
  2015-09-09 11:49 [Bug sanitizer/67515] New: "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list rogero at howzatt dot demon.co.uk
                   ` (3 preceding siblings ...)
  2015-09-09 13:09 ` rogero at howzatt dot demon.co.uk
@ 2015-09-09 13:10 ` trippels at gcc dot gnu.org
  2015-09-09 13:21 ` jakub at gcc dot gnu.org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: trippels at gcc dot gnu.org @ 2015-09-09 13:10 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67515

--- Comment #5 from Markus Trippelsdorf <trippels at gcc dot gnu.org> ---
(anonymous namespace)::getVtablePrefix (Object=0x401460 <a>) at
../../../../gcc/libsanitizer/ubsan/ubsan_type_hash.cc:200
200       if (Prefix->Offset > 0 || !Prefix->TypeInfo)
(gdb) bt
#0  (anonymous namespace)::getVtablePrefix (Object=0x401460 <a>) at
../../../../gcc/libsanitizer/ubsan/ubsan_type_hash.cc:200
#1  __ubsan::checkDynamicType (Object=Object@entry=0x401460 <a>, Type=0x400d78
<typeinfo for test>, Hash=17814158270761423139)
    at ../../../../gcc/libsanitizer/ubsan/ubsan_type_hash.cc:219
#2  0x00007ffff72d8203 in HandleDynamicTypeCacheMiss (Data=0x401320,
Pointer=4199520, Hash=<optimized out>, Opts=...)
    at ../../../../gcc/libsanitizer/ubsan/ubsan_handlers_cxx.cc:31
#3  0x00007ffff72d8963 in __ubsan::__ubsan_handle_dynamic_type_cache_miss
(Data=<optimized out>, Pointer=<optimized out>, Hash=<optimized out>)
    at ../../../../gcc/libsanitizer/ubsan/ubsan_handlers_cxx.cc:74
#4  0x0000000000400a95 in main ()


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug sanitizer/67515] "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list
  2015-09-09 11:49 [Bug sanitizer/67515] New: "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list rogero at howzatt dot demon.co.uk
                   ` (4 preceding siblings ...)
  2015-09-09 13:10 ` trippels at gcc dot gnu.org
@ 2015-09-09 13:21 ` jakub at gcc dot gnu.org
  2015-09-09 13:26 ` [Bug sanitizer/67515] crash from ubsan for non-virtual call in initializer list with an invalid vtable pinskia at gcc dot gnu.org
  2015-09-09 13:33 ` jakub at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: jakub at gcc dot gnu.org @ 2015-09-09 13:21 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67515

--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The problem is that to avoid the segfault, you'd need to significantly slow
down the library code (pretty much, instead of
  if (Prefix->Offset > 0 || !Prefix->TypeInfo)
    // This can't possibly be a valid vtable.
    return 0;
you'd need something like write (dev_null_fd, VtablePrefix, sizeof
(*VtablePrefix)); first and check if it didn't return -1 / EFAULT (because the
library hardly can install segfault handlers).
The library assumes that the virtual table pointers contain either valid, or
previously valid vptrs (or NULL).
So, to get rid of some of the segfaults, but not all, it could e.g. write NULL
to the virtual table pointer at the start of the constructor, before starting
to construct the base classes, or something similar (if -fsanitize=vptr only,
of course).


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug sanitizer/67515] crash from ubsan for non-virtual call in initializer list with an invalid vtable
  2015-09-09 11:49 [Bug sanitizer/67515] New: "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list rogero at howzatt dot demon.co.uk
                   ` (5 preceding siblings ...)
  2015-09-09 13:21 ` jakub at gcc dot gnu.org
@ 2015-09-09 13:26 ` pinskia at gcc dot gnu.org
  2015-09-09 13:33 ` jakub at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2015-09-09 13:26 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67515

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|"invalid vptr" false        |crash from ubsan for
                   |positive or crash from      |non-virtual call in
                   |ubsan for non-virtual call  |initializer list with an
                   |in initializer list         |invalid vtable

--- Comment #7 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Correct the summary.  To some extent this is inside libubsan so it should be
reported upstream too.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug sanitizer/67515] crash from ubsan for non-virtual call in initializer list with an invalid vtable
  2015-09-09 11:49 [Bug sanitizer/67515] New: "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list rogero at howzatt dot demon.co.uk
                   ` (6 preceding siblings ...)
  2015-09-09 13:26 ` [Bug sanitizer/67515] crash from ubsan for non-virtual call in initializer list with an invalid vtable pinskia at gcc dot gnu.org
@ 2015-09-09 13:33 ` jakub at gcc dot gnu.org
  7 siblings, 0 replies; 9+ messages in thread
From: jakub at gcc dot gnu.org @ 2015-09-09 13:33 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67515

--- Comment #8 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
You can get the same segfault with clang++ e.g. on
struct A
{
  int a;
  A () {}
  int foo () { return 1; }
  virtual ~A () {}
};
alignas (A) char buf[sizeof (A)];

void foo (void *x)
{
  A *y = (A *) x;
  y->foo ();
}

int main ()
{
  __builtin_memset (buf, '\x7f', sizeof 0);
  foo (&buf);
}
(but as in this case it is really called on object not even started to be
constructed, there is no other workaround than to slow down the library).


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2015-09-09 13:33 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-09 11:49 [Bug sanitizer/67515] New: "invalid vptr" false positive or crash from ubsan for non-virtual call in initializer list rogero at howzatt dot demon.co.uk
2015-09-09 12:37 ` [Bug sanitizer/67515] " redi at gcc dot gnu.org
2015-09-09 12:41 ` redi at gcc dot gnu.org
2015-09-09 12:51 ` trippels at gcc dot gnu.org
2015-09-09 13:09 ` rogero at howzatt dot demon.co.uk
2015-09-09 13:10 ` trippels at gcc dot gnu.org
2015-09-09 13:21 ` jakub at gcc dot gnu.org
2015-09-09 13:26 ` [Bug sanitizer/67515] crash from ubsan for non-virtual call in initializer list with an invalid vtable pinskia at gcc dot gnu.org
2015-09-09 13:33 ` jakub at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).