Terminal: Crash: Use after free of std::function through CodepointWidthDetector

Created on 9 Aug 2019  路  7Comments  路  Source: microsoft/terminal

Environment

Windows build number: Microsoft Windows [Version 10.0.18362.267]
Windows Terminal version (if applicable): 0.3.2171.0

Steps to reproduce

I'm honestly not sure what I was doing. This might be #2251?

Expected behavior

The terminal shouldn't crash.

Actual behavior

ExceptionAddress: 00007ffdd2990f60 (uiautomationcore!MenuOpened_Event_GUID)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 0000000000000008
   Parameter[1]: 00007ffdd2990f60
Attempt to execute non-executable address 00007ffdd2990f60

 # Child-SP          RetAddr           Call Site
0c 00000004`2aefe098 00007ffd`b226761b uiautomationcore!MenuOpened_Event_GUID
0d (Inline Function) --------`-------- TerminalControl!std::_Invoker_pmf_pointer::_Call+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\type_traits @ 1457] 
0e (Inline Function) --------`-------- TerminalControl!std::invoke+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\type_traits @ 1457] 
0f (Inline Function) --------`-------- TerminalControl!std::_Invoker_ret<std::_Unforced,0>::_Call+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\type_traits @ 1492] 
10 (Inline Function) --------`-------- TerminalControl!std::_Call_binder+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\functional @ 1485] 
11 (Inline Function) --------`-------- TerminalControl!std::_Binder<std::_Unforced,bool (__cdecl Microsoft::Console::Render::Renderer::*)(std::basic_string_view<wchar_t,std::char_traits<wchar_t> >),Microsoft::Console::Render::Renderer *,std::_Ph<1> const &>::operator()+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\functional @ 1531] 
12 (Inline Function) --------`-------- TerminalControl!std::_Invoker_functor::_Call+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\type_traits @ 1457] 
13 (Inline Function) --------`-------- TerminalControl!std::invoke+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\type_traits @ 1457] 
14 (Inline Function) --------`-------- TerminalControl!std::_Invoker_ret<bool,0>::_Call+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\type_traits @ 1483] 
15 00000004`2aefe0a0 00000000`00000000 TerminalControl!std::_Func_impl_no_alloc<std::_Binder<std::_Unforced,bool (__cdecl Microsoft::Console::Render::Renderer::*)(std::basic_string_view<wchar_t,std::char_traits<wchar_t> >),Microsoft::Console::Render::Renderer *,std::_Ph<1> const &>,bool,std::basic_string_view<wchar_t,std::char_traits<wchar_t> > >::_Do_call+0x1b [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\functional @ 1007] 

I'm happy to share the crash dump out of band.

Area-Server Issue-Bug Needs-Tag-Fix Product-Conhost Product-Terminal Resolution-Fix-Committed Severity-Crash

All 7 comments

Did someone set a callback pointing to a GUID?

This is more likely a use-after-free or an std::function parked on an invalid address than an actual callback pointing to a GUID :grin:

Hmm, after ~1 week without any crash, I just hit a second in the space of a few minutes. Same symptom (std::invoke callback gone awry), different stack.

ExceptionAddress: 00007ffdc19e8b4b (TerminalControl!Microsoft::Console::Render::Renderer::`vcall'{120}'+0x0000000000000003)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 0000000000000000
   Parameter[1]: ffffffffffffffff
Attempt to read from address ffffffffffffffff

0c 000000de`62bfe498 00007ffd`c19e76ab TerminalControl!Microsoft::Console::Render::Renderer::`vcall'{120}'+0x3
0d (Inline Function) --------`-------- TerminalControl!std::_Invoker_pmf_pointer::_Call+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\type_traits @ 1457] 
0e (Inline Function) --------`-------- TerminalControl!std::invoke+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\type_traits @ 1457] 
0f (Inline Function) --------`-------- TerminalControl!std::_Invoker_ret<std::_Unforced,0>::_Call+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\type_traits @ 1492] 
10 (Inline Function) --------`-------- TerminalControl!std::_Call_binder+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\functional @ 1485] 
11 (Inline Function) --------`-------- TerminalControl!std::_Binder<std::_Unforced,bool (__cdecl Microsoft::Console::Render::Renderer::*)(std::basic_string_view<wchar_t,std::char_traits<wchar_t> >),Microsoft::Console::Render::Renderer *,std::_Ph<1> const &>::operator()+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\functional @ 1531] 
12 (Inline Function) --------`-------- TerminalControl!std::_Invoker_functor::_Call+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\type_traits @ 1457] 
13 (Inline Function) --------`-------- TerminalControl!std::invoke+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\type_traits @ 1457] 
14 (Inline Function) --------`-------- TerminalControl!std::_Invoker_ret<bool,0>::_Call+0x17 [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\type_traits @ 1483] 
15 000000de`62bfe4a0 00007ffd`c1a0ba9c TerminalControl!std::_Func_impl_no_alloc<std::_Binder<std::_Unforced,bool (__cdecl Microsoft::Console::Render::Renderer::*)(std::basic_string_view<wchar_t,std::char_traits<wchar_t> >),Microsoft::Console::Render::Renderer *,std::_Ph<1> const &>,bool,std::basic_string_view<wchar_t,std::char_traits<wchar_t> > >::_Do_call+0x1b [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\functional @ 1007] 
16 (Inline Function) --------`-------- TerminalControl!std::_Func_class<bool,std::basic_string_view<wchar_t,std::char_traits<wchar_t> > >::operator()+0x1d [C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.22.27905\include\functional @ 1049] 
17 000000de`62bfe4e0 00007ffd`c1a0b988 TerminalControl!CodepointWidthDetector::_checkFallbackViaCache+0xec [E:\BA\30\s\src\types\CodepointWidthDetector.cpp @ 148] 
18 000000de`62bfe5c0 00007ffd`c19f868e TerminalControl!CodepointWidthDetector::_lookupIsWide+0x118 [E:\BA\30\s\src\types\CodepointWidthDetector.cpp @ 117] 
19 (Inline Function) --------`-------- TerminalControl!OutputCellView::{ctor}+0x12 [E:\BA\30\s\src\buffer\out\OutputCellView.cpp @ 19] 
1a 000000de`62bfe610 00007ffd`c1a1926b TerminalControl!OutputCellIterator::s_GenerateView+0x17e [E:\BA\30\s\src\buffer\out\OutputCellIterator.cpp @ 412] 
1b (Inline Function) --------`-------- TerminalControl!OutputCellIterator::s_GenerateView+0x56 [E:\BA\30\s\src\buffer\out\OutputCellIterator.cpp @ 387] 
1c (Inline Function) --------`-------- TerminalControl!OutputCellIterator::{ctor}+0x60 [E:\BA\30\s\src\buffer\out\OutputCellIterator.cpp @ 102] 
1d 000000de`62bfe690 00007ffd`c1a1b1d9 TerminalControl!Microsoft::Terminal::Core::Terminal::_WriteBuffer+0x34b [E:\BA\30\s\src\cascadia\TerminalCore\Terminal.cpp @ 374] 
1e 000000de`62bfea80 00007ffd`c1a1c878 TerminalControl!Microsoft::Terminal::Core::Terminal::PrintString+0x9 [E:\BA\30\s\src\cascadia\TerminalCore\TerminalApi.cpp @ 16] 
1f 000000de`62bfeab0 00007ffd`c1a1f063 TerminalControl!TerminalDispatch::PrintString+0x28 [E:\BA\30\s\src\cascadia\TerminalCore\TerminalDispatch.cpp @ 31] 
20 000000de`62bfeaf0 00007ffd`c1a22a8b TerminalControl!Microsoft::Console::VirtualTerminal::OutputStateMachineEngine::ActionPrintString+0x23 [E:\BA\30\s\src\terminal\parser\OutputStateMachineEngine.cpp @ 109] 
21 000000de`62bfeb20 00007ffd`c19e75be TerminalControl!Microsoft::Console::VirtualTerminal::StateMachine::ProcessString+0xeb [E:\BA\30\s\src\terminal\parser\stateMachine.cpp @ 1373] 
22 (Inline Function) --------`-------- TerminalControl!Microsoft::Terminal::Core::Terminal::Write+0x2c [E:\BA\30\s\src\cascadia\TerminalCore\Terminal.cpp @ 188] 
23 (Inline Function) --------`-------- TerminalControl!winrt::Microsoft::Terminal::TerminalControl::implementation::TermControl::_InitializeTerminal::__l2::<lambda_b88b9f699081dc558b4b31a208759546>::operator()+0x5d [E:\BA\30\s\src\cascadia\TerminalControl\TermControl.cpp @ 435] 
24 000000de`62bfeb60 00007ffd`c458e819 TerminalControl!winrt::impl::delegate<winrt::Microsoft::Terminal::TerminalConnection::TerminalOutputEventArgs,<lambda_b88b9f699081dc558b4b31a208759546> >::Invoke+0xbe [E:\BA\30\s\src\cascadia\TerminalControl\Generated Files\winrt\Microsoft.Terminal.TerminalConnection.h @ 90] 
25 (Inline Function) --------`-------- TerminalConnection!winrt::Microsoft::Terminal::TerminalConnection::TerminalOutputEventArgs::operator()+0xc [E:\BA\30\s\src\cascadia\TerminalConnection\Generated Files\winrt\Microsoft.Terminal.TerminalConnection.h @ 247] 
26 000000de`62bfebe0 00007ffd`c458876b TerminalConnection!winrt::impl::invoke<winrt::Microsoft::Terminal::TerminalConnection::TerminalOutputEventArgs,winrt::hstring>+0x19 [E:\BA\30\s\src\cascadia\TerminalConnection\Generated Files\winrt\base.h @ 4901] 
27 000000de`62bfec20 00007ffd`c45a13da TerminalConnection!winrt::event<winrt::Microsoft::Terminal::TerminalConnection::TerminalOutputEventArgs>::operator()<winrt::hstring>+0x9b [E:\BA\30\s\src\cascadia\TerminalConnection\Generated Files\winrt\base.h @ 5033] 
28 000000de`62bfec70 00007ffd`f6ed7bd4 TerminalConnection!winrt::Microsoft::Terminal::TerminalConnection::implementation::ConhostConnection::_OutputThread+0x16a [E:\BA\30\s\src\cascadia\TerminalConnection\ConhostConnection.cpp @ 218] 

This looks like a UAF of probably a dessicated husk of a CodepointWidthDetector. _We should probably not be constructing and destroying those things lightly,_ but we should almost certainly not be mistreating them like this.

All of the CABs @0xabu provided lead to the same sad end.

Thanks!

Oh jeez, it's because we have a singleton codepoint width detector and we bind its width detector fallback to an instance of a single terminal control's renderer.

This also means that the answer for glyph widths in one tab will change based on the font in the most recently created tab.

Assigning Dustin because we talked about this briefly in the hallway and I want to remember to not pick it up out from under what his idea is here.

:tada:This issue was addressed in #2928, which has now been successfully released as Windows Terminal Preview v0.6.2951.0.:tada:

Handy links:

Was this page helpful?
0 / 5 - 0 ratings