File qt3-trinity-buffer-overflow-CVE-2020-17507.patch of Package qt3

From 9d7d238e9efc673a0dbda1140e2eaa740fe00d6b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sl=C3=A1vek=20Banko?= <slavek.banko@axis.cz>
Date: Mon, 28 Sep 2020 15:21:41 +0200
Subject: Fix buffer overflow in XBM parser.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Avoid parsing over the buffer limit, or interpreting non-hex as hex.
This still leaves parsing of lines longer than 300 chars unreliable.

Based on Qt5 patch for CVE-2020-17507.

Signed-off-by: Slávek Banko <slavek.banko@axis.cz>
---
 src/kernel/qimage.cpp | 39 ++++++++++++++++++++++++++++++++-------
 1 file changed, 32 insertions(+), 7 deletions(-)

diff --git a/src/kernel/qimage.cpp b/src/kernel/qimage.cpp
index 676a969..69b5350 100644
--- a/src/kernel/qimage.cpp
+++ b/src/kernel/qimage.cpp
@@ -5512,18 +5512,32 @@ static inline int hex2byte( char *p )
 static void read_xbm_image( QImageIO *iio )
 {
     const int	buflen = 300;
+    const int	maxlen = 4096;
     char	buf[buflen];
     QRegExp	r1, r2;
     QIODevice  *d = iio->ioDevice();
     int		w=-1, h=-1;
     QImage	image;
+    Q_INT64	readBytes = 0;
+    Q_INT64	totalReadBytes = 0;
 
     r1 = QString::fromLatin1("^#define[ \t]+[a-zA-Z0-9._]+[ \t]+");
     r2 = QString::fromLatin1("[0-9]+");
-    d->readLine( buf, buflen );		// "#define .._width <num>"
 
-    while (!d->atEnd() && buf[0] != '#') //skip leading comment, if any
-        d->readLine( buf, buflen );
+    buf[0] = '\0';
+    while (buf[0] != '#') { //skip leading comment, if any
+        readBytes = d->readLine(buf, buflen);
+
+        // if readBytes >= buflen, it's very probably not a C file
+        if ((readBytes <= 0) || (readBytes >= (buflen-1)))
+            return;
+
+        // limit xbm headers to the first 4k in the file to prevent
+        // excessive reads on non-xbm files
+        totalReadBytes += readBytes;
+        if (totalReadBytes >= maxlen)
+            return;
+    }
 
     QString sbuf;
     sbuf = QString::fromLatin1(buf);
@@ -5532,7 +5546,10 @@ static void read_xbm_image( QImageIO *iio )
 	 r2.search(sbuf, r1.matchedLength()) == r1.matchedLength() )
 	w = atoi( &buf[r1.matchedLength()] );
 
-    d->readLine( buf, buflen );			// "#define .._height <num>"
+    readBytes = d->readLine(buf, buflen );		// "#define .._height <num>"
+    if (readBytes <= 0) {
+        return;
+    }
     sbuf = QString::fromLatin1(buf);
 
     if ( r1.search(sbuf) == 0 &&
@@ -5543,8 +5560,11 @@ static void read_xbm_image( QImageIO *iio )
 	return;					// format error
 
     for ( ;; ) {				// scan for data
-	if ( d->readLine(buf, buflen) <= 0 )	// end of file
+	readBytes = d->readLine(buf, buflen);
+	if (readBytes <= 0) {	// end of file
 	    return;
+	}
+	buf[readBytes] = '\0';
 	if ( strstr(buf,"0x") != 0 )		// does line contain data?
 	    break;
     }
@@ -5562,7 +5582,10 @@ static void read_xbm_image( QImageIO *iio )
     w = (w+7)/8;				// byte width
 
     while ( y < h ) {				// for all encoded bytes...
-	if ( p ) {				// p = "0x.."
+	if (p && (p < (buf + readBytes - 3))) {      // p = "0x.."
+	    if (!isxdigit(p[2]) || !isxdigit(p[3])) {
+		return;
+	    }
 	    *b++ = hex2byte(p+2);
 	    p += 2;
 	    if ( ++x == w && ++y < h ) {
@@ -5571,8 +5594,10 @@ static void read_xbm_image( QImageIO *iio )
 	    }
 	    p = strstr( p, "0x" );
 	} else {				// read another line
-	    if ( d->readLine(buf,buflen) <= 0 )	// EOF ==> truncated image
+	    readBytes = d->readLine(buf, buflen);
+	    if (readBytes <= 0)	// EOF ==> truncated image
 		break;
+	    buf[readBytes] = '\0';
 	    p = strstr( buf, "0x" );
 	}
     }
-- 
cgit v1.2.1

openSUSE Build Service is sponsored by