sfx2/source/doc/objserv.cxx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
New commits: commit a828e6adbb334282b8405a42f20826f5924c58a2 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed Nov 9 16:13:52 2022 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Nov 9 17:25:43 2022 +0100 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 <vmik...@collabora.com> 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);