tools/source/stream/stream.cxx |    4 ++++
 1 file changed, 4 insertions(+)

New commits:
commit fa002b6244207ff2bb92f7e714d56c4e2b103064
Author:     Noel Grandin <[email protected]>
AuthorDate: Sat Feb 21 21:00:32 2026 +0200
Commit:     Noel Grandin <[email protected]>
CommitDate: Wed Feb 25 09:12:11 2026 +0100

    fix asan heap-use-after-free
    
    Seems like recent font/pdf related changes have exposed a latent
    bug(?) in the SvMemoryStream class. Specifically, writing to
    SvMemoryStream using a source pointer that points inside the SvMemoryStream
    data buffer causes trouble when the buffer is re-allocated.
    
    Make SvMemoryStream tolerant of this, although it is a rather
    dodgy use-case.
    
    READ of size 177 at 0x531000155fe7 thread T0
      SvMemoryStream::PutData(void const*, unsigned long) 
/tools/source/stream/stream.cxx:1578:5
      SvStream::WriteBytes(void const*, unsigned long) 
/tools/source/stream/stream.cxx:1195:26
      vcl::filter::PDFDocument::WriteCatalogObject(int, 
vcl::filter::PDFReferenceElement*&) 
/vcl/source/filter/ipdf/pdfdocument.cxx:577:27
    
    freed by thread T0 here:
      in SvMemoryStream::FreeMemory() /tools/source/stream/stream.cxx:1694:9
      in SvMemoryStream::ReAllocateMemory(long) 
/tools/source/stream/stream.cxx:1671:9
      in SvMemoryStream::PutData(void const*, unsigned long) 
/tools/source/stream/stream.cxx:1569:22
      in SvStream::WriteBytes(void const*, unsigned long) 
/tools/source/stream/stream.cxx:1195:26
      in vcl::filter::PDFDocument::WriteCatalogObject(int, 
vcl::filter::PDFReferenceElement*&) 
/vcl/source/filter/ipdf/pdfdocument.cxx:577:27
    
    Change-Id: I2613ed66cec600b7f44e575a56f6a97c0ff3053d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199959
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <[email protected]>

diff --git a/tools/source/stream/stream.cxx b/tools/source/stream/stream.cxx
index 2cb511e9896d..e9775d4b3524 100644
--- a/tools/source/stream/stream.cxx
+++ b/tools/source/stream/stream.cxx
@@ -1546,6 +1546,8 @@ std::size_t SvMemoryStream::PutData( const void* pData, 
std::size_t nCount )
         }
         else
         {
+            const bool bSourceDataIsInsideBuffer = pData >= pBuf && pData <= 
(pBuf + nSize);
+            std::ptrdiff_t const offset = bSourceDataIsInsideBuffer ? 
static_cast<const char*>(pData) - reinterpret_cast<const char*>(pBuf) : 0;
             tools::Long nNewResize;
             if( nSize && nSize > nResize )
                 nNewResize = nSize;
@@ -1572,6 +1574,8 @@ std::size_t SvMemoryStream::PutData( const void* pData, 
std::size_t nCount )
                     SetError( SVSTREAM_WRITE_ERROR );
                 }
             }
+            if (bSourceDataIsInsideBuffer)
+                pData = pBuf + offset;
         }
     }
     assert(pBuf && "Possibly Reallocate failed");

Reply via email to