Version in base suite: 25.2.3-2+deb13u6 Base version: libreoffice_25.2.3-2+deb13u6 Target version: libreoffice_25.2.3-2+deb13u7 Base file: /srv/ftp-master.debian.org/ftp/pool/main/libr/libreoffice/libreoffice_25.2.3-2+deb13u6.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/libr/libreoffice/libreoffice_25.2.3-2+deb13u7.dsc changelog | 14 +++ patches/CVE-2026-63272.diff | 62 ++++++++++++++ patches/CVE-2026-63273.diff | 52 ++++++++++++ patches/CVE-2026-63274.diff | 48 +++++++++++ patches/CVE-2026-63275.diff | 44 ++++++++++ patches/CVE-2026-63276.diff | 188 ++++++++++++++++++++++++++++++++++++++++++++ patches/CVE-2026-63278.diff | 115 ++++++++++++++++++++++++++ patches/CVE-2026-63279.diff | 103 ++++++++++++++++++++++++ patches/series | 7 + 9 files changed, 633 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpdrqw1z11/libreoffice_25.2.3-2+deb13u6.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpdrqw1z11/libreoffice_25.2.3-2+deb13u7.dsc: no acceptable signature found diff -Nru libreoffice-25.2.3/debian/changelog libreoffice-25.2.3/debian/changelog --- libreoffice-25.2.3/debian/changelog 2026-06-06 20:12:08.000000000 +0000 +++ libreoffice-25.2.3/debian/changelog 2026-07-21 16:41:22.000000000 +0000 @@ -1,3 +1,17 @@ +libreoffice (4:25.2.3-2+deb13u7) trixie-security; urgency=medium + + * debian/patches/CVE-2026-62327?.diff: fix + - CVE-2026-63272 WMF DX-array heap OOB (CRFDC4JM) + - CVE-2026-63273 PDF decrypt-key OOB write (J00S1S9Y) + - CVE-2026-63274 PDF /Length stream OOB (QT406EDT) + - CVE-2026-63275 CFF addHints stack OOB (RNHRV8B9) + - CVE-2026-63276 CFF-to-Type1 stack OOB (YA6ADR86) + - CVE-2026-63278 environment / ini-file disclosure + (CVE-2024-12426 bypass) + - CVE-2026-63279 PICT palette-index heap OOB read + + -- Rene Engelhard Tue, 21 Jul 2026 13:41:22 -0300 + libreoffice (4:25.2.3-2+deb13u6) trixie; urgency=medium * debian/patches/check-for-hb_shape_full-failure.diff: add patch from diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63272.diff libreoffice-25.2.3/debian/patches/CVE-2026-63272.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63272.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63272.diff 2026-07-21 16:41:22.000000000 +0000 @@ -0,0 +1,62 @@ +From 835c83a04979d0545a3c3d7d188c8c058d9300ed Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sat, 4 Jul 2026 15:04:46 +0100 +Subject: [PATCH] ofz: ignore an advance array shorter than the string +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Caolán McNamara +Change-Id: I6ceec1ecbae58a714d2f45eb786e01b428e6d942 +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/6114 +Reviewed-by: Noel Grandin +Tested-by: Jenkins CPCI +(cherry picked from commit 6ab602ca281f507f7e637183a49dd514ffb1376b) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207656 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +(cherry picked from commit 4406da79b0715411528c17f93ae7ebcb29b9a0d2) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207677 +(cherry picked from commit acf64b67cceecf3d1acd26033668b6673208bcf2) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207715 +Reviewed-by: Christian Lohmaier +Tested-by: Xisco Fauli +Reviewed-by: Michael Weghorn +--- + emfio/source/reader/wmfreader.cxx | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/emfio/source/reader/wmfreader.cxx b/emfio/source/reader/wmfreader.cxx +index a3acf52a7e96..e490f67d036c 100644 +--- a/emfio/source/reader/wmfreader.cxx ++++ b/emfio/source/reader/wmfreader.cxx +@@ -1274,7 +1274,7 @@ namespace emfio + GetFont().GetFamilyName())) + { + Point aPt; +- sal_uInt32 nStringLen, nDXCount; ++ sal_uInt32 nStringLen(0), nDXCount(0); + KernArray aDXAry; + SvMemoryStream aMemoryStream(nEscLen); + aMemoryStream.WriteBytes(pData.get(), nEscLen); +@@ -1293,6 +1293,8 @@ namespace emfio + OUString aString = read_uInt16s_ToOUString( + aMemoryStream, nStringLen); + aMemoryStream.ReadUInt32(nDXCount); ++ if (nDXCount < o3tl::make_unsigned(aString.getLength())) ++ nDXCount = 0; + if ((static_cast(nDXCount) + * sizeof(sal_Int32)) + >= (nEscLen - aMemoryStream.Tell())) +@@ -1301,7 +1303,7 @@ namespace emfio + aDXAry.resize(nDXCount); + for (sal_uInt32 i = 0; i < nDXCount; i++) + { +- sal_Int32 val; ++ sal_Int32 val(0); + aMemoryStream.ReadInt32(val); + aDXAry[i] = val; + } +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63273.diff libreoffice-25.2.3/debian/patches/CVE-2026-63273.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63273.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63273.diff 2026-07-21 16:41:22.000000000 +0000 @@ -0,0 +1,52 @@ +From acc86d1fd6825feccdb4e609b870d9d8c7462471 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sat, 4 Jul 2026 15:43:32 +0100 +Subject: [PATCH] ofz: pdf, check record againsts max allowed size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Caolán McNamara +Change-Id: I51a31c1e09d2b5d5a413c5345c40998e032f09d6 +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/6117 +Tested-by: Jenkins CPCI +Reviewed-by: Noel Grandin +(cherry picked from commit e230b10b7cd2d5d8623cdba0877ec68f67003690) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207659 +Reviewed-by: Xisco Fauli +Tested-by: Jenkins +(cherry picked from commit 21124741e0134f0f1222a42726c223bf6da41dca) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207674 +(cherry picked from commit 3a92ea5af6d1bf3820ce0909fb9de003565ebf2b) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207684 +Tested-by: Xisco Fauli +Reviewed-by: Michael Weghorn +Reviewed-by: Christian Lohmaier +--- + sdext/source/pdfimport/pdfparse/pdfentries.cxx | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/sdext/source/pdfimport/pdfparse/pdfentries.cxx b/sdext/source/pdfimport/pdfparse/pdfentries.cxx +index cfcb36ecb7ac..317548e6266e 100644 +--- a/sdext/source/pdfimport/pdfparse/pdfentries.cxx ++++ b/sdext/source/pdfimport/pdfparse/pdfentries.cxx +@@ -1352,7 +1352,15 @@ PDFFileImplData* PDFFile::impl_getData() const + { + PDFNumber* pNum = dynamic_cast(len->second); + if( pNum ) +- m_pData->m_nKeyLength = static_cast(pNum->m_fValue) / 8; ++ { ++ sal_uInt32 nKeyLength = static_cast(pNum->m_fValue) / 8; ++ if (nKeyLength > ENCRYPTION_KEY_LEN) ++ { ++ SAL_WARN("sdext.pdfimport.pdfparse", "entry has length " << nKeyLength << " which is greater than " << ENCRYPTION_KEY_LEN); ++ nKeyLength = ENCRYPTION_KEY_LEN; ++ } ++ m_pData->m_nKeyLength = nKeyLength; ++ } + } + PDFName* pFilter = dynamic_cast(filter->second); + if( pFilter && pFilter->getFilteredName() == "Standard" ) +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63274.diff libreoffice-25.2.3/debian/patches/CVE-2026-63274.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63274.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63274.diff 2026-07-21 16:41:22.000000000 +0000 @@ -0,0 +1,48 @@ +From 95e8e6e27db4006f760c3e703278fd0fbc7da163 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sat, 4 Jul 2026 15:00:32 +0000 +Subject: [PATCH] ofz: pdf, clamp stream Length to the bytes actually read +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Caolán McNamara +Change-Id: I155f3eddbd204069084b50f52f7cc6328fb053eb +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/6118 +Tested-by: Jenkins CPCI +Reviewed-by: Noel Grandin +(cherry picked from commit 332e8831e0b0e580dae0d77a0ec27bd267af6b29) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207660 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +(cherry picked from commit 7906b5a8aac335a0155a90fc6f8310a92e558124) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207678 +(cherry picked from commit b4b7fcc1f0551ccdba1ddc520c351eee9bfccd4c) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207777 +Reviewed-by: Christian Lohmaier +Reviewed-by: Michael Weghorn +Tested-by: Xisco Fauli +--- + sdext/source/pdfimport/pdfparse/pdfentries.cxx | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/sdext/source/pdfimport/pdfparse/pdfentries.cxx b/sdext/source/pdfimport/pdfparse/pdfentries.cxx +index 6f781149c3e8..cfcb36ecb7ac 100644 +--- a/sdext/source/pdfimport/pdfparse/pdfentries.cxx ++++ b/sdext/source/pdfimport/pdfparse/pdfentries.cxx +@@ -701,6 +701,12 @@ bool PDFObject::getDeflatedStream( std::unique_ptr& rpStream, unsigned i + pStream++; + // get the compressed length + *pBytes = m_pStream->getDictLength( pObjectContainer ); ++ unsigned int nAvailable = nOuterStreamLen - static_cast(pStream - rpStream.get()); ++ if (*pBytes > nAvailable) ++ { ++ SAL_WARN("sdext.pdfimport.pdfparse", "stream /Length " << *pBytes << " exceeds " << nAvailable << " available bytes"); ++ *pBytes = nAvailable; ++ } + if( pStream != rpStream.get() ) + memmove( rpStream.get(), pStream, *pBytes ); + if( rContext.m_bDecrypt ) +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63275.diff libreoffice-25.2.3/debian/patches/CVE-2026-63275.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63275.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63275.diff 2026-07-21 16:41:22.000000000 +0000 @@ -0,0 +1,44 @@ +From 0051d552d408cdcad943615d9e0ae3b60a5da753 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sat, 4 Jul 2026 15:34:05 +0100 +Subject: [PATCH] ofz: wmf, check record against max allowed size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Caolán McNamara +Change-Id: I3c0a155bdf0922771694fc500a24eb09ec8abc27 +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/6116 +Tested-by: Jenkins CPCI +Reviewed-by: Noel Grandin +(cherry picked from commit 9b412f7cda30a4e1b820e51249fa7b3c36a812d3) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207658 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +(cherry picked from commit 1db305f340787ab7e59d089e51ac9d6fc07c2715) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207675 +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207726 +Reviewed-by: Michael Weghorn +Reviewed-by: Christian Lohmaier +--- + vcl/source/fontsubset/cff.cxx | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/vcl/source/fontsubset/cff.cxx b/vcl/source/fontsubset/cff.cxx +index 710d0fccfd8e..b02643c78497 100644 +--- a/vcl/source/fontsubset/cff.cxx ++++ b/vcl/source/fontsubset/cff.cxx +@@ -888,7 +888,8 @@ void CffSubsetterContext::addHints( bool bVerticalHints) + if( mnStackIdx & 1) --mnStackIdx;//####### + // TODO: if( !bSubr) assert( mnStackIdx >= 2); + +- assert( (mnHintSize + mnStackIdx) <= 2*NMAXHINTS); ++ if (o3tl::make_unsigned(mnHintSize + mnStackIdx) > std::size(mnHintStack)) ++ return; + + ValType nHintOfs = 0; + for( int i = 0; i < mnStackIdx; ++i) { +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63276.diff libreoffice-25.2.3/debian/patches/CVE-2026-63276.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63276.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63276.diff 2026-07-21 16:41:22.000000000 +0000 @@ -0,0 +1,188 @@ +From 5ad3c9cd6573ccc4505d16e4f9d46a2909a15c91 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sun, 5 Jul 2026 20:48:22 +0100 +Subject: [PATCH] ofz: cff, track the charstring output capacity +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Caolán McNamara +Change-Id: I0bd22e737fb9700108d616a1ba4a69f6bd95691d +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/6165 +Tested-by: Jenkins CPCI +Reviewed-by: Miklos Vajna +(cherry picked from commit 0b090eff6ca18e3f2bacc7311b746d2a15ed1247) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207718 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +(cherry picked from commit 49360f34f5caff4eee29489e339def8cf13053cc) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207729 +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207877 +Signed-off-by: Xisco Fauli +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/207913 +Tested-by: Christian Lohmaier +Reviewed-by: Christian Lohmaier +--- + vcl/source/fontsubset/cff.cxx | 63 +++++++++++++++++++++++++++++------ + 1 file changed, 53 insertions(+), 10 deletions(-) + +diff --git a/vcl/source/fontsubset/cff.cxx b/vcl/source/fontsubset/cff.cxx +index 3c62880a8b08..b2597df3749e 100644 +--- a/vcl/source/fontsubset/cff.cxx ++++ b/vcl/source/fontsubset/cff.cxx +@@ -736,7 +736,8 @@ public: + private: + void convertCharStrings(const sal_GlyphId* pGlyphIds, int nGlyphCount, + std::vector& rCharStrings); +- int convert2Type1Ops( CffLocal*, const U8* pType2Ops, int nType2Len, U8* pType1Ops); ++ int convert2Type1Ops(CffLocal*, const U8* pType2Ops, int nType2Len, U8* pType1Ops, ++ size_t nType1Cap); + void convertOneTypeOp(); + void convertOneTypeEsc(); + void callType2Subr( bool bGlobal, int nSubrNumber); +@@ -747,6 +748,11 @@ private: + void callType2Subr( bool bGlobal, int nSubrNumber); + sal_Int32 getReadOfs() const { return static_cast(mpReadPtr - mpBasePtr);} + ++ // Abandon the charstring conversion when the output buffer is full. ++ // callType2Subr does not restore mpWritePtr, so this stays in effect when ++ // the buffer fills inside a subroutine. ++ void abandonConversion() { mpWritePtr = mpWriteEnd + 1; } ++ + const U8* mpBasePtr; + const U8* mpBaseEnd; + +@@ -754,6 +760,8 @@ private: + const U8* mpReadEnd; + + U8* mpWritePtr; ++ U8* mpWriteEnd; ++ int mnSubrDepth; + bool mbNeedClose; + bool mbIgnoreHints; + sal_Int32 mnCntrMask; +@@ -773,6 +781,9 @@ private: + bool getBaseAccent(ValType aBase, ValType aAccent, int* nBase, int* nAccent); + + void read2push(); ++ // True if nBytes more fit in the output buffer; otherwise abandon the ++ // conversion and return false so the caller skips the write. ++ bool hasWriteRoom(int nBytes); + void writeType1Val( ValType); + void writeTypeOp( int nTypeOp); + void writeTypeEsc( int nTypeOp); +@@ -820,6 +831,8 @@ CffSubsetterContext::CffSubsetterContext( const U8* pBasePtr, int nBaseLen) + , mpReadPtr(nullptr) + , mpReadEnd(nullptr) + , mpWritePtr(nullptr) ++ , mpWriteEnd(nullptr) ++ , mnSubrDepth(0) + , mbNeedClose(false) + , mbIgnoreHints(false) + , mnCntrMask(0) +@@ -1047,8 +1060,21 @@ void CffSubsetterContext::read2push() + push( aVal); + } + ++bool CffSubsetterContext::hasWriteRoom(int nBytes) ++{ ++ if (mpWritePtr + nBytes <= mpWriteEnd) ++ return true; ++ abandonConversion(); ++ return false; ++} ++ + void CffSubsetterContext::writeType1Val( ValType aVal) + { ++ // Five bytes for the number, plus five more and a two byte "div" escape ++ // when a fractional value is split. ++ if (!hasWriteRoom(12)) ++ return; ++ + U8* pOut = mpWritePtr; + + // tdf#126242 +@@ -1104,11 +1130,15 @@ void CffSubsetterContext::writeType1Val( ValType aVal) + + inline void CffSubsetterContext::writeTypeOp( int nTypeOp) + { ++ if (!hasWriteRoom(1)) ++ return; + *(mpWritePtr++) = static_cast(nTypeOp); + } + + inline void CffSubsetterContext::writeTypeEsc( int nTypeEsc) + { ++ if (!hasWriteRoom(2)) ++ return; + *(mpWritePtr++) = TYPE1OP::T1ESC; + *(mpWritePtr++) = static_cast(nTypeEsc); + } +@@ -1589,23 +1619,32 @@ void CffSubsetterContext::callType2Subr( bool bGlobal, int nSubrNumber) + seekIndexData( mpCffLocal->mnLocalSubrBase, nSubrNumber); + } + +- while( mpReadPtr < mpReadEnd) ++ // The CFF specification limits subroutine call nesting to 10 levels; ++ // deeper nesting would let cyclic subroutines recurse without bound. ++ if (mnSubrDepth >= 10) ++ return; ++ ++mnSubrDepth; ++ ++ while (mpReadPtr < mpReadEnd && mpWritePtr <= mpWriteEnd) + convertOneTypeOp(); ++ --mnSubrDepth; + + mpReadPtr = pOldReadPtr; + mpReadEnd = pOldReadEnd; + } + +-int CffSubsetterContext::convert2Type1Ops( CffLocal* pCffLocal, const U8* const pT2Ops, int nT2Len, U8* const pT1Ops) ++int CffSubsetterContext::convert2Type1Ops(CffLocal* pCffLocal, const U8* const pT2Ops, int nT2Len, ++ U8* const pT1Ops, size_t nT1Cap) + { + mpCffLocal = pCffLocal; + + // prepare the charstring conversion + mpWritePtr = pT1Ops; +- U8 aType1Ops[ MAX_T1OPS_SIZE]; +- if( !pT1Ops) +- mpWritePtr = aType1Ops; +- *const_cast(&pT1Ops) = mpWritePtr; ++ ++ // Remember where the output buffer ends so the write primitives can tell ++ // how much space is left. Start with no subroutine nesting. ++ mpWriteEnd = mpWritePtr + nT1Cap; ++ mnSubrDepth = 0; + + // prepend random seed for T1crypt + *(mpWritePtr++) = 0x48; +@@ -1632,9 +1671,12 @@ int CffSubsetterContext::convert2Type1Ops( CffLocal* pCffLocal, const U8* const + mbIgnoreHints = false; + mnHintSize=mnHorzHintSize=mnStackIdx=0; maCharWidth=-1;//####### + mnCntrMask = 0; +- while( mpReadPtr < mpReadEnd) ++ while (mpReadPtr < mpReadEnd && mpWritePtr <= mpWriteEnd) + convertOneTypeOp(); +- if( maCharWidth != -1 ) ++ ++ if (mpWritePtr > mpWriteEnd) ++ return -1; ++ if (maCharWidth != -1) + { + // overwrite earlier charWidth value, which we only now have + // parsed out of mpReadPtr buffer (by way of +@@ -2316,7 +2358,8 @@ void CffSubsetterContext::convertCharStrings(const sal_GlyphId* pGlyphIds, int n + assert(nT2Len > 0); + + CharString aCharString; +- const int nT1Len = convert2Type1Ops(mpCffLocal, mpReadPtr, nT2Len, aCharString.aOps); ++ const int nT1Len = convert2Type1Ops(mpCffLocal, mpReadPtr, nT2Len, aCharString.aOps, ++ std::size(aCharString.aOps)); + aCharString.nLen = nT1Len; + aCharString.nCffGlyphId = nCffGlyphId; + +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63278.diff libreoffice-25.2.3/debian/patches/CVE-2026-63278.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63278.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63278.diff 2026-07-21 16:41:22.000000000 +0000 @@ -0,0 +1,115 @@ +From c0b461b50fea19b78dce67e9e5c777cc2e44bceb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Fri, 12 Jun 2026 20:32:27 +0000 +Subject: [PATCH] match the package content provider when checking a + vnd.sun.star.pkg url +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +IsExoticProtocol used GetHost() to recover the nested package url of a +vnd.sun.star.pkg url, but the package content provider in +ucb/source/ucp/package/pkguri.cxx uses the whole authority between "://" +and the next '/', which GetHost() truncates at '@'. Check the same +substring the provider does. + +The vnd.sun.star.zip branch below already did the equivalent extraction, +so pull the shared parts into a helper that both branches call. + +Signed-off-by: Caolán McNamara +Change-Id: I27be6a839108f2e58d62baefc1a71dcbfc9a4568 +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/4410 +Tested-by: Jenkins CPCI +Reviewed-by: Stephan Bergmann +(cherry picked from commit ce436efb34d2e0e90ee2cdb450da285530c562f7) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/206681 +Reviewed-by: Xisco Fauli +Tested-by: Jenkins +(cherry picked from commit 4ba5567cc44be760066c0c45c99949f790cf181a) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/206701 +--- + tools/qa/cppunit/test_urlobj.cxx | 5 +++++ + tools/source/fsys/urlobj.cxx | 37 ++++++++++++++++++++++++++------ + 2 files changed, 35 insertions(+), 7 deletions(-) + +diff --git a/tools/qa/cppunit/test_urlobj.cxx b/tools/qa/cppunit/test_urlobj.cxx +index 31347cf4b576..949b2ac155cb 100644 +--- a/tools/qa/cppunit/test_urlobj.cxx ++++ b/tools/qa/cppunit/test_urlobj.cxx +@@ -370,6 +370,11 @@ namespace tools_urlobj + CPPUNIT_ASSERT_EQUAL(INetProtocol::VndSunStarPkg, url.GetProtocol()); + CPPUNIT_ASSERT(!url.IsExoticProtocol()); + } ++ { ++ INetURLObject url(u"vnd.sun.star.pkg://vnd.sun.star.expand%3Ahttp%3A%2F%2F127.0.0.1%2F%24%7BHOME%7D@example.com/x"); ++ CPPUNIT_ASSERT_EQUAL(INetProtocol::VndSunStarPkg, url.GetProtocol()); ++ CPPUNIT_ASSERT(url.IsExoticProtocol()); ++ } + { + INetURLObject url(u"vnd.sun.star.zip://slot%3A0"); + CPPUNIT_ASSERT_EQUAL(INetProtocol::Generic, url.GetProtocol()); +diff --git a/tools/source/fsys/urlobj.cxx b/tools/source/fsys/urlobj.cxx +index 6dc2dee5ef76..c93dbecf2222 100644 +--- a/tools/source/fsys/urlobj.cxx ++++ b/tools/source/fsys/urlobj.cxx +@@ -4887,6 +4887,25 @@ OUString INetURLObject::CutExtension() + return OUString(); + } + ++namespace { ++ ++// Treat the substring of rURL from nStart up to the next '/' or '?' as a ++// percent-encoded nested url and report whether that nested url is an ++// exotic protocol. ++bool isExoticNestedProtocol(const OUString& rURL, sal_Int32 nStart) ++{ ++ auto const find = [&rURL, nStart](auto c) { ++ auto const n = rURL.indexOf(c, nStart); ++ return n == -1 ? rURL.getLength() : n; ++ }; ++ return INetURLObject( ++ INetURLObject::decode(rURL.subView(nStart, std::min(find('/'), find('?')) - nStart), ++ INetURLObject::DecodeMechanism::WithCharset)) ++ .IsExoticProtocol(); ++} ++ ++} ++ + bool INetURLObject::IsExoticProtocol() const + { + if (m_eScheme == INetProtocol::Slot || +@@ -4914,8 +4933,16 @@ bool INetURLObject::IsExoticProtocol() const + return true; + } + if (m_eScheme == INetProtocol::VndSunStarPkg) { +- return INetURLObject(GetHost(INetURLObject::DecodeMechanism::WithCharset)) +- .IsExoticProtocol(); ++ // The package content provider (ucb/source/ucp/package/pkguri.cxx) ++ // treats the whole authority between "://" and the next '/' as the ++ // nested package url. GetHost() returns only the part after any '@', ++ // so match the provider and check that substring instead. ++ OUString sPayloadURL = GetMainURL(INetURLObject::DecodeMechanism::NONE); ++ sal_Int32 nStart = sPayloadURL.indexOf(u"://"); ++ if (nStart == -1) { ++ return false; ++ } ++ return isExoticNestedProtocol(sPayloadURL, nStart + 3); + } + if (isSchemeEqualTo(u"vnd.sun.star.zip")) + { +@@ -4923,11 +4950,7 @@ bool INetURLObject::IsExoticProtocol() const + if (!sPayloadURL.startsWith(u"//")) { + return false; + } +- auto const find = [&sPayloadURL](auto c) { +- auto const n = sPayloadURL.indexOf(c, 2); +- return n == -1 ? sPayloadURL.getLength() : n; +- }; +- return INetURLObject(decode(sPayloadURL.subView(2, std::min(find('/'), find('?')) - 2), INetURLObject::DecodeMechanism::WithCharset)).IsExoticProtocol(); ++ return isExoticNestedProtocol(sPayloadURL, 2); + } + return false; + } +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/CVE-2026-63279.diff libreoffice-25.2.3/debian/patches/CVE-2026-63279.diff --- libreoffice-25.2.3/debian/patches/CVE-2026-63279.diff 1970-01-01 00:00:00.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/CVE-2026-63279.diff 2026-07-21 16:41:22.000000000 +0000 @@ -0,0 +1,103 @@ +From b59a3e5f8dc8c7e678c5af8bce065b050bede0ee Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= +Date: Sat, 13 Jun 2026 13:27:30 +0000 +Subject: [PATCH] limit palette index +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +use the same SanitizePaletteIndex guard ipsd and iras already have. + +Signed-off-by: Caolán McNamara +Change-Id: Iff3450ab2c3781c5181b3f28ed2a321d1e49c6ae +Reviewed-on: https://gerrit.collaboraoffice.com/c/online/+/4425 +Tested-by: Jenkins CPCI +(cherry picked from commit ada76821319b80671dba9908aeea8cabba5cedc0) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/206612 +Tested-by: Jenkins +Reviewed-by: Xisco Fauli +(cherry picked from commit 6bc93227e7c603d3f314202b89b6c567680e6261) +Reviewed-on: https://gerrit.libreoffice.org/c/core/+/206670 +--- + vcl/source/filter/ipict/ipict.cxx | 43 ++++++++++++++++++++----------- + 1 file changed, 28 insertions(+), 15 deletions(-) + +diff --git a/vcl/source/filter/ipict/ipict.cxx b/vcl/source/filter/ipict/ipict.cxx +index 630350a96ee5..58758aa55b37 100644 +--- a/vcl/source/filter/ipict/ipict.cxx ++++ b/vcl/source/filter/ipict/ipict.cxx +@@ -268,43 +268,56 @@ public: + + } + ++static const Color& SanitizePaletteIndex(std::vector const & rvPalette, sal_uInt8 nIndex) ++{ ++ if (nIndex >= rvPalette.size()) ++ { ++ auto nSanitizedIndex = nIndex % rvPalette.size(); ++ SAL_WARN_IF(nIndex != nSanitizedIndex, "filter.pict", "invalid palette index: " ++ << static_cast(nIndex) << ", palette len is: " ++ << rvPalette.size()); ++ nIndex = nSanitizedIndex; ++ } ++ return rvPalette[nIndex]; ++} ++ + static void SetByte(sal_uInt16& nx, sal_uInt16 ny, vcl::bitmap::RawBitmap& rBitmap, sal_uInt16 nPixelSize, sal_uInt8 nDat, sal_uInt16 nWidth, std::vector const & rvPalette) + { + switch (nPixelSize) + { + case 1: +- rBitmap.SetPixel(ny, nx++, rvPalette[(nDat >> 7) & 1]); ++ rBitmap.SetPixel(ny, nx++, SanitizePaletteIndex(rvPalette, (nDat >> 7) & 1)); + if ( nx == nWidth ) break; +- rBitmap.SetPixel(ny, nx++, rvPalette[(nDat >> 6) & 1]); ++ rBitmap.SetPixel(ny, nx++, SanitizePaletteIndex(rvPalette, (nDat >> 6) & 1)); + if ( nx == nWidth ) break; +- rBitmap.SetPixel(ny, nx++, rvPalette[(nDat >> 5) & 1]); ++ rBitmap.SetPixel(ny, nx++, SanitizePaletteIndex(rvPalette, (nDat >> 5) & 1)); + if ( nx == nWidth ) break; +- rBitmap.SetPixel(ny, nx++, rvPalette[(nDat >> 4) & 1]); ++ rBitmap.SetPixel(ny, nx++, SanitizePaletteIndex(rvPalette, (nDat >> 4) & 1)); + if ( nx == nWidth ) break; +- rBitmap.SetPixel(ny, nx++, rvPalette[(nDat >> 3) & 1]); ++ rBitmap.SetPixel(ny, nx++, SanitizePaletteIndex(rvPalette, (nDat >> 3) & 1)); + if ( nx == nWidth ) break; +- rBitmap.SetPixel(ny, nx++, rvPalette[(nDat >> 2) & 1]); ++ rBitmap.SetPixel(ny, nx++, SanitizePaletteIndex(rvPalette, (nDat >> 2) & 1)); + if ( nx == nWidth ) break; +- rBitmap.SetPixel(ny, nx++, rvPalette[(nDat >> 1) & 1]); ++ rBitmap.SetPixel(ny, nx++, SanitizePaletteIndex(rvPalette, (nDat >> 1) & 1)); + if ( nx == nWidth ) break; +- rBitmap.SetPixel(ny, nx++, rvPalette[nDat & 1]); ++ rBitmap.SetPixel(ny, nx++, SanitizePaletteIndex(rvPalette, nDat & 1)); + break; + case 2: +- rBitmap.SetPixel(ny, nx++, rvPalette[nDat >> 6]); ++ rBitmap.SetPixel(ny, nx++, SanitizePaletteIndex(rvPalette, nDat >> 6)); + if ( nx == nWidth ) break; +- rBitmap.SetPixel(ny, nx++, rvPalette[(nDat>>4)&3]); ++ rBitmap.SetPixel(ny, nx++, SanitizePaletteIndex(rvPalette, (nDat>>4)&3)); + if ( nx == nWidth ) break; +- rBitmap.SetPixel(ny, nx++, rvPalette[(nDat>>2)&3]); ++ rBitmap.SetPixel(ny, nx++, SanitizePaletteIndex(rvPalette, (nDat>>2)&3)); + if ( nx == nWidth ) break; +- rBitmap.SetPixel(ny, nx++, rvPalette[nDat & 3]); ++ rBitmap.SetPixel(ny, nx++, SanitizePaletteIndex(rvPalette, nDat & 3)); + break; + case 4: +- rBitmap.SetPixel(ny, nx++, rvPalette[nDat >> 4]); ++ rBitmap.SetPixel(ny, nx++, SanitizePaletteIndex(rvPalette, nDat >> 4)); + if ( nx == nWidth ) break; +- rBitmap.SetPixel(ny, nx++, rvPalette[nDat & 0x0f]); ++ rBitmap.SetPixel(ny, nx++, SanitizePaletteIndex(rvPalette, nDat & 0x0f)); + break; + case 8: +- rBitmap.SetPixel(ny, nx++, rvPalette[nDat]); ++ rBitmap.SetPixel(ny, nx++, SanitizePaletteIndex(rvPalette, nDat)); + break; + } + } +-- +2.47.3 + diff -Nru libreoffice-25.2.3/debian/patches/series libreoffice-25.2.3/debian/patches/series --- libreoffice-25.2.3/debian/patches/series 2026-06-06 20:11:29.000000000 +0000 +++ libreoffice-25.2.3/debian/patches/series 2026-07-21 16:41:22.000000000 +0000 @@ -63,3 +63,10 @@ CVE-2026-8357.diff CVE-2026-8358.diff check-for-hb_shape_full-failure.diff +CVE-2026-63272.diff +CVE-2026-63273.diff +CVE-2026-63274.diff +CVE-2026-63275.diff +CVE-2026-63276.diff +CVE-2026-63278.diff +CVE-2026-63279.diff