Bug#1064053: qtbase-opensource-src: CVE-2024-25580

2024-02-16 Thread James Addison
Source: qtbase-opensource-src
Followup-For: Bug #1064053
Control: found -1
Control: found -1 5.12.2+dfsg-1

Replying to set the earliest version affected from the advisory blogpost[1],
and to (re)attach the patch from the duplicate bugreport.

[1]  
https://www.qt.io/blog/security-advisory-potential-buffer-overflow-when-reading-ktx-images
diff --git a/src/gui/util/qktxhandler.cpp b/src/gui/util/qktxhandler.cpp
index 0d98e97453..6a79e55109 100644
--- a/src/gui/util/qktxhandler.cpp
+++ b/src/gui/util/qktxhandler.cpp
@@ -73,7 +73,7 @@ struct KTXHeader {
 quint32 bytesOfKeyValueData;
 };
 
-static const quint32 headerSize = sizeof(KTXHeader);
+static constexpr quint32 qktxh_headerSize = sizeof(KTXHeader);
 
 // Currently unused, declared for future reference
 struct KTXKeyValuePairItem {
@@ -103,11 +103,36 @@ struct KTXMipmapLevel {
 */
 };
 
-bool QKtxHandler::canRead(const QByteArray , const QByteArray )
+static bool qAddOverflow(quint32 v1, quint32 v2, quint32 *r) {
+// unsigned additions are well-defined
+*r = v1 + v2;
+return v1 > quint32(v1 + v2);
+}
+
+// Returns the nearest multiple of 4 greater than or equal to 'value'
+static bool nearestMultipleOf4(quint32 value, quint32 *result)
+{
+constexpr quint32 rounding = 4;
+*result = 0;
+if (qAddOverflow(value, rounding - 1, result))
+return true;
+*result &= ~(rounding - 1);
+return false;
+}
+
+// Returns a slice with prechecked bounds
+static QByteArray safeSlice(const QByteArray& array, quint32 start, quint32 
length)
 {
-Q_UNUSED(suffix)
+quint32 end = 0;
+if (qAddOverflow(start, length, ) || end > quint32(array.length()))
+return {};
+return QByteArray(array.data() + start, length);
+}
 
-return (qstrncmp(block.constData(), ktxIdentifier, KTX_IDENTIFIER_LENGTH) 
== 0);
+bool QKtxHandler::canRead(const QByteArray , const QByteArray )
+{
+Q_UNUSED(suffix);
+return block.startsWith(QByteArray::fromRawData(ktxIdentifier, 
KTX_IDENTIFIER_LENGTH));
 }
 
 QTextureFileData QKtxHandler::read()
@@ -115,42 +140,97 @@ QTextureFileData QKtxHandler::read()
 if (!device())
 return QTextureFileData();
 
-QByteArray buf = device()->readAll();
-const quint32 dataSize = quint32(buf.size());
-if (dataSize < headerSize || !canRead(QByteArray(), buf)) {
-qCDebug(lcQtGuiTextureIO, "Invalid KTX file %s", 
logName().constData());
+const QByteArray buf = device()->readAll();
+if (size_t(buf.size()) > std::numeric_limits::max()) {
+qWarning(lcQtGuiTextureIO, "Too big KTX file %s", 
logName().constData());
+return QTextureFileData();
+}
+
+if (!canRead(QByteArray(), buf)) {
+qWarning(lcQtGuiTextureIO, "Invalid KTX file %s", 
logName().constData());
+return QTextureFileData();
+}
+
+if (buf.size() < qsizetype(qktxh_headerSize)) {
+qWarning(lcQtGuiTextureIO, "Invalid KTX header size in %s", 
logName().constData());
 return QTextureFileData();
 }
 
-const KTXHeader *header = reinterpret_cast(buf.constData());
-if (!checkHeader(*header)) {
-qCDebug(lcQtGuiTextureIO, "Unsupported KTX file format in %s", 
logName().constData());
+KTXHeader header;
+memcpy(, buf.data(), qktxh_headerSize);
+if (!checkHeader(header)) {
+qWarning(lcQtGuiTextureIO, "Unsupported KTX file format in %s", 
logName().constData());
 return QTextureFileData();
 }
 
 QTextureFileData texData;
 texData.setData(buf);
 
-texData.setSize(QSize(decode(header->pixelWidth), 
decode(header->pixelHeight)));
-texData.setGLFormat(decode(header->glFormat));
-texData.setGLInternalFormat(decode(header->glInternalFormat));
-texData.setGLBaseInternalFormat(decode(header->glBaseInternalFormat));
-
-texData.setNumLevels(decode(header->numberOfMipmapLevels));
-quint32 offset = headerSize + decode(header->bytesOfKeyValueData);
-const int maxLevels = qMin(texData.numLevels(), 32);   // Cap 
iterations in case of corrupt file.
-for (int i = 0; i < maxLevels; i++) {
-if (offset + sizeof(KTXMipmapLevel) > dataSize)// 
Corrupt file; avoid oob read
-break;
-const KTXMipmapLevel *level = reinterpret_cast(buf.constData() + offset);
-quint32 levelLen = decode(level->imageSize);
-texData.setDataOffset(offset + sizeof(KTXMipmapLevel::imageSize), i);
-texData.setDataLength(levelLen, i);
-offset += sizeof(KTXMipmapLevel::imageSize) + levelLen + (3 - 
((levelLen + 3) % 4));
+texData.setSize(QSize(decode(header.pixelWidth), 
decode(header.pixelHeight)));
+texData.setGLFormat(decode(header.glFormat));
+texData.setGLInternalFormat(decode(header.glInternalFormat));
+texData.setGLBaseInternalFormat(decode(header.glBaseInternalFormat));
+
+texData.setNumLevels(decode(header.numberOfMipmapLevels));
+
+const quint32 bytesOfKeyValueData = 

Bug#1064053: qtbase-opensource-src: CVE-2024-25580

2024-02-16 Thread Moritz Mühlenhoff
Source: qtbase-opensource-src
X-Debbugs-CC: t...@security.debian.org
Severity: important
Tags: security

Hi,

The following vulnerability was published for qtbase-opensource-src.

CVE-2024-25580[0]:
https://bugzilla.redhat.com/show_bug.cgi?id=2264423
https://download.qt.io/official_releases/qt/5.15/CVE-2024-25580-qtbase-5.15.diff


If you fix the vulnerability please also make sure to include the
CVE (Common Vulnerabilities & Exposures) id in your changelog entry.

For further information see:

[0] https://security-tracker.debian.org/tracker/CVE-2024-25580
https://www.cve.org/CVERecord?id=CVE-2024-25580

Please adjust the affected versions in the BTS as needed.