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.

Reply via email to