public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/102217] New: co_awaiting a temporary produced by ternary operator crashes (double-free)
@ 2021-09-06 11:01 max at duempel dot org
  2021-11-19 11:49 ` [Bug c++/102217] " max at duempel dot org
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: max at duempel dot org @ 2021-09-06 11:01 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 102217
           Summary: co_awaiting a temporary produced by ternary operator
                    crashes (double-free)
           Product: gcc
           Version: 11.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: max at duempel dot org
  Target Milestone: ---

Created attachment 51414
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51414&action=edit
Crashing demo program

When awaiting a coroutine task which is a temporary evaluated with the ternary
operator, GCC emits faulty code that destructs the task twice, leading to a
crash due to double free / use-after-free.

Tested with "gcc version 10.2.1 20210110 (Debian 10.2.1-6)" and "gcc version
11.2.0 (Debian 11.2.0-1)"

clang ("Debian clang version 11.0.1-2") is fine.

This crash bug can be worked around by assigning the result of the ternary
operator to a local variable first, and then co_await that variable.

In my demo program, the UniqueHandle destructor gets called twice with the same
contained pointer value; however, the UniqueHandle instance that gets
destructed first was never constructed.

ASan output with GCC 11:

==2==ERROR: AddressSanitizer: heap-use-after-free on address 0x606000000028 at
pc 0x5573042b18a9 bp 0x7ffdde510f60 sp 0x7ffdde510f58
READ of size 8 at 0x606000000028 thread T0
    #0 0x5573042b18a8 in Co::UniqueHandle<Co::promise<Foo, Co::Task<Foo> >
>::~UniqueHandle() (/home/max/dl/a.out+0x28a8)
    #1 0x5573042b1284 in FooC(FooC(bool)::_Z4FooCb.frame*) [clone .actor]
(/home/max/dl/a.out+0x2284)
    #2 0x5573042b0582 in FooA(FooA()::_Z4FooAv.frame*) [clone .actor]
(/home/max/dl/a.out+0x1582)
    #3 0x5573042b13a1 in FooC(FooC(bool)::_Z4FooCb.frame*) [clone .actor]
(/home/max/dl/a.out+0x23a1)
    #4 0x5573042b00dd in main (/home/max/dl/a.out+0x10dd)
    #5 0x7fa1f4ffbe39 in __libc_start_main
(/lib/x86_64-linux-gnu/libc.so.6+0x27e39)
    #6 0x5573042b01e9 in _start (/home/max/dl/a.out+0x11e9)

0x606000000028 is located 8 bytes inside of 64-byte region
[0x606000000020,0x606000000060)
freed by thread T0 here:
    #0 0x7fa1f55b6957 in operator delete(void*)
../../../../src/libsanitizer/asan/asan_new_delete.cpp:160
    #1 0x5573042b05b7 in FooA(FooA()::_Z4FooAv.frame*) [clone .actor]
(/home/max/dl/a.out+0x15b7)

previously allocated by thread T0 here:
    #0 0x7fa1f55b5f57 in operator new(unsigned long)
../../../../src/libsanitizer/asan/asan_new_delete.cpp:99
    #1 0x5573042b0af5 in FooA() (/home/max/dl/a.out+0x1af5)

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

* [Bug c++/102217] co_awaiting a temporary produced by ternary operator crashes (double-free)
  2021-09-06 11:01 [Bug c++/102217] New: co_awaiting a temporary produced by ternary operator crashes (double-free) max at duempel dot org
@ 2021-11-19 11:49 ` max at duempel dot org
  2021-11-19 11:52 ` max at duempel dot org
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: max at duempel dot org @ 2021-11-19 11:49 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #1 from Max Kellermann <max at duempel dot org> ---
Tested again with "g++-11 (Debian 11.2.0-10) 11.2.0", and my demo program still
crashes.

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

* [Bug c++/102217] co_awaiting a temporary produced by ternary operator crashes (double-free)
  2021-09-06 11:01 [Bug c++/102217] New: co_awaiting a temporary produced by ternary operator crashes (double-free) max at duempel dot org
  2021-11-19 11:49 ` [Bug c++/102217] " max at duempel dot org
@ 2021-11-19 11:52 ` max at duempel dot org
  2022-03-04 13:53 ` kux@smart-hmi.de
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: max at duempel dot org @ 2021-11-19 11:52 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #2 from Max Kellermann <max at duempel dot org> ---
Also crashes with "gcc version 12.0.0 20211117 (experimental) [master
r12-5346-gd3a9082d7ac] (Debian 12-20211117-1)"

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

* [Bug c++/102217] co_awaiting a temporary produced by ternary operator crashes (double-free)
  2021-09-06 11:01 [Bug c++/102217] New: co_awaiting a temporary produced by ternary operator crashes (double-free) max at duempel dot org
  2021-11-19 11:49 ` [Bug c++/102217] " max at duempel dot org
  2021-11-19 11:52 ` max at duempel dot org
@ 2022-03-04 13:53 ` kux@smart-hmi.de
  2022-11-02 11:41 ` redi at gcc dot gnu.org
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: kux@smart-hmi.de @ 2022-03-04 13:53 UTC (permalink / raw)
  To: gcc-bugs

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

kux@smart-hmi.de changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |kux@smart-hmi.de

--- Comment #3 from kux@smart-hmi.de ---
Program now causes an ICE with "gcc version 12.0.1 20220303" as can be seen on
https://godbolt.org/z/1x5EeTK4h

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

* [Bug c++/102217] co_awaiting a temporary produced by ternary operator crashes (double-free)
  2021-09-06 11:01 [Bug c++/102217] New: co_awaiting a temporary produced by ternary operator crashes (double-free) max at duempel dot org
                   ` (2 preceding siblings ...)
  2022-03-04 13:53 ` kux@smart-hmi.de
@ 2022-11-02 11:41 ` redi at gcc dot gnu.org
  2022-11-02 11:43 ` redi at gcc dot gnu.org
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2022-11-02 11:41 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |ice-on-valid-code
   Last reconfirmed|                            |2022-11-02
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
=================================================================
==624580==ERROR: AddressSanitizer: heap-use-after-free on address
0x606000000028 at pc 0x0000004042b1 bp 0x7ffe18357490 sp 0x7ffe18357488
READ of size 8 at 0x606000000028 thread T0
    #0 0x4042b0 in std::__n4861::coroutine_handle<Co::promise<Foo,
Co::Task<Foo> > >::destroy() const
/home/jwakely/gcc/12.1.0/include/c++/12.1.0/coroutine:246
    #1 0x403cb7 in Co::UniqueHandle<Co::promise<Foo, Co::Task<Foo> >
>::~UniqueHandle() /tmp/cocrash.cxx:37
    #2 0x403767 in Co::Task<Foo>::~Task() /tmp/cocrash.cxx:135
    #3 0x402a47 in FooC /tmp/cocrash.cxx:171
    #4 0x4018c2 in FooA /tmp/cocrash.cxx:160
    #5 0x402c11 in FooC /tmp/cocrash.cxx:168
    #6 0x403501 in std::__n4861::coroutine_handle<void>::resume() const
/home/jwakely/gcc/12.1.0/include/c++/12.1.0/coroutine:135
    #7 0x402f84 in main /tmp/cocrash.cxx:177
    #8 0x7f66323e750f in __libc_start_call_main (/lib64/libc.so.6+0x2950f)
    #9 0x7f66323e75c8 in __libc_start_main_impl (/lib64/libc.so.6+0x295c8)
    #10 0x4011b4 in _start (/tmp/a.out+0x4011b4)

0x606000000028 is located 8 bytes inside of 56-byte region
[0x606000000020,0x606000000058)
freed by thread T0 here:
    #0 0x7f66329bcbb8 in operator delete(void*)
../../../../gcc-12.1.0/libsanitizer/asan/asan_new_delete.cpp:152
    #1 0x401981 in FooA /tmp/cocrash.cxx:162
    #2 0x401a38 in FooA /tmp/cocrash.cxx:160
    #3 0x4042b9 in std::__n4861::coroutine_handle<Co::promise<Foo,
Co::Task<Foo> > >::destroy() const
/home/jwakely/gcc/12.1.0/include/c++/12.1.0/coroutine:246
    #4 0x403cb7 in Co::UniqueHandle<Co::promise<Foo, Co::Task<Foo> >
>::~UniqueHandle() /tmp/cocrash.cxx:37
    #5 0x403767 in Co::Task<Foo>::~Task() /tmp/cocrash.cxx:135
    #6 0x4029ff in FooC /tmp/cocrash.cxx:171
    #7 0x4018c2 in FooA /tmp/cocrash.cxx:160
    #8 0x402c11 in FooC /tmp/cocrash.cxx:168
    #9 0x403501 in std::__n4861::coroutine_handle<void>::resume() const
/home/jwakely/gcc/12.1.0/include/c++/12.1.0/coroutine:135
    #10 0x402f84 in main /tmp/cocrash.cxx:177
    #11 0x7f66323e750f in __libc_start_call_main (/lib64/libc.so.6+0x2950f)

previously allocated by thread T0 here:
    #0 0x7f66329bc178 in operator new(unsigned long)
../../../../gcc-12.1.0/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x40129f in FooA() /tmp/cocrash.cxx:162
    #2 0x4027c2 in FooC /tmp/cocrash.cxx:171
    #3 0x403501 in std::__n4861::coroutine_handle<void>::resume() const
/home/jwakely/gcc/12.1.0/include/c++/12.1.0/coroutine:135
    #4 0x402f84 in main /tmp/cocrash.cxx:177
    #5 0x7f66323e750f in __libc_start_call_main (/lib64/libc.so.6+0x2950f)

SUMMARY: AddressSanitizer: heap-use-after-free
/home/jwakely/gcc/12.1.0/include/c++/12.1.0/coroutine:246 in
std::__n4861::coroutine_handle<Co::promise<Foo, Co::Task<Foo> > >::destroy()
const
Shadow bytes around the buggy address:
  0x0c0c7fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0c7fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0c7fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0c7fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0c7fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c0c7fff8000: fa fa fa fa fd[fd]fd fd fd fd fd fa fa fa fa fa
  0x0c0c7fff8010: fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==624580==ABORTING

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

* [Bug c++/102217] co_awaiting a temporary produced by ternary operator crashes (double-free)
  2021-09-06 11:01 [Bug c++/102217] New: co_awaiting a temporary produced by ternary operator crashes (double-free) max at duempel dot org
                   ` (3 preceding siblings ...)
  2022-11-02 11:41 ` redi at gcc dot gnu.org
@ 2022-11-02 11:43 ` redi at gcc dot gnu.org
  2022-11-24  1:59 ` pinskia at gcc dot gnu.org
  2024-02-05 14:20 ` redi at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2022-11-02 11:43 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I also see the ICE on trunk (but not the release branches) so I suspect it's
related to --enable-checking 

cocrash.cxx: In function 'Co::Task<Foo> FooC(bool)':
cocrash.cxx:171:1: internal compiler error: in flatten_await_stmt, at
cp/coroutines.cc:2891
  171 | }
      | ^
0x6a8242 flatten_await_stmt
        /home/jwakely/src/gcc/gcc/gcc/cp/coroutines.cc:2891
0x9d7d57 flatten_await_stmt
        /home/jwakely/src/gcc/gcc/gcc/cp/coroutines.cc:2920
0x9d7d57 flatten_await_stmt
        /home/jwakely/src/gcc/gcc/gcc/cp/coroutines.cc:2920
0x9d9dee maybe_promote_temps
        /home/jwakely/src/gcc/gcc/gcc/cp/coroutines.cc:3105
0x9d9dee await_statement_walker
        /home/jwakely/src/gcc/gcc/gcc/cp/coroutines.cc:3749
0x14b54d3 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
        /home/jwakely/src/gcc/gcc/gcc/tree.cc:11270
0x9d9f30 await_statement_walker
        /home/jwakely/src/gcc/gcc/gcc/cp/coroutines.cc:3420
0x14b54d3 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
        /home/jwakely/src/gcc/gcc/gcc/tree.cc:11270
0x9d975f await_statement_walker
        /home/jwakely/src/gcc/gcc/gcc/cp/coroutines.cc:3697
0x14b54d3 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
        /home/jwakely/src/gcc/gcc/gcc/tree.cc:11270
0x9da03c await_statement_walker
        /home/jwakely/src/gcc/gcc/gcc/cp/coroutines.cc:3409
0x14b54d3 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
        /home/jwakely/src/gcc/gcc/gcc/tree.cc:11270
0x9d9f30 await_statement_walker
        /home/jwakely/src/gcc/gcc/gcc/cp/coroutines.cc:3420
0x14b54d3 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
        /home/jwakely/src/gcc/gcc/gcc/tree.cc:11270
0x14b56dd walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
        /home/jwakely/src/gcc/gcc/gcc/tree.cc:11501
0x9d9f30 await_statement_walker
        /home/jwakely/src/gcc/gcc/gcc/cp/coroutines.cc:3420
0x14b54d3 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
        /home/jwakely/src/gcc/gcc/gcc/tree.cc:11270
0x9da03c await_statement_walker
        /home/jwakely/src/gcc/gcc/gcc/cp/coroutines.cc:3409
0x14b54d3 walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*,
tree_node* (*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, false, default_hash_traits<tree_node*> >*))
        /home/jwakely/src/gcc/gcc/gcc/tree.cc:11270
0x9db8e5 morph_fn_to_coro(tree_node*, tree_node**, tree_node**)
        /home/jwakely/src/gcc/gcc/gcc/cp/coroutines.cc:4496
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.

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

* [Bug c++/102217] co_awaiting a temporary produced by ternary operator crashes (double-free)
  2021-09-06 11:01 [Bug c++/102217] New: co_awaiting a temporary produced by ternary operator crashes (double-free) max at duempel dot org
                   ` (4 preceding siblings ...)
  2022-11-02 11:43 ` redi at gcc dot gnu.org
@ 2022-11-24  1:59 ` pinskia at gcc dot gnu.org
  2024-02-05 14:20 ` redi at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu.org @ 2022-11-24  1:59 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |adrian@adi-ware.ch

--- Comment #6 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
*** Bug 107854 has been marked as a duplicate of this bug. ***

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

* [Bug c++/102217] co_awaiting a temporary produced by ternary operator crashes (double-free)
  2021-09-06 11:01 [Bug c++/102217] New: co_awaiting a temporary produced by ternary operator crashes (double-free) max at duempel dot org
                   ` (5 preceding siblings ...)
  2022-11-24  1:59 ` pinskia at gcc dot gnu.org
@ 2024-02-05 14:20 ` redi at gcc dot gnu.org
  6 siblings, 0 replies; 8+ messages in thread
From: redi at gcc dot gnu.org @ 2024-02-05 14:20 UTC (permalink / raw)
  To: gcc-bugs

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

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

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |iains at gcc dot gnu.org

--- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> ---
This seems to be fixed in 13.1 too.

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

end of thread, other threads:[~2024-02-05 14:20 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-06 11:01 [Bug c++/102217] New: co_awaiting a temporary produced by ternary operator crashes (double-free) max at duempel dot org
2021-11-19 11:49 ` [Bug c++/102217] " max at duempel dot org
2021-11-19 11:52 ` max at duempel dot org
2022-03-04 13:53 ` kux@smart-hmi.de
2022-11-02 11:41 ` redi at gcc dot gnu.org
2022-11-02 11:43 ` redi at gcc dot gnu.org
2022-11-24  1:59 ` pinskia at gcc dot gnu.org
2024-02-05 14:20 ` redi 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).