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).