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