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

Reply via email to