diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2022-11-09 16:13:52 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2022-11-09 17:25:43 +0100 |
commit | a828e6adbb334282b8405a42f20826f5924c58a2 (patch) | |
tree | 16f9bd731c5abd2a68667fe3dbdb782d4062f861 /sfx2 | |
parent | 56db6406b0b63a2d2d99024e7c311ebd874f3893 (diff) |
sfx2: fix user-after-free in SfxObjectShell::ExecFile_Impl()
This happened even with an empty Writer document, on File -> Export As
-> Export Directly as PDF, since commit
1e007e8f1703851b01c68884e87c906f6bae5a5e (sw: fix merge mail to direct
export as pdf, 2022-10-18).
The problem is that SfxObjectShell::ExecFile_Impl() gets a SfxBoolItem*
returned by GetSlotState(), and then uses it before and after calling
SfxStoringHelper::GUIStoreModel(). But as part of opening the file
picker for save, ModelData_Impl::OutputFileDialog() indirectly calls
Dialog::Execute(), which starts to process user events on the main loop,
which leads to SfxItemDisruptor_Impl::Delete(), which deletes that
SfxBoolItem*.
Fix the problem by storing the bool value on the stack in
SfxObjectShell::ExecFile_Impl(), and work with that after our
SfxBoolItem* is gone.
The "freed by" backtrace from asan is cut quite early in the gtk3 case.
The "gen" case is more helpful, though it's still cut at frame 29.
Change-Id: Ib97c7df7c1289730dec478eede3d620f3a33ace8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142492
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'sfx2')
-rw-r--r-- | sfx2/source/doc/objserv.cxx | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/sfx2/source/doc/objserv.cxx b/sfx2/source/doc/objserv.cxx index 91493e2eb616..ed8c0bf81a5a 100644 --- a/sfx2/source/doc/objserv.cxx +++ b/sfx2/source/doc/objserv.cxx @@ -969,7 +969,10 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) const SfxBoolItem *pItem = nId != SID_DIRECTEXPORTDOCASPDF ? nullptr : dynamic_cast<const SfxBoolItem*>( GetSlotState(SID_MAIL_PREPAREEXPORT) ); - if (pItem && pItem->GetValue()) + // Fetch value from the pool item early, because GUIStoreModel() can free the pool + // item as part of spinning the main loop if a dialog is opened. + bool bMailPrepareExport = pItem && pItem->GetValue(); + if (bMailPrepareExport) { SfxRequest aRequest(SID_MAIL_PREPAREEXPORT, SfxCallMode::SYNCHRON, GetPool()); aRequest.AppendItem(SfxBoolItem(FN_PARAM_1, true)); @@ -982,7 +985,7 @@ void SfxObjectShell::ExecFile_Impl(SfxRequest &rReq) bPreselectPassword, GetDocumentSignatureState() ); - if (pItem && pItem->GetValue()) + if (bMailPrepareExport) { SfxRequest aRequest(SID_MAIL_EXPORT_FINISHED, SfxCallMode::SYNCHRON, GetPool()); ExecuteSlot(aRequest); |