diff options
author | Michael Stahl <mstahl@redhat.com> | 2017-07-04 22:46:15 +0200 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2017-07-06 13:30:00 +0200 |
commit | f1732a9b718e59365fa6160a7a224d7e5cc3ffb8 (patch) | |
tree | 16b46d3ca8fdaa801b74d78b002710036353a73e /sw | |
parent | fd6d6cad96a89f675e650c7494e553047cceb885 (diff) |
sw: fix use-after-free in SwAccessibleMap::FireEvents()
As seen when running JunitTest_sw_unoapi_3 against "make debugrun",
the damn thing can call itself recursively via an odd corner case in
GetContext():
0 in SwAccessibleEventList_Impl::~SwAccessibleEventList_Impl() (this=0x9a6a170, __in_chrg=<optimized out>) at sw/source/core/access/accmap.cxx:498
1 in SwAccessibleMap::FireEvents() (this=0x8198bb0) at sw/source/core/access/accmap.cxx:3023
2 in SwAccessibleMap::InvalidateCursorPosition(com::sun::star::uno::Reference<com::sun::star::accessibility::XAccessible> const&) (this=0x8198bb0, rAcc=uno::Reference to (SwAccessibleParagraph *) 0x9a439d8) at sw/source/core/access/accmap.cxx:1069
3 in SwAccessibleMap::GetContext(SwFrame const*, bool) (this=0x8198bb0, pFrame=0x825ca10, bCreate=true) at sw/source/core/access/accmap.cxx:1925
4 in SwAccessibleMap::GetContextImpl(SwFrame const*, bool) (this=0x8198bb0, pFrame=0x825ca10, bCreate=true) at sw/source/core/access/accmap.cxx:1936
5 in SwAccessibleContext::InvalidateChildPosOrSize(sw::access::SwAccessibleChild const&, SwRect const&) (this=0x405a350, rChildFrameOrObj=..., rOldFrame=SwRect = {...}) at sw/source/core/access/acccontext.cxx:1196
6 in SwAccessibleMap::FireEvent(SwAccessibleEvent_Impl const&) (this=0x8198bb0, rEvent=...) at sw/source/core/access/accmap.cxx:898
7 in SwAccessibleMap::FireEvents() (this=0x8198bb0) at sw/source/core/access/accmap.cxx:3018
8 in SwViewShellImp::FireAccessibleEvents() (this=0x7744dc0) at sw/source/core/view/viewimp.cxx:460
9 in SwLayIdle::SwLayIdle(SwRootFrame*, SwViewShellImp*) (this=0x7ffc63395e30, pRt=0x7745120, pI=0x7744dc0) at sw/source/core/layout/layact.cxx:2267
Presumably all of mpEvents, mpEventMap and mpShapes must live until
the outermost FireEvents() completes.
Change-Id: I4e5a053035bf7fc12d9407913437d721889950ae
(cherry picked from commit ddf8d9a150e3e1725de65577c48d47918b4b11a8)
Reviewed-on: https://gerrit.libreoffice.org/39566
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/access/accmap.cxx | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/sw/source/core/access/accmap.cxx b/sw/source/core/access/accmap.cxx index 895a4bfd9c7e..711e34adccce 100644 --- a/sw/source/core/access/accmap.cxx +++ b/sw/source/core/access/accmap.cxx @@ -3047,6 +3047,11 @@ void SwAccessibleMap::FireEvents() osl::MutexGuard aGuard( maEventMutex ); if( mpEvents ) { + if (mpEvents->IsFiring()) + { + return; // prevent recursive FireEvents() + } + mpEvents->SetFiring(); mpEvents->MoveMissingXAccToEnd(); for( auto const& aEvent : *mpEvents ) |