Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Buffer overflow in VST3 plugin #431

Open
keinstein opened this issue Feb 13, 2022 · 2 comments
Open

Buffer overflow in VST3 plugin #431

keinstein opened this issue Feb 13, 2022 · 2 comments

Comments

@keinstein
Copy link

Trying to find the problem reported by @KottV in PR #400 I came accross a strange buffer overflow:
The commit is
damiensellier@8a804c8

I ran the VST3 plugin in the AudioPluginHost from JUCE in the same repository

==16992==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6040006b9640 at pc 0x7fffc3b32fec bp 0x7fffffffc5d0 sp 0x7fffffffc5c8
WRITE of size 1 at 0x6040006b9640 thread T0
    #0 0x7fffc3b32feb in juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>::generate(juce::Font const&, int) (/nomirror/tobias/build/ctrlr/ctrlr/Builds/LinuxMakefile/build/Ctrlr-Debug.vst3/Contents/x86_64-linux/Ctrlr-Debug.so+0x367bfeb)
    #1 0x7fffc3b2142e in juce::RenderingHelpers::GlyphCache<juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>, juce::RenderingHelpers::SoftwareRendererSavedState>::findOrCreateGlyph(juce::Font const&, int) (/nomirror/tobias/build/ctrlr/ctrlr/Builds/LinuxMakefile/build/Ctrlr-Debug.vst3/Contents/x86_64-linux/Ctrlr-Debug.so+0x366a42e)
    #2 0x7fffc3b07195 in juce::RenderingHelpers::GlyphCache<juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>, juce::RenderingHelpers::SoftwareRendererSavedState>::drawGlyph(juce::RenderingHelpers::SoftwareRendererSavedState&, juce::Font const&, int, juce::Point<float>) (/nomirror/tobias/build/ctrlr/ctrlr/Builds/LinuxMakefile/build/Ctrlr-Debug.vst3/Contents/x86_64-linux/Ctrlr-Debug.so+0x3650195)
    #3 0x7fffc3aedd7a in juce::RenderingHelpers::SoftwareRendererSavedState::drawGlyph(int, juce::AffineTransform const&) (/nomirror/tobias/build/ctrlr/ctrlr/Builds/LinuxMakefile/build/Ctrlr-Debug.vst3/Contents/x86_64-linux/Ctrlr-Debug.so+0x3636d7a)
    #4 0x7fffc3b612d8 in juce::RenderingHelpers::StackBasedLowLevelGraphicsContext<juce::RenderingHelpers::SoftwareRendererSavedState>::drawGlyph(int, juce::AffineTransform const&) (/nomirror/tobias/build/ctrlr/ctrlr/Builds/LinuxMakefile/build/Ctrlr-Debug.vst3/Contents/x86_64-linux/Ctrlr-Debug.so+0x36aa2d8)
    #5 0x7fffc3adbf4b in juce::GlyphArrangement::draw(juce::Graphics const&, juce::AffineTransform) const ../../JUCE/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp:733
    #6 0x7fffc3adb94f in juce::GlyphArrangement::draw(juce::Graphics const&) const ../../JUCE/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp:702
    #7 0x7fffc39c2427 in juce::Graphics::drawFittedText(juce::String const&, juce::Rectangle<int>, juce::Justification, int, float) const ../../JUCE/modules/juce_graphics/contexts/juce_GraphicsContext.cpp:332
    #8 0x7fffc39c25a9 in juce::Graphics::drawFittedText(juce::String const&, int, int, int, int, juce::Justification, int, float) const ../../JUCE/modules/juce_graphics/contexts/juce_GraphicsContext.cpp:341
    #9 0x7fffc3c9569a in juce::LookAndFeel_V4::drawMenuBarItem(juce::Graphics&, int, int, int, juce::String const&, bool, bool, bool, juce::MenuBarComponent&) ../../JUCE/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V4.cpp:907
    #10 0x7fffc3ca491b in juce::MenuBarComponent::paint(juce::Graphics&) ../../JUCE/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp:90
    #11 0x7fffc3be0f65 in juce::Component::paintComponentAndChildren(juce::Graphics&) ../../JUCE/modules/juce_gui_basics/components/juce_Component.cpp:1932
    #12 0x7fffc3be1ffa in juce::Component::paintEntireComponent(juce::Graphics&, bool) ../../JUCE/modules/juce_gui_basics/components/juce_Component.cpp:2029
    #13 0x7fffc3be0b87 in juce::Component::paintWithinParentContext(juce::Graphics&) ../../JUCE/modules/juce_gui_basics/components/juce_Component.cpp:1916
    #14 0x7fffc3be1423 in juce::Component::paintComponentAndChildren(juce::Graphics&) ../../JUCE/modules/juce_gui_basics/components/juce_Component.cpp:1974
    #15 0x7fffc3be1ffa in juce::Component::paintEntireComponent(juce::Graphics&, bool) ../../JUCE/modules/juce_gui_basics/components/juce_Component.cpp:2029
    #16 0x7fffc3be0b87 in juce::Component::paintWithinParentContext(juce::Graphics&) ../../JUCE/modules/juce_gui_basics/components/juce_Component.cpp:1916
    #17 0x7fffc3be1423 in juce::Component::paintComponentAndChildren(juce::Graphics&) ../../JUCE/modules/juce_gui_basics/components/juce_Component.cpp:1974
    #18 0x7fffc3be1ffa in juce::Component::paintEntireComponent(juce::Graphics&, bool) ../../JUCE/modules/juce_gui_basics/components/juce_Component.cpp:2029
    #19 0x7fffc3d12e54 in juce::ComponentPeer::handlePaint(juce::LowLevelGraphicsContext&) ../../JUCE/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp:132
    #20 0x7fffc3e256e1 in juce::LinuxComponentPeer::LinuxRepaintManager::performAnyPendingRepaintsNow() ../../JUCE/modules/juce_gui_basics/native/juce_linux_Windowing.cpp:421
    #21 0x7fffc3e24b60 in juce::LinuxComponentPeer::LinuxRepaintManager::timerCallback() ../../JUCE/modules/juce_gui_basics/native/juce_linux_Windowing.cpp:368
    #22 0x7fffc395e5c1 in juce::Timer::TimerThread::callTimers() ../../JUCE/modules/juce_events/timers/juce_Timer.cpp:114
    #23 0x7fffc395e8b8 in juce::Timer::TimerThread::CallTimersMessage::messageCallback() ../../JUCE/modules/juce_events/timers/juce_Timer.cpp:180
    #24 0x7fffc396257a in juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}::operator()(int) const ../../JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:43
    #25 0x7fffc3986905 in void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/11/bits/invoke.h:61
    #26 0x7fffc398081c in std::enable_if<std::__and_<std::is_void<void>, std::__is_invocable<juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int> >::value, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/11/bits/invoke.h:154
    #27 0x7fffc3975c69 in std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) /usr/include/c++/11/bits/std_function.h:290
    #28 0x7fffc3389dc9 in std::function<void (int)>::operator()(int) const /usr/include/c++/11/bits/std_function.h:590
    #29 0x7fffc336922f in juce::JuceVST3EditController::JuceVST3Editor::onFDIsSet(int) (/nomirror/tobias/build/ctrlr/ctrlr/Builds/LinuxMakefile/build/Ctrlr-Debug.vst3/Contents/x86_64-linux/Ctrlr-Debug.so+0x2eb222f)
    #30 0x555555b05a49 in juce::VST3PluginWindow::RunLoop::registerEventHandler(Steinberg::Linux::IEventHandler*, int)::{lambda(int)#1}::operator()(int) const ../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp:1198
    #31 0x555555ba5306 in bool std::__invoke_impl<bool, juce::VST3PluginWindow::RunLoop::registerEventHandler(Steinberg::Linux::IEventHandler*, int)::{lambda(int)#1}&, int>(std::__invoke_other, juce::VST3PluginWindow::RunLoop::registerEventHandler(Steinberg::Linux::IEventHandler*, int)::{lambda(int)#1}&, int&&) /usr/include/c++/11/bits/invoke.h:61
    #32 0x555555ba5343 in std::enable_if<std::__and_<std::is_void<void>, std::__is_invocable<juce::VST3PluginWindow::RunLoop::registerEventHandler(Steinberg::Linux::IEventHandler*, int)::{lambda(int)#1}&, int> >::value, void>::type std::__invoke_r<void, juce::VST3PluginWindow::RunLoop::registerEventHandler(Steinberg::Linux::IEventHandler*, int)::{lambda(int)#1}&, int>(juce::VST3PluginWindow::RunLoop::registerEventHandler(Steinberg::Linux::IEventHandler*, int)::{lambda(int)#1}&, int&&) /usr/include/c++/11/bits/invoke.h:154
    #33 0x555555b73a1b in std::_Function_handler<void (int), juce::VST3PluginWindow::RunLoop::registerEventHandler(Steinberg::Linux::IEventHandler*, int)::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) (/nomirror/tobias/build/ctrlr/ctrlr/JUCE/extras/AudioPluginHost/Builds/LinuxMakefile/build/AudioPluginHost+0x61fa1b)
    #34 0x555555f13d8e in std::function<void (int)>::operator()(int) const /usr/include/c++/11/bits/std_function.h:590
    #35 0x555555f09e9e in juce::InternalRunLoop::dispatchPendingEvents() ../../../../modules/juce_events/native/juce_linux_Messaging.cpp:186
    #36 0x555555efd97e in juce::MessageManager::dispatchNextMessageOnSystemQueue(bool) ../../../../modules/juce_events/native/juce_linux_Messaging.cpp:300
    #37 0x555555ef3160 in juce::MessageManager::runDispatchLoop() ../../../../modules/juce_events/messages/juce_MessageManager.cpp:128
    #38 0x555555ef1d8e in juce::JUCEApplicationBase::main() ../../../../modules/juce_events/messages/juce_ApplicationBase.cpp:263
    #39 0x555555ef1bd9 in juce::JUCEApplicationBase::main(int, char const**) ../../../../modules/juce_events/messages/juce_ApplicationBase.cpp:241
    #40 0x55555587457e in main ../../Source/HostStartup.cpp:278
    #41 0x7ffff6d767ec in __libc_start_main ../csu/libc-start.c:332
    #42 0x555555717049 in _start (/nomirror/tobias/build/ctrlr/ctrlr/JUCE/extras/AudioPluginHost/Builds/LinuxMakefile/build/AudioPluginHost+0x1c3049)

0x6040006b9640 is located 0 bytes to the right of 48-byte region [0x6040006b9610,0x6040006b9640)
allocated by thread T0 here:
    #0 0x7ffff7655f97 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:99
    #1 0x7fffc9aaf326 in juce::RenderingHelpers::GlyphCache<juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>, juce::RenderingHelpers::SoftwareRendererSavedState>::addNewGlyphSlots(int) ../../JUCE/modules/juce_graphics/native/juce_RenderingHelpers.h:239
    #2 0x7fffc9aaf326 in juce::RenderingHelpers::GlyphCache<juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>, juce::RenderingHelpers::SoftwareRendererSavedState>::reset() ../../JUCE/modules/juce_graphics/native/juce_RenderingHelpers.h:171
    #3 0x7fffc9aaf326 in juce::RenderingHelpers::GlyphCache<juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>, juce::RenderingHelpers::SoftwareRendererSavedState>::GlyphCache() ../../JUCE/modules/juce_graphics/native/juce_RenderingHelpers.h:148
    #4 0x7fffc9aaf326 in juce::RenderingHelpers::GlyphCache<juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>, juce::RenderingHelpers::SoftwareRendererSavedState>::getInstance() ../../JUCE/modules/juce_graphics/native/juce_RenderingHelpers.h:146
    #5 0x7fffc9aaf326 in juce::RenderingHelpers::SoftwareRendererSavedState::drawGlyph(int, juce::AffineTransform const&) ../../JUCE/modules/juce_graphics/native/juce_RenderingHelpers.h:2541
    #6 0x7fffc9aaf326 in juce::RenderingHelpers::StackBasedLowLevelGraphicsContext<juce::RenderingHelpers::SoftwareRendererSavedState>::drawGlyph(int, juce::AffineTransform const&) ../../JUCE/modules/juce_graphics/native/juce_RenderingHelpers.h:2725
    #7 0x7fffc9a942b9 in juce::GlyphArrangement::draw(juce::Graphics const&, juce::AffineTransform) const ../../JUCE/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp:733
    #8 0x7fffc9a94332 in juce::GlyphArrangement::draw(juce::Graphics const&) const ../../JUCE/modules/juce_graphics/fonts/juce_GlyphArrangement.cpp:702
    #9 0x7fffc9a96fe0 in juce::Graphics::drawFittedText(juce::String const&, juce::Rectangle<int>, juce::Justification, int, float) const ../../JUCE/modules/juce_graphics/contexts/juce_GraphicsContext.cpp:332
    #10 0x7fffc9b8e025 in juce::MenuBarComponent::paint(juce::Graphics&) ../../JUCE/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp:90
    #11 0x7fffc9afe386 in juce::Component::paintComponentAndChildren(juce::Graphics&) ../../JUCE/modules/juce_gui_basics/components/juce_Component.cpp:1932
    #12 0x7fffc9afe580 in juce::Component::paintComponentAndChildren(juce::Graphics&) ../../JUCE/modules/juce_gui_basics/components/juce_Component.cpp:1974
    #13 0x7fffc9afe580 in juce::Component::paintComponentAndChildren(juce::Graphics&) ../../JUCE/modules/juce_gui_basics/components/juce_Component.cpp:1974
    #14 0x7fffc9b338f7 in juce::ComponentPeer::handlePaint(juce::LowLevelGraphicsContext&) ../../JUCE/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp:132
    #15 0x7fffc9c023e3 in juce::LinuxComponentPeer::LinuxRepaintManager::performAnyPendingRepaintsNow() ../../JUCE/modules/juce_gui_basics/native/juce_linux_Windowing.cpp:421
    #16 0x7fffc9a210c1 in juce::Timer::TimerThread::callTimers() ../../JUCE/modules/juce_events/timers/juce_Timer.cpp:114
    #17 0x7fffc9a210c1 in juce::Timer::TimerThread::CallTimersMessage::messageCallback() ../../JUCE/modules/juce_events/timers/juce_Timer.cpp:180
    #18 0x7fffc9a20e39 in juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}::operator()(int) const ../../JUCE/modules/juce_events/native/juce_linux_Messaging.cpp:43
    #19 0x7fffc9a20e39 in void std::__invoke_impl<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(std::__invoke_other, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/11/bits/invoke.h:61
    #20 0x7fffc9a20e39 in std::enable_if<std::__and_<std::is_void<void>, std::__is_invocable<juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int> >::value, void>::type std::__invoke_r<void, juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int>(juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}&, int&&) /usr/include/c++/11/bits/invoke.h:154
    #21 0x7fffc9a20e39 in std::_Function_handler<void (int), juce::InternalMessageQueue::InternalMessageQueue()::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) /usr/include/c++/11/bits/std_function.h:290
    #22 0x7fffc98b6654 in non-virtual thunk to juce::JuceVST3EditController::JuceVST3Editor::onFDIsSet(int) (/nomirror/tobias/build/ctrlr/ctrlr/Builds/LinuxMakefile/build/Ctrlr.vst3/Contents/x86_64-linux/Ctrlr.so+0xd60654)
    #23 0x555555b05a49 in juce::VST3PluginWindow::RunLoop::registerEventHandler(Steinberg::Linux::IEventHandler*, int)::{lambda(int)#1}::operator()(int) const ../../../../modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp:1198
    #24 0x555555ba5306 in bool std::__invoke_impl<bool, juce::VST3PluginWindow::RunLoop::registerEventHandler(Steinberg::Linux::IEventHandler*, int)::{lambda(int)#1}&, int>(std::__invoke_other, juce::VST3PluginWindow::RunLoop::registerEventHandler(Steinberg::Linux::IEventHandler*, int)::{lambda(int)#1}&, int&&) /usr/include/c++/11/bits/invoke.h:61
    #25 0x555555ba5343 in std::enable_if<std::__and_<std::is_void<void>, std::__is_invocable<juce::VST3PluginWindow::RunLoop::registerEventHandler(Steinberg::Linux::IEventHandler*, int)::{lambda(int)#1}&, int> >::value, void>::type std::__invoke_r<void, juce::VST3PluginWindow::RunLoop::registerEventHandler(Steinberg::Linux::IEventHandler*, int)::{lambda(int)#1}&, int>(juce::VST3PluginWindow::RunLoop::registerEventHandler(Steinberg::Linux::IEventHandler*, int)::{lambda(int)#1}&, int&&) /usr/include/c++/11/bits/invoke.h:154
    #26 0x555555b73a1b in std::_Function_handler<void (int), juce::VST3PluginWindow::RunLoop::registerEventHandler(Steinberg::Linux::IEventHandler*, int)::{lambda(int)#1}>::_M_invoke(std::_Any_data const&, int&&) (/nomirror/tobias/build/ctrlr/ctrlr/JUCE/extras/AudioPluginHost/Builds/LinuxMakefile/build/AudioPluginHost+0x61fa1b)
    #27 0x555555f13d8e in std::function<void (int)>::operator()(int) const /usr/include/c++/11/bits/std_function.h:590
    #28 0x555555f09e9e in juce::InternalRunLoop::dispatchPendingEvents() ../../../../modules/juce_events/native/juce_linux_Messaging.cpp:186
    #29 0x555555efd97e in juce::MessageManager::dispatchNextMessageOnSystemQueue(bool) ../../../../modules/juce_events/native/juce_linux_Messaging.cpp:300
    #30 0x555555ef3160 in juce::MessageManager::runDispatchLoop() ../../../../modules/juce_events/messages/juce_MessageManager.cpp:128
    #31 0x555555ef1d8e in juce::JUCEApplicationBase::main() ../../../../modules/juce_events/messages/juce_ApplicationBase.cpp:263
    #32 0x555555ef1bd9 in juce::JUCEApplicationBase::main(int, char const**) ../../../../modules/juce_events/messages/juce_ApplicationBase.cpp:241
    #33 0x55555587457e in main ../../Source/HostStartup.cpp:278
    #34 0x7ffff6d767ec in __libc_start_main ../csu/libc-start.c:332

SUMMARY: AddressSanitizer: heap-buffer-overflow (/nomirror/tobias/build/ctrlr/ctrlr/Builds/LinuxMakefile/build/Ctrlr-Debug.vst3/Contents/x86_64-linux/Ctrlr-Debug.so+0x367bfeb) in juce::RenderingHelpers::CachedGlyphEdgeTable<juce::RenderingHelpers::SoftwareRendererSavedState>::generate(juce::Font const&, int)
Shadow bytes around the buggy address:
  0x0c08800cf270: fa fa 00 00 00 00 00 00 fa fa fd fd fd fd fd fa
  0x0c08800cf280: fa fa fd fd fd fd fd fa fa fa 00 00 00 00 00 00
  0x0c08800cf290: fa fa fd fd fd fd fd fa fa fa 00 00 00 00 00 00
  0x0c08800cf2a0: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 00
  0x0c08800cf2b0: fa fa fd fd fd fd fd fa fa fa 00 00 00 00 00 00
=>0x0c08800cf2c0: fa fa 00 00 00 00 00 00[fa]fa fd fd fd fd fd fa
  0x0c08800cf2d0: fa fa 00 00 00 00 00 fa fa fa fd fd fd fd fd fa
  0x0c08800cf2e0: fa fa fd fd fd fd fd fa fa fa 00 00 00 00 00 fa
  0x0c08800cf2f0: fa fa fd fd fd fd fd fa fa fa 00 00 00 00 00 00
  0x0c08800cf300: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c08800cf310: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd 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
  Shadow gap:              cc
==16992==ABORTING
@keinstein
Copy link
Author

This could be caused in a similar way as in #433. There an unconditional cast causes an access beyond the bounds of the object. Note that both static_cast and dynamic_cast are conditional casts: In case of failure static_cast aborts the compilation and dynamic casts provokes a null pointer dereference. Both take the best available measures to ensure predictable behaviour of the program.

@keinstein
Copy link
Author

after grepping for '([a-zA-Z0-9_]*\s*\*)' the Ctrlr souce code contains very few unconditional casts (most to uint8* or void*). So it's probably a different cause

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant