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");
