sw/source/core/layout/pagechg.cxx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
New commits: commit 6430fd9034c8d52d953a7fd61c439c27c0ce3cc7 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed Jun 8 11:51:21 2022 +0200 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Thu Jun 9 20:45:15 2022 +0200 sw: fix use-after-free in SwFrame::ImplFindPageFrame() Header-footer controls have a non-owning pointer to their page frames in Writer views, so whenever a page frame gets deleted, we need to manually make sure that the header-footer control doesn't have a pointer to the deleted page frame. This already works with a single view, but in case one view has a visible header-footer control and an other view deletes the page frame that is known to the header-footer control, then we have a problem. Fix the problematic outdated SwFrameMenuButtonBase::m_pFrame by extending SwPageFrame::DestroyImpl(), so it un-registers itself (before deletion) not only from the current view, but from all views. Found by online.git's: tst=/tmp/testfoo.odt cp test/data/hello-world.odt $tst ./coolstress wss://localhost:9980 $tst test/traces/writer-hello-shape.txt $tst test/traces/writer-document-edit.txt $tst test/traces/writer-mash-text-table.txt $tst test/traces/writer-rambling-text-table.txt $tst test/traces/writer-add-bullet.txt although also reproducible on the desktop, in case you have two views (windows), do cltr-enter to have 2 pages, go to the 2nd page in both views, view 1 clicks on the 2nd page's header, view 2 deletes the page (backspace) and finally view 1 clicks in the body text of the current page. Change-Id: I35e5d82256ab5db8e5f0ba198f5d2638cbff7d3c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135489 Reviewed-by: Michael Meeks <michael.me...@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> (cherry picked from commit 8d1627ff8aeb0eb128d93d9bf8c1d9b373edbf4a) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135503 Tested-by: Andras Timar <andras.ti...@collabora.com> diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx index 7b885474f135..20423f85b19d 100644 --- a/sw/source/core/layout/pagechg.cxx +++ b/sw/source/core/layout/pagechg.cxx @@ -255,13 +255,19 @@ SwPageFrame::SwPageFrame( SwFrameFormat *pFormat, SwFrame* pSib, SwPageDesc *pPg void SwPageFrame::DestroyImpl() { - // Cleanup the header-footer controls in the SwEditWin + // Cleanup the header-footer controls in all SwEditWins SwViewShell* pSh = getRootFrame()->GetCurrShell(); - SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( pSh ); - if ( pWrtSh ) + if (pSh) { - SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin(); - rEditWin.GetFrameControlsManager( ).RemoveControls( this ); + for (SwViewShell& rSh : pSh->GetRingContainer()) + { + SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( &rSh ); + if ( pWrtSh ) + { + SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin(); + rEditWin.GetFrameControlsManager( ).RemoveControls( this ); + } + } } // empty FlyContainer, deletion of the Flys is done by the anchor (in base class SwFrame)