Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package librecad for openSUSE:Factory checked in at 2026-11-13 18:32:00 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/librecad (Old) and /work/SRC/openSUSE:Factory/.librecad.new.1251 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "librecad" Fri Nov 13 18:32:00 2026 rev:42 rq:1397069 version:2.2.1.6 Changes: -------- --- /work/SRC/openSUSE:Factory/librecad/librecad.changes 2026-10-21 20:58:52.614477979 +0200 +++ /work/SRC/openSUSE:Factory/.librecad.new.1251/librecad.changes 2026-11-13 18:36:00.348013097 +0100 @@ -1,0 +2,7 @@ +Thu Nov 12 08:59:21 UTC 2026 - Martin Pluskal <[email protected]> + +- CVE-2026-126497: heap OOB write in bundled libdxfrw + dwgReader18::parseDataPage() on crafted R2004 DWG (boo#1290030) + * fix-CVE-2026-126497.patch + +------------------------------------------------------------------- New: ---- fix-CVE-2026-126497.patch ----------(New B)---------- New: dwgReader18::parseDataPage() on crafted R2004 DWG (boo#1290030) * fix-CVE-2026-126497.patch ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ librecad.spec ++++++ --- /var/tmp/diff_new_pack.0S6D0j/_old 2026-11-13 18:36:02.093086980 +0100 +++ /var/tmp/diff_new_pack.0S6D0j/_new 2026-11-13 18:36:02.094087022 +0100 @@ -35,6 +35,7 @@ Patch4: librecad-no-date.diff Patch6: librecad-install.diff Patch7: librecad-plugindir.diff +Patch8: fix-CVE-2026-126497.patch BuildRequires: fdupes BuildRequires: gcc-c++ >= 4.7 BuildRequires: libboost_headers-devel ++++++ _scmsync.obsinfo ++++++ --- /var/tmp/diff_new_pack.0S6D0j/_old 2026-11-13 18:36:02.152089478 +0100 +++ /var/tmp/diff_new_pack.0S6D0j/_new 2026-11-13 18:36:02.157089689 +0100 @@ -1,5 +1,5 @@ -mtime: 1792514360 -commit: a5980246b974872d2dfe9bddfcc6cf43642fd7600970941190666e1eff3fd110 +mtime: 1794479994 +commit: 458ad21997a824faf306f8ebec851c3da83245b91d9fe38f0720a4265f5d9b69 url: https://src.opensuse.org/jengelh/librecad revision: master ++++++ build.specials.obscpio ++++++ ++++++ build.specials.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.gitignore new/.gitignore --- old/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/.gitignore 2026-11-12 11:39:54.000000000 +0100 @@ -0,0 +1 @@ +.osc ++++++ fix-CVE-2026-126497.patch ++++++ From: Dongxu Li <[email protected]> Date: Mon, 9 Nov 2026 17:39:44 -0500 References: https://bugzilla.opensuse.org/1290030 References: CVE-2026-126497 Patch-mainline: yes, upstream commit 17ba2b273b89cc9c8b6fcf71882e327ccf1eebf6 (PR #3257) Subject: libdxfrw: fix heap OOB write in dwgReader18::parseDataPage (CVE-2026-126497) --- libraries/libdxfrw/src/intern/dwgreader18.cpp | 55 +++++++++++++++---- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/libraries/libdxfrw/src/intern/dwgreader18.cpp b/libraries/libdxfrw/src/intern/dwgreader18.cpp index 78fa9b1d..bbaf43f7 100644 --- a/libraries/libdxfrw/src/intern/dwgreader18.cpp +++ b/libraries/libdxfrw/src/intern/dwgreader18.cpp @@ -13,6 +13,8 @@ #include <cstdlib> #include <iostream> #include <fstream> +#include <new> +#include <utility> #include <string> #include <sstream> #include <vector> @@ -111,15 +113,39 @@ bool dwgReader18::parseSysPage(duint8 *decompSec, duint32 decompSize){ //called ???: Section map: 0x4163003b bool dwgReader18::parseDataPage(const dwgSectionInfo &si/*, duint8 *dData*/){ DRW_DBG("\nparseDataPage\n "); - objData.reset( new duint8 [si.pageCount * si.maxSize] ); + constexpr duint64 maxBufferSize = 0x2f000000; + const duint64 pageCap = si.maxSize != 0 ? si.maxSize : si.size; + if (si.size == 0 || (si.compressed != 1 && si.compressed != 2) + || pageCap == 0) + return false; + + duint64 bufferPageCount = + si.size / pageCap + (si.size % pageCap != 0); + if (bufferPageCount < si.pageCount) + bufferPageCount = si.pageCount; + if (bufferPageCount > maxBufferSize / pageCap) + return false; + + const duint64 bufferSize = bufferPageCount * pageCap; + std::unique_ptr<duint8[]> decodedData(new (std::nothrow) + duint8[static_cast<std::size_t>(bufferSize)]()); + if (!decodedData) + return false; for (auto it=si.pages.begin(); it!=si.pages.end(); ++it){ dwgPageInfo pi = it->second; + const duint64 fileSize = fileBuf->size(); + if (pi.size < 32 || pi.address > fileSize + || pi.size > fileSize - pi.address + || pi.startOffset > bufferSize + || pageCap > bufferSize - pi.startOffset) + return false; if (!fileBuf->setPosition(pi.address)) return false; //decript section header duint8 hdrData[32]; - fileBuf->getBytes(hdrData, 32); + if (!fileBuf->getBytes(hdrData, 32)) + return false; dwgCompressor::decrypt18Hdr(hdrData, 32, pi.address); DRW_DBG("Section "); DRW_DBG(si.name); DRW_DBG(" page header=\n"); for (unsigned int i=0, j=0; i< 32;i++) { @@ -150,29 +176,36 @@ bool dwgReader18::parseDataPage(const dwgSectionInfo &si/*, duint8 *dData*/){ DRW_DBG("\n header checksum= "); DRW_DBGH(bufHdr.getRawLong32()); DRW_DBG("\n data checksum= "); DRW_DBGH(bufHdr.getRawLong32()); DRW_DBG("\n"); + if (!bufHdr.isGood() || pi.cSize == 0 + || pi.cSize > pi.size - 32 || pi.cSize > maxBufferSize + || pi.uSize > pageCap) + return false; + //get compressed data - std::vector<duint8> cData(pi.cSize); - if (!fileBuf->setPosition(pi.address + 32)) { + std::unique_ptr<duint8[]> cData(new (std::nothrow) + duint8[static_cast<std::size_t>(pi.cSize)]); + if (!cData || !fileBuf->setPosition(pi.address + 32) + || !fileBuf->getBytes(cData.get(), pi.cSize)) return false; - } - fileBuf->getBytes(cData.data(), pi.cSize); //calculate checksum - duint32 calcsD = checksum(0, cData.data(), pi.cSize); + duint32 calcsD = checksum(0, cData.get(), pi.cSize); for (duint8 i= 24; i<28; ++i) hdrData[i]=0; duint32 calcsH = checksum(calcsD, hdrData, 32); DRW_DBG("Calc header checksum= "); DRW_DBGH(calcsH); DRW_DBG("\nCalc data checksum= "); DRW_DBGH(calcsD); DRW_DBG("\n"); - duint8* oData = objData.get() + pi.startOffset; - pi.uSize = si.maxSize; - DRW_DBG("decompressing "); DRW_DBG(pi.cSize); DRW_DBG(" bytes in "); DRW_DBG(pi.uSize); DRW_DBG(" bytes\n"); + duint8* oData = decodedData.get() + + static_cast<std::size_t>(pi.startOffset); + DRW_DBG("decompressing "); DRW_DBG(pi.cSize); + DRW_DBG(" bytes in "); DRW_DBG(pageCap); DRW_DBG(" bytes\n"); dwgCompressor comp; - if (!comp.decompress18(cData.data(), oData, pi.cSize, pi.uSize)) { + if (!comp.decompress18(cData.get(), oData, pi.cSize, pageCap)) { return false; } } + objData = std::move(decodedData); return true; } -- 2.53.0
