https://bugs.documentfoundation.org/show_bug.cgi?id=174008
Bug ID: 174008
Summary: CRASH: free(): invalid pointer when a remote UNO
client repeatedly enumerates shape text paragraphs
(URP release races with SvxUnoTextContentEnumeration)
Product: LibreOffice
Version: 25.2.3.2 release
Hardware: All
OS: Linux (All)
Status: UNCONFIRMED
Severity: normal
Priority: medium
Component: LibreOffice
Assignee: [email protected]
Reporter: [email protected]
Description:
A Python UNO client connected over a pipe/socket URP bridge that repeatedly
enumerates the paragraphs of a shape's text crashes soffice with "free():
invalid pointer" (SIGABRT) within seconds.
I noticed this behavior during my development of a automated
presentation-creation tool, especially when creating large presentations.
Steps to Reproduce:
1. Run the attached mre_textrange_race.py:
python3 mre_textrange_race.py --soffice /path/to/soffice --seconds 120
--shapes 1 --paras 20 --para-loop
It starts a headless soffice, creates one Impress text shape with 20
paragraphs and loops:
e = shape.createEnumeration(); paras = [all elements]; del e, paras
shape.createEnumeration()
Actual Results:
soffice aborts after <= 2 s (8/8 runs, both Debian 25.2.3 and a vanilla
25.2.3.2 build).
Expected Results:
No crash.
Reproducible: Always
User Profile Reset: Yes
Additional Info:
Backtrace (25.2.3, symbols via debuginfod):
free(): invalid pointer
cppu::OWeakAggObject::release cppuhelper/source/weak.cxx:296
SvxUnoTextContent::release
editeng/source/uno/unotext2.cxx:179
~vector<rtl::Reference<SvxUnoTextContent>>
SvxUnoTextContentEnumeration::~...
editeng/source/uno/unotext2.cxx:93
freeUnoInterfaceProxy / s_stub_defenv_revokeInterface
binaryurp::Bridge::releaseStub binaryurp/source/bridge.cxx:512
binaryurp::IncomingRequest::execute (cppu_threadpool thread)
Analysis:
- binaryurp executes release messages on a dedicated thread id ("releasehack",
Bridge::makeReleaseCall), i.e. concurrently with synchronous calls and without
the SolarMutex.
- ~SvxUnoTextRangeBase calls SvxTextEditSourceImpl::removeRange() (std::erase
on the shared mvTextRanges vector) without the SolarMutex, while addRange() and
the enumeration ctors walking getRanges() run with it. Measured with a gdb
breakpoint during a real workload: 34,496 add/removeRange calls with the
SolarMutex held vs. 12,524 without, all of the latter from releaseStub.
- SvxUnoTextContentEnumeration / SvxUnoTextRangeEnumeration ctors reuse objects
from that list by raw pointer. An object whose refcount already hit 0 (its
release() is deleting it) is resurrected via rtl::Reference and deleted a
second time later -> double free.
Proposed fix: <GERRIT-LINK>
(SolarMutexGuard in ~SvxUnoTextRangeBase; reuse only objects that are still
alive, using the increment-and-check technique of
cppu::OWeakConnectionPoint::queryAdapted; DBG_TESTSOLARMUTEX in
add/removeRange.)
Tested on 25.2.3.2: 8/8 reproducer runs survive 120 s (~2,680 rounds each); a
real-world deck-building workload had 0/13 crashes vs. 3/12 without the patch.
The patch applies cleanly to master 91f5f11cb226 (the affected code is
unchanged there), but I have only built it on 25.2.3.
tdf#155262 shows the same "free(): corrupted ..." symptom in server mode and
may have the same cause.
--
You are receiving this mail because:
You are the assignee for the bug.