Compare commits

...

11 Commits

Author SHA1 Message Date
openeuler-ci-bot
9bcfb22993
!138 [sync] PR-136: Fix CVE-2023-45935
From: @openeuler-sync-bot 
Reviewed-by: @peijiankang 
Signed-off-by: @peijiankang
2024-04-28 01:37:40 +00:00
lvfei
5c5d497e50 Fix CVE-2023-45935
(cherry picked from commit dca3aa7b7f3d94dfe28c7ee3c701c6876ad3246c)
2024-04-26 17:09:53 +08:00
openeuler-ci-bot
6302f9e097
!134 [sync] PR-127: fix CVE-2024-25580
From: @openeuler-sync-bot 
Reviewed-by: @peijiankang 
Signed-off-by: @peijiankang
2024-04-25 05:35:13 +00:00
peijiankang
cfb3337f0f CVE-2024-25580
(cherry picked from commit 9c1a96338f1c0566823c35f298da56515ee69955)
2024-04-25 13:34:27 +08:00
openeuler-ci-bot
f166bc423f
!117 CVE-2023-51714
From: @dou33 
Reviewed-by: @peijiankang 
Signed-off-by: @peijiankang
2024-02-01 05:27:59 +00:00
peijiankang
e40830cbfe qtbase5.15-CVE-2023-51714 2024-02-01 12:18:11 +08:00
openeuler-ci-bot
a2385c0b86
!116 fix build error of libxkbcommon 1.6.0
From: @dou33 
Reviewed-by: @peijiankang 
Signed-off-by: @peijiankang
2024-01-31 04:24:05 +00:00
dou33
dfe636f529 fix build error of libxkbcommon 1.6.0 2024-01-31 11:04:02 +08:00
openeuler-ci-bot
6f86c04bfd
!106 fix CVE-2023-43114
From: @hua_yadong 
Reviewed-by: @peijiankang 
Signed-off-by: @peijiankang
2023-11-25 04:35:40 +00:00
hua_yadong
d41b1e56b0 qt-CVE-2023-43114 2023-11-25 11:15:12 +08:00
openeuler-ci-bot
4f2158bc5e
!100 qtbase5.15.10-CVE-2023-38197.patch
From: @hua_yadong 
Reviewed-by: @peijiankang 
Signed-off-by: @peijiankang
2023-11-25 00:21:39 +00:00
9 changed files with 458 additions and 40 deletions

31
CVE-2023-45935.patch Normal file
View File

@ -0,0 +1,31 @@
From 33f905df885041e97a465c3706046fa4378ea27f Mon Sep 17 00:00:00 2001
From: Liang Qi <liang.qi@qt.io>
Date: 2023-07-31 05:35:11 +0200
Subject: [PATCH] CVE-2023-45935
port invokeMethodImpl() from QScopeGuard to SlotObjUniquePtr
---
src/plugins/platforms/xcb/qxcbatom.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/plugins/platforms/xcb/qxcbatom.cpp b/src/plugins/platforms/xcb/qxcbatom.cpp
index a769ddad..a33b1b44 100644
--- a/src/plugins/platforms/xcb/qxcbatom.cpp
+++ b/src/plugins/platforms/xcb/qxcbatom.cpp
@@ -270,8 +270,10 @@ void QXcbAtom::initializeAllAtoms(xcb_connection_t *connection) {
for (i = 0; i < QXcbAtom::NAtoms; ++i) {
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, cookies[i], nullptr);
- m_allAtoms[i] = reply->atom;
- free(reply);
+ if (reply) {
+ m_allAtoms[i] = reply->atom;
+ free(reply);
+ }
}
}
--
2.27.0

View File

@ -0,0 +1,197 @@
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 &suffix, const QByteArray &block)
+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) || 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 &suffix, const QByteArray &block)
+{
+ 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<quint32>::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<const KTXHeader *>(buf.constData());
- if (!checkHeader(*header)) {
- qCDebug(lcQtGuiTextureIO, "Unsupported KTX file format in %s", logName().constData());
+ KTXHeader header;
+ memcpy(&header, 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<const KTXMipmapLevel *>(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 = decode(header.bytesOfKeyValueData);
+ quint32 headerKeyValueSize;
+ if (qAddOverflow(qktxh_headerSize, bytesOfKeyValueData, &headerKeyValueSize)) {
+ qWarning(lcQtGuiTextureIO, "Overflow in size of key value data in header of KTX file %s",
+ logName().constData());
+ return QTextureFileData();
+ }
+
+ if (headerKeyValueSize >= quint32(buf.size())) {
+ qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ // Technically, any number of levels is allowed but if the value is bigger than
+ // what is possible in KTX V2 (and what makes sense) we return an error.
+ // maxLevels = log2(max(width, height, depth))
+ const int maxLevels = (sizeof(quint32) * 8)
+ - qCountLeadingZeroBits(std::max(
+ { header.pixelWidth, header.pixelHeight, header.pixelDepth }));
+
+ if (texData.numLevels() > maxLevels) {
+ qWarning(lcQtGuiTextureIO, "Too many levels in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ quint32 offset = headerKeyValueSize;
+ for (int level = 0; level < texData.numLevels(); level++) {
+ const auto imageSizeSlice = safeSlice(buf, offset, sizeof(quint32));
+ if (imageSizeSlice.isEmpty()) {
+ qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ const quint32 imageSize = decode(qFromUnaligned<quint32>(imageSizeSlice.data()));
+ offset += sizeof(quint32); // overflow checked indirectly above
+
+ texData.setDataOffset(offset, level);
+ texData.setDataLength(imageSize, level);
+
+ // Add image data and padding to offset
+ quint32 padded = 0;
+ if (nearestMultipleOf4(imageSize, &padded)) {
+ qWarning(lcQtGuiTextureIO, "Overflow in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ quint32 offsetNext;
+ if (qAddOverflow(offset, padded, &offsetNext)) {
+ qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData());
+ return QTextureFileData();
+ }
+
+ offset = offsetNext;
}
if (!texData.isValid()) {
- qCDebug(lcQtGuiTextureIO, "Invalid values in header of KTX file %s", logName().constData());
+ qWarning(lcQtGuiTextureIO, "Invalid values in header of KTX file %s",
+ logName().constData());
return QTextureFileData();
}
@@ -191,7 +271,7 @@ bool QKtxHandler::checkHeader(const KTXHeader &header)
(decode(header.numberOfFaces) == 1));
}
-quint32 QKtxHandler::decode(quint32 val)
+quint32 QKtxHandler::decode(quint32 val) const
{
return inverseEndian ? qbswap<quint32>(val) : val;
}
diff --git a/src/gui/util/qktxhandler_p.h b/src/gui/util/qktxhandler_p.h
index f831e59d95..cdf1b2eaf8 100644
--- a/src/gui/util/qktxhandler_p.h
+++ b/src/gui/util/qktxhandler_p.h
@@ -68,7 +68,7 @@ public:
private:
bool checkHeader(const KTXHeader &header);
- quint32 decode(quint32 val);
+ quint32 decode(quint32 val) const;
bool inverseEndian = false;
};

View File

@ -0,0 +1,31 @@
From cf3d8031ac756fb339658d1e9fabb9e7d254e66f Mon Sep 17 00:00:00 2001
From: peijiankang <peijiankang@kylinos.cn>
Date: Mon, 29 Jan 2024 11:10:54 +0800
Subject: [PATCH] fix build error of libxkbcommon 1.6.0
---
src/platformsupport/input/xkbcommon/qxkbcommon.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/platformsupport/input/xkbcommon/qxkbcommon.cpp b/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
index b713c194..ecf02de6 100644
--- a/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
+++ b/src/platformsupport/input/xkbcommon/qxkbcommon.cpp
@@ -273,10 +273,14 @@ static constexpr const auto KeyTbl = qMakeArray(
Xkb2Qt<XKB_KEY_dead_small_schwa, Qt::Key_Dead_Small_Schwa>,
Xkb2Qt<XKB_KEY_dead_capital_schwa, Qt::Key_Dead_Capital_Schwa>,
Xkb2Qt<XKB_KEY_dead_greek, Qt::Key_Dead_Greek>,
+/* The following four XKB_KEY_dead keys got removed in libxkbcommon 1.6.0
+ The define check is kind of version check here. */
+#ifdef XKB_KEY_dead_lowline
Xkb2Qt<XKB_KEY_dead_lowline, Qt::Key_Dead_Lowline>,
Xkb2Qt<XKB_KEY_dead_aboveverticalline, Qt::Key_Dead_Aboveverticalline>,
Xkb2Qt<XKB_KEY_dead_belowverticalline, Qt::Key_Dead_Belowverticalline>,
Xkb2Qt<XKB_KEY_dead_longsolidusoverlay, Qt::Key_Dead_Longsolidusoverlay>,
+#endif
// Special keys from X.org - This include multimedia keys,
// wireless/bluetooth/uwb keys, special launcher keys, etc.
--
2.41.0

Binary file not shown.

View File

@ -1,17 +0,0 @@
diff -up qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/configure.json.firebird qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/configure.json
--- qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/configure.json.firebird 2019-01-28 11:11:52.000000000 -0600
+++ qtbase-everywhere-src-5.12.1/src/plugins/sqldrivers/configure.json 2019-02-03 13:41:27.392305128 -0600
@@ -49,10 +49,11 @@
"ibase": {
"label": "InterBase",
"test": {},
- "headers": "ibase.h",
+ "headers": "ibase.h",
"sources": [
{ "libs": "-lgds32_ms", "condition": "config.win32" },
- { "libs": "-lgds", "condition": "!config.win32" }
+ { "libs": "-lgds", "condition": "!config.win32" },
+ { "libs": "-lfbclient", "condition": "!config.win32" }
]
},
"mysql": {

View File

@ -36,7 +36,7 @@
Name: qt5-qtbase
Summary: Qt5 - QtBase components
Version: 5.15.10
Release: 4
Release: 9
# See LGPL_EXCEPTIONS.txt, for exception details
License: LGPL-3.0-only OR GPL-3.0-only WITH Qt-GPL-exception-1.0
@ -59,7 +59,7 @@ Source3: 10-qt5-check-opengl2.sh
Source4: macros.qt5-qtbase
# support multilib optflags
#Patch2: qtbase-multilib_optflags.patch
Patch0000: qtbase-multilib_optflags.patch
# make mixing versions with private apis a warning instead of fatal error
Patch0001: qtbase-everywhere-src-5.15.6-private_api_warning.patch
@ -68,11 +68,6 @@ Patch0001: qtbase-everywhere-src-5.15.6-private_api_warning.patch
# namespace QT_VERSION_CHECK to workaround major/minor being pre-defined (#1396755)
Patch0002: qtbase-opensource-src-5.8.0-QT_VERSION_CHECK.patch
# 1381828 - Broken window scaling for some QT5 applications (#1381828)
# This patch moves the threshold for 2x scaling from the DPI of 144 to 192,
# the same value GNOME uses. It's not a complete solution...
#Patch51: qtbase-hidpi_scale_at_192.patch
# 1. Workaround moc/multilib issues
# https://bugzilla.redhat.com/show_bug.cgi?id=1290020
# https://bugreports.qt.io/browse/QTBUG-49972
@ -113,7 +108,7 @@ Patch0013: %{name}-gcc11.patch
# https://invent.kde.org/qt/qt/qtbase, kde/5.15 branch
# git diff v5.15.10-lts-lgpl..HEAD | gzip > kde-5.15-rollup-$(date +%Y%m%d).patch.gz
# patch100 in lookaside cache due to large'ish size -- rdieter
Patch100: kde-5.15-rollup-20230613.patch.gz
Patch100: kde-5.15-rollup-20230613.patch
Patch101: qtbase-5.15.10-fix-missing-qtsan-include.patch
# Workaround for font rendering issue with cjk-vf-fonts
@ -134,6 +129,13 @@ Patch0024: Fix-lupdate-command-error-on-loongarch64.patch
Patch0025: CVE-2023-37369.patch
# https://codereview.qt-project.org/c/qt/qtbase/+/488960
Patch0026: qtbase5.15.10-CVE-2023-38197.patch
# https://codereview.qt-project.org/c/qt/qtbase/+/503026
Patch0027: qtbase5.15.10-CVE-2023-43114.patch
Patch0028: fix-build-error-of-libxkbcommon-1.6.0.patch
Patch0029: qtbase5.15-CVE-2023-51714.patch
Patch0030: CVE-2024-25580-qtbase-5.15.diff
Patch0031: CVE-2023-45935.patch
# Do not check any files in %%{_qt5_plugindir}/platformthemes/ for requires.
# Those themes are there for platform integration. If the required libraries are
# not there, the platform to integrate with isn't either. Then Qt will just
@ -371,13 +373,12 @@ Qt5 libraries used for drawing widgets and OpenGL items.
%setup -q -n %{qt_module}-everywhere-src-%{version}
## dowstream patches
%patch -P0000 -p1
%patch -P0001 -p1 -b .private_api_warning
## upstream fixes
%patch -P0002 -p1 -b .QT_VERSION_CHECK
# FIXME/TODO : rebase or drop -- rdieter
#patch -P51 -p1 -b .hidpi_scale_at_192
%patch -P0004 -p1 -b .moc_macros
%patch -P0005 -p1 -b .qt5gui_cmake_isystem_includes
%patch -P0006 -p1 -b .qmake_LFLAGS
@ -401,6 +402,12 @@ Qt5 libraries used for drawing widgets and OpenGL items.
%patch -P0024 -p1
%patch -P0025 -p1
%patch -P0026 -p1
%patch -P0027 -p1
%patch -P0028 -p1
%patch -P0029 -p1
%patch -P0030 -p1
%patch -P0031 -p1
# move some bundled libs to ensure they're not accidentally used
pushd src/3rdparty
mkdir UNUSED
@ -1058,7 +1065,22 @@ fi
%changelog
* Fri Nov 24 2023 peijiankang <peijiankang@kylinos.cn> - 5.15.10-4
* Wed Apr 24 2024 lvfei <lvfei@kylinos.cn> - 5.15.10-9
- add CVE-2023-45935.patch
* Wed Apr 17 2024 peijiankang <peijiankang@kylinos.cn> - 5.15.10-8
- add CVE-2024-25580-qtbase-5.15.diff
* Wed Jan 31 2024 douyan <douyan@kylinos.cn> - 5.15.10-7
- add qtbase5.15-CVE-2023-51714.patch
* Wed Jan 31 2024 douyan <douyan@kylinos.cn> - 5.15.10-6
- fix build error of libxkbcommon-1.6.0
* Sat Nov 25 2023 hua_yadong <huayadong@kylinos.cn> - 5.15.10-5
- fix qtbase5.15.10-CVE-2023-43114.patch
* Fri Nov 24 2023 hua_yadong <huayadong@kylinos.cn> - 5.15.10-4
- fix qtbase5.15.10-CVE-2023-38197.patch
* Wed Sep 13 2023 yoo <sunyuechi@iscas.ac.cn> - 5.15.10-3

View File

@ -1,12 +0,0 @@
diff -up qtbase-everywhere-src-5.12.1/src/plugins/platforms/xcb/qxcbscreen.cpp.hidpi_scale_at_192 qtbase-everywhere-src-5.12.1/src/plugins/platforms/xcb/qxcbscreen.cpp
--- qtbase-everywhere-src-5.12.1/src/plugins/platforms/xcb/qxcbscreen.cpp.hidpi_scale_at_192 2019-02-03 13:21:27.866906481 -0600
+++ qtbase-everywhere-src-5.12.1/src/plugins/platforms/xcb/qxcbscreen.cpp 2019-02-03 13:23:47.554767565 -0600
@@ -744,7 +744,7 @@ void QXcbScreen::updateGeometry(const QR
// Use 128 as a reference DPI on small screens. This favors "small UI" over "large UI".
qreal referenceDpi = physicalSize().width() <= 320 ? 128 : 96;
- m_pixelDensity = qMax(1, qRound(dpi/referenceDpi));
+ m_pixelDensity = qMax(1, (int) (dpi/referenceDpi)); //instead of rounding at 1.5, round at 2.0 (same as GNOME)
m_geometry = geometry;
m_availableGeometry = geometry & m_virtualDesktop->workArea();
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry);

View File

@ -0,0 +1,37 @@
From 061cbe5796a9ff1e998bd5753bb5b44e4481df11 Mon Sep 17 00:00:00 2001
From: peijiankang <peijiankang@kylinos.cn>
Date: Wed, 31 Jan 2024 13:38:10 +0800
Subject: [PATCH] qtbase5.15-CVE-2023-51714
---
src/network/access/http2/hpacktable.cpp | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/network/access/http2/hpacktable.cpp b/src/network/access/http2/hpacktable.cpp
index fddb5fec..315f3e23 100644
--- a/src/network/access/http2/hpacktable.cpp
+++ b/src/network/access/http2/hpacktable.cpp
@@ -40,6 +40,7 @@
#include "hpacktable_p.h"
#include <QtCore/qdebug.h>
+#include <QtCore/private/qnumeric_p.h>
#include <algorithm>
#include <cstddef>
@@ -62,8 +63,10 @@ HeaderSize entry_size(const QByteArray &name, const QByteArray &value)
// for counting the number of references to the name and value would have
// 32 octets of overhead."
- const unsigned sum = unsigned(name.size() + value.size());
- if (std::numeric_limits<unsigned>::max() - 32 < sum)
+ size_t sum;
+ if (add_overflow(size_t(name.size()), size_t(value.size()), &sum))
+ return HeaderSize();
+ if (sum > (std::numeric_limits<unsigned>::max() - 32))
return HeaderSize();
return HeaderSize(true, quint32(sum + 32));
}
--
2.41.0

View File

@ -0,0 +1,129 @@
From 61dedcc9d02dbd16cc1bd1cd8aafae96213104a1 Mon Sep 17 00:00:00 2001
From: hua_yadong <huayadong@kylinos.cn>
Date: Sat, 25 Nov 2023 11:08:39 +0800
Subject: [PATCH] qtbase5.15.10-CVE-2023-43114
---
.../windows/qwindowsfontdatabase.cpp | 67 ++++++++++++++-----
1 file changed, 51 insertions(+), 16 deletions(-)
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
index 09d2d916..0e6fe5eb 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsfontdatabase.cpp
@@ -1471,36 +1471,70 @@ QT_WARNING_POP
return fontEngine;
}
-static QList<quint32> getTrueTypeFontOffsets(const uchar *fontData)
+static QList<quint32> getTrueTypeFontOffsets(const uchar *fontData, const uchar *fileEndSentinel)
{
QList<quint32> offsets;
- const quint32 headerTag = *reinterpret_cast<const quint32 *>(fontData);
+ if (fileEndSentinel - fontData < 12) {
+ qCWarning(lcQpaFonts) << "Corrupted font data detected";
+ return offsets;
+ }
+
+ const quint32 headerTag = qFromUnaligned<quint32>(fontData);
if (headerTag != MAKE_TAG('t', 't', 'c', 'f')) {
if (headerTag != MAKE_TAG(0, 1, 0, 0)
&& headerTag != MAKE_TAG('O', 'T', 'T', 'O')
&& headerTag != MAKE_TAG('t', 'r', 'u', 'e')
- && headerTag != MAKE_TAG('t', 'y', 'p', '1'))
+ && headerTag != MAKE_TAG('t', 'y', 'p', '1')) {
return offsets;
+ }
offsets << 0;
return offsets;
}
+
+ const quint32 maximumNumFonts = 0xffff;
const quint32 numFonts = qFromBigEndian<quint32>(fontData + 8);
- for (uint i = 0; i < numFonts; ++i) {
- offsets << qFromBigEndian<quint32>(fontData + 12 + i * 4);
+ if (numFonts > maximumNumFonts) {
+ qCWarning(lcQpaFonts) << "Font collection of" << numFonts << "fonts is too large. Aborting.";
+ return offsets;
}
+
+ if (quintptr(fileEndSentinel - fontData) > 12 + (numFonts - 1) * 4) {
+ for (quint32 i = 0; i < numFonts; ++i)
+ offsets << qFromBigEndian<quint32>(fontData + 12 + i * 4);
+ } else {
+ qCWarning(lcQpaFonts) << "Corrupted font data detected";
+ }
+
return offsets;
}
-static void getFontTable(const uchar *fileBegin, const uchar *data, quint32 tag, const uchar **table, quint32 *length)
+static void getFontTable(const uchar *fileBegin, const uchar *fileEndSentinel, const uchar *data, quint32 tag, const uchar **table, quint32 *length)
{
- const quint16 numTables = qFromBigEndian<quint16>(data + 4);
- for (uint i = 0; i < numTables; ++i) {
- const quint32 offset = 12 + 16 * i;
- if (*reinterpret_cast<const quint32 *>(data + offset) == tag) {
- *table = fileBegin + qFromBigEndian<quint32>(data + offset + 8);
- *length = qFromBigEndian<quint32>(data + offset + 12);
- return;
+ if (fileEndSentinel - data >= 6) {
+ const quint16 numTables = qFromBigEndian<quint16>(data + 4);
+ if (fileEndSentinel - data >= 28 + 16 * (numTables - 1)) {
+ for (quint32 i = 0; i < numTables; ++i) {
+ const quint32 offset = 12 + 16 * i;
+ if (qFromUnaligned<quint32>(data + offset) == tag) {
+ const quint32 tableOffset = qFromBigEndian<quint32>(data + offset + 8);
+ if (quintptr(fileEndSentinel - fileBegin) <= tableOffset) {
+ qCWarning(lcQpaFonts) << "Corrupted font data detected";
+ break;
+ }
+ *table = fileBegin + tableOffset;
+ *length = qFromBigEndian<quint32>(data + offset + 12);
+ if (quintptr(fileEndSentinel - *table) < *length) {
+ qCWarning(lcQpaFonts) << "Corrupted font data detected";
+ break;
+ }
+ return;
+ }
+ }
+ } else {
+ qCWarning(lcQpaFonts) << "Corrupted font data detected";
}
+ } else {
+ qCWarning(lcQpaFonts) << "Corrupted font data detected";
}
*table = 0;
*length = 0;
@@ -1513,8 +1547,9 @@ static void getFamiliesAndSignatures(const QByteArray &fontData,
QVector<QFontValues> *values)
{
const uchar *data = reinterpret_cast<const uchar *>(fontData.constData());
+ const uchar *dataEndSentinel = data + fontData.size();
- QList<quint32> offsets = getTrueTypeFontOffsets(data);
+ QList<quint32> offsets = getTrueTypeFontOffsets(data, dataEndSentinel);
if (offsets.isEmpty())
return;
@@ -1522,7 +1557,7 @@ static void getFamiliesAndSignatures(const QByteArray &fontData,
const uchar *font = data + offsets.at(i);
const uchar *table;
quint32 length;
- getFontTable(data, font, MAKE_TAG('n', 'a', 'm', 'e'), &table, &length);
+ getFontTable(data, dataEndSentinel, font, MAKE_TAG('n', 'a', 'm', 'e'), &table, &length);
if (!table)
continue;
QFontNames names = qt_getCanonicalFontNames(table, length);
@@ -1532,7 +1567,7 @@ static void getFamiliesAndSignatures(const QByteArray &fontData,
families->append(std::move(names));
if (values || signatures)
- getFontTable(data, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length);
+ getFontTable(data, dataEndSentinel, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length);
if (values) {
QFontValues fontValues;
--
2.41.0