summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2019-08-26 09:05:05 +0200
committerMiklos Vajna <vmiklos@collabora.com>2019-08-26 09:58:29 +0200
commit9f399fd26fdae602b321296d3f983320385b254d (patch)
treeafaf3fce71a497b6a0b376a2996592f5bc332869
parent1ddb742aed047a745bbcd1787d0f9cfa8f0beda5 (diff)
vcl lok: fix UB when lok notifier is deleted before its window
During online.git's unit-copy-paste test: ==18827==ERROR: AddressSanitizer: heap-use-after-free on address 0x61c0000c88c0 at pc 0x7fcbf515fcac bp 0x7ffe9be7eef0 sp 0x7ffe9be7eee8 READ of size 8 at 0x61c0000c88c0 thread T0 (loolkit) #0 0x7fcbf515fcab in vcl::Window::PixelInvalidate(tools::Rectangle const*) core/vcl/source/window/paint.cxx:1227:20 #1 0x7fcbf515efcb in vcl::Window::LogicInvalidate(tools::Rectangle const*) core/vcl/source/window/paint.cxx:1207:9 #2 0x7fcbf5f6f9f4 in vcl::Window::queue_resize(StateChangedType) core/vcl/source/window/window2.cxx:1351:13 #3 0x7fcbf57e3a4f in DockingWindow::queue_resize(StateChangedType) core/vcl/source/window/dockwin.cxx:1046:18 #4 0x7fcbf5f6ff12 in vcl::(anonymous namespace)::queue_ungrouped_resize(vcl::Window const*) core/vcl/source/window/window2.cxx:1301:22 #5 0x7fcbf5f6e390 in vcl::Window::queue_resize(StateChangedType) core/vcl/source/window/window2.cxx:1320:26 #6 0x7fcbf5f6ff12 in vcl::(anonymous namespace)::queue_ungrouped_resize(vcl::Window const*) core/vcl/source/window/window2.cxx:1301:22 #7 0x7fcbf5f6e390 in vcl::Window::queue_resize(StateChangedType) core/vcl/source/window/window2.cxx:1320:26 #8 0x7fcbf601ebef in vcl::Window::StateChanged(StateChangedType) core/vcl/source/window/window.cxx:1929:13 #9 0x7fcbf601f761 in vcl::Window::CompatStateChanged(StateChangedType) core/vcl/source/window/window.cxx:3719:5 #10 0x7fcbf600d9b6 in vcl::Window::Show(bool, ShowFlags) core/vcl/source/window/window.cxx:2189:9 #11 0x7fcbf50ae584 in vcl::Window::Hide() core/include/vcl/window.hxx:930:50 #12 0x7fcbf5fceb7a in vcl::Window::dispose() core/vcl/source/window/window.cxx:399:5 #13 0x7fcbf629f6fb in Control::dispose() core/vcl/source/control/ctrl.cxx:62:13 #14 0x7fcbf612db90 in Button::dispose() core/vcl/source/control/button.cxx:108:14 #15 0x7fcbf617736d in RadioButton::dispose() core/vcl/source/control/button.cxx:2292:13 #16 0x7fcbf6dd52da in VclReferenceBase::disposeOnce() core/vcl/source/outdev/vclreferencebase.cxx:41:5 #17 0x7fcc1add4fa4 in VclPtr<RadioButton>::disposeAndClear() core/include/vcl/vclptr.hxx:206:19 #18 0x7fcc1adc4b3e in sfx2::sidebar::TabBar::SetDecks(std::__debug::vector<sfx2::sidebar::ResourceManager::DeckContextDescriptor, std::allocator<sfx2::sidebar::ResourceManager::DeckContextDescriptor> > const&) core/sfx2/source/sidebar/TabBar.cxx:116:27 #19 0x7fcc1abb2ebb in sfx2::sidebar::SidebarController::UpdateConfigurations() core/sfx2/source/sidebar/SidebarController.cxx:525:15 #20 0x7fcc1abb0d1e in sfx2::sidebar::SidebarController::notifyContextChangeEvent(com::sun::star::ui::ContextChangeEventObject const&) core/sfx2/source/sidebar/SidebarController.cxx:321:9 #21 0x7fcb4688906e in (anonymous namespace)::ContextChangeEventMultiplexer::BroadcastEventToSingleContainer(com::sun::star::ui::ContextChangeEventObject const&, com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const&) core/framework/source/services/ContextChangeEventMultiplexer.cxx:254:23 #22 0x7fcb46883d44 in (anonymous namespace)::ContextChangeEventMultiplexer::broadcastContextChangeEvent(com::sun::star::ui::ContextChangeEventObject const&, com::sun::star::uno::Reference<com::sun::star::uno::XInterface> const&) core/framework/source/services/ContextChangeEventMultiplexer.cxx:237:5 #23 0x7fcc1ac67170 in sfx2::sidebar::ContextChangeBroadcaster::BroadcastContextChange(com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&, rtl::OUString const&, rtl::OUString const&) core/sfx2/source/sidebar/ContextChangeBroadcaster.cxx:108:23 #24 0x7fcc1ac66021 in sfx2::sidebar::ContextChangeBroadcaster::Activate(com::sun::star::uno::Reference<com::sun::star::frame::XFrame> const&) core/sfx2/source/sidebar/ContextChangeBroadcaster.cxx:53:9 #25 0x7fcc19838064 in SfxShell::BroadcastContextForActivation(bool) core/sfx2/source/control/shell.cxx:713:47 #26 0x7fcc19837b2a in SfxShell::Activate(bool) core/sfx2/source/control/shell.cxx:361:5 #27 0x7fcc19836442 in SfxShell::DoActivate_Impl(SfxViewFrame*, bool) core/sfx2/source/control/shell.cxx:314:5 #28 0x7fcc19647b7e in SfxDispatcher::DoActivate_Impl(bool) core/sfx2/source/control/dispatch.cxx:702:42 #29 0x7fcc1b125692 in SfxViewFrame::DoActivate(bool) core/sfx2/source/view/viewfrm.cxx:1173:20 #30 0x7fcc18ed323d in SfxApplication::SetViewFrame_Impl(SfxViewFrame*) core/sfx2/source/appl/app.cxx:311:21 #31 0x7fcc1b1254f7 in SfxViewFrame::SetViewFrame(SfxViewFrame*) core/sfx2/source/view/viewfrm.cxx:3266:19 #32 0x7fcc1b1412fb in SfxViewFrame::MakeActive_Impl(bool) core/sfx2/source/view/viewfrm.cxx:1877:9 #33 0x7fcc1b06d6f4 in SfxLokHelper::setView(int) core/sfx2/source/view/lokhelper.cxx:85:25 freed by thread T0 (loolkit) here: #0 0x610150 in operator delete(void*) _asan_rtl_:0 #1 0x7fcbb32e2560 in ScTabViewShell::~ScTabViewShell() core/sc/source/ui/view/tabvwsh4.cxx:1709:1 #2 0x7fcc1b121be5 in SfxViewFrame::ReleaseObjectShell_Impl() core/sfx2/source/view/viewfrm.cxx:1116:9 #3 0x7fcc1b13caf9 in SfxViewFrame::~SfxViewFrame() core/sfx2/source/view/viewfrm.cxx:1615:5 #4 0x7fcc1b13e234 in SfxViewFrame::~SfxViewFrame() core/sfx2/source/view/viewfrm.cxx:1609:1 #5 0x7fcc1b125143 in SfxViewFrame::Close() core/sfx2/source/view/viewfrm.cxx:1168:5 #6 0x7fcc1afc6a92 in SfxFrame::DoClose_Impl() core/sfx2/source/view/frame.cxx:159:35 #7 0x7fcc1b0bb60d in SfxBaseController::dispose() core/sfx2/source/view/sfxbasecontroller.cxx:983:28 #8 0x7fcb469d1e9b in (anonymous namespace)::XFrameImpl::setComponent(com::sun::star::uno::Reference<com::sun::star::awt::XWindow> const&, com::sun::star::uno::Reference<com::sun::star::frame::XController> const&) core/framework/source/services/frame.cxx:1492:33 #9 0x7fcb469dd0c0 in (anonymous namespace)::XFrameImpl::close(unsigned char) core/framework/source/services/frame.cxx:1699:12 #10 0x7fcc1b185d84 in SfxViewFrame::Exec_Impl(SfxRequest&) core/sfx2/source/view/viewfrm2.cxx:246:32 #11 0x7fcc1b06c967 in SfxLokHelper::destroyView(int) core/sfx2/source/view/lokhelper.cxx:59:25 #12 0x7fcc2bf0a551 in doc_destroyView(_LibreOfficeKitDocument*, int) core/desktop/source/lib/init.cxx:4473:5 #13 0x980e57 in lok::Document::destroyView(int) core/include/LibreOfficeKit/LibreOfficeKit.hxx:512:9 #14 0x9310e4 in Document::onUnload(ChildSession const&) online/kit/Kit.cpp:1555:29 #15 0x6175e8 in ChildSession::disconnect() online/kit/ChildSession.cpp:98:30 #16 0x616c85 in ChildSession::~ChildSession() online/kit/ChildSession.cpp:85:5 I.e. normally first the vcl::Window is deleted, and only then the view shell, and the lifecycle handled in vcl::Window::ReleaseLOKNotifier(). But at least with DockingWindow, it can happen that the vcl::Window outlives its view shell, so we need to decouple the vcl::Window and its view shell (lok notifier) in both cases, no matter which object is deleted first. Change-Id: I49701817827f8b7545d07a1d74514781551db7e9 Reviewed-on: https://gerrit.libreoffice.org/78105 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
-rw-r--r--include/vcl/IDialogRenderable.hxx2
-rw-r--r--vcl/source/window/window.cxx22
2 files changed, 23 insertions, 1 deletions
diff --git a/include/vcl/IDialogRenderable.hxx b/include/vcl/IDialogRenderable.hxx
index e5596c5fe88f..86ea333d1100 100644
--- a/include/vcl/IDialogRenderable.hxx
+++ b/include/vcl/IDialogRenderable.hxx
@@ -27,7 +27,7 @@ typedef sal_uInt32 LOKWindowId;
class VCL_DLLPUBLIC ILibreOfficeKitNotifier
{
public:
- virtual ~ILibreOfficeKitNotifier() {}
+ virtual ~ILibreOfficeKitNotifier();
/// Callbacks
virtual void notifyWindow(vcl::LOKWindowId nLOKWindowId,
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index d20dccb60481..02e10941d61d 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -3217,6 +3217,28 @@ void Window::ReleaseLOKNotifier()
mpWindowImpl->mnLOKWindowId = 0;
}
+ILibreOfficeKitNotifier::~ILibreOfficeKitNotifier()
+{
+ if (!comphelper::LibreOfficeKit::isActive())
+ {
+ return;
+ }
+
+ for (auto it = GetLOKWindowsMap().begin(); it != GetLOKWindowsMap().end();)
+ {
+ WindowImpl* pWindowImpl = it->second->ImplGetWindowImpl();
+ if (pWindowImpl->mpLOKNotifier == this)
+ {
+ pWindowImpl->mpLOKNotifier = nullptr;
+ pWindowImpl->mnLOKWindowId = 0;
+ it = GetLOKWindowsMap().erase(it);
+ continue;
+ }
+
+ ++it;
+ }
+}
+
const vcl::ILibreOfficeKitNotifier* Window::GetLOKNotifier() const
{
return mpWindowImpl->mpLOKNotifier;