Skip to content

Commit

Permalink
devel/qt6-base: Address CVE-2023-51714
Browse files Browse the repository at this point in the history
A potential integer overflow has been discovered in Qt's HTTP2
implementation. If the HTTP2 implementation receives more then 4GiB
in total headers, or more than 2GiB for any given header pair, then
the internal buffers may overflow.

Reported by:	vvd via #freebsd-desktop
MFH:		2024Q1
Security:	e2f981f1-ad9e-11ee-8b55-4ccc6adda413
  • Loading branch information
BSDKaffee committed Jan 7, 2024
1 parent 205177c commit dff1011
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 1 deletion.
2 changes: 1 addition & 1 deletion devel/qt6-base/Makefile
@@ -1,6 +1,6 @@
PORTNAME= base
DISTVERSION= ${QT6_VERSION}
PORTREVISION= 1
PORTREVISION= 2
CATEGORIES= devel
PKGNAMEPREFIX= qt6-

Expand Down
145 changes: 145 additions & 0 deletions devel/qt6-base/files/patch-security-rollup
@@ -0,0 +1,145 @@
From 13c16b756900fe524f6d9534e8a07aa003c05e0c Mon Sep 17 00:00:00 2001
From: Marc Mutz <marc.mutz@qt.io>
Date: Tue, 12 Dec 2023 20:51:56 +0100
Subject: [PATCH] HPack: fix a Yoda Condition

Putting the variable on the LHS of a relational operation makes the
expression easier to read. In this case, we find that the whole
expression is nonsensical as an overflow protection, because if
name.size() + value.size() overflows, the result will exactly _not_
be > max() - 32, because UB will have happened.

To be fixed in a follow-up commit.

As a drive-by, add parentheses around the RHS.

Pick-to: 6.5 6.2 5.15
Change-Id: I35ce598884c37c51b74756b3bd2734b9aad63c09
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit 658607a34ead214fbacbc2cca44915655c318ea9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 4f7efd41740107f90960116700e3134f5e433867)
---
src/network/access/http2/hpacktable.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/network/access/http2/hpacktable.cpp b/src/network/access/http2/hpacktable.cpp
index 74a09a207ff..c8c5d098c80 100644
--- src/network/access/http2/hpacktable.cpp.orig
+++ src/network/access/http2/hpacktable.cpp
@@ -27,7 +27,7 @@ HeaderSize entry_size(QByteArrayView name, QByteArrayView value)
// 32 octets of overhead."

const unsigned sum = unsigned(name.size() + value.size());
- if (std::numeric_limits<unsigned>::max() - 32 < sum)
+ if (sum > (std::numeric_limits<unsigned>::max() - 32))
return HeaderSize();
return HeaderSize(true, quint32(sum + 32));
}
From 811b9eef6d08d929af8708adbf2a5effb0eb62d7 Mon Sep 17 00:00:00 2001
From: Marc Mutz <marc.mutz@qt.io>
Date: Tue, 12 Dec 2023 22:08:07 +0100
Subject: [PATCH] HPack: fix incorrect integer overflow check

This code never worked:

For the comparison with max() - 32 to trigger, on 32-bit platforms (or
Qt 5) signed interger overflow would have had to happen in the
addition of the two sizes. The compiler can therefore remove the
overflow check as dead code.

On Qt 6 and 64-bit platforms, the signed integer addition would be
very unlikely to overflow, but the following truncation to uint32
would yield the correct result only in a narrow 32-value window just
below UINT_MAX, if even that.

Fix by using the proper tool, qAddOverflow.

Pick-to: 6.5 6.2 5.15
Change-Id: I7599f2e75ff7f488077b0c60b81022591005661c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from commit ee5da1f2eaf8932aeca02ffea6e4c618585e29e3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit debeb8878da2dc706ead04b6072ecbe7e5313860)
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
---
src/network/access/http2/hpacktable.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/network/access/http2/hpacktable.cpp b/src/network/access/http2/hpacktable.cpp
index c8c5d098c80..2c728b37e3b 100644
--- src/network/access/http2/hpacktable.cpp.orig
+++ src/network/access/http2/hpacktable.cpp
@@ -26,7 +26,9 @@ HeaderSize entry_size(QByteArrayView name, QByteArrayView 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());
+ size_t sum;
+ if (qAddOverflow(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));
From 2e50fbc30a61d69cc2caf6fbd8aca29aa6b8db86 Mon Sep 17 00:00:00 2001
From: Marc Mutz <marc.mutz@qt.io>
Date: Tue, 19 Dec 2023 14:22:37 +0100
Subject: [PATCH] Http2: fix potential overflow in assemble_hpack_block()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The function is given a vector of Http2::Frame's and flattens it into
a vector<uchar>. While each Frame can contain a maximum of 16GiB of
data (24-bit size field), one "only" needs 257 of them to overflow the
quint32 variable's range.

So make sure any overflow does not go undetected.

Keep the limited uint32_t range for now, as we don't know whether all
consumers of the result can deal with more than 4GiB of data.

Since all these frames must be in memory, this cannot overflow in
practice on 32-bit machines.

Pick-to: 6.5 6.2 5.15
Change-Id: Iafaa7d1c870cba9100e75065db11d95934f86213
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
(cherry picked from commit 1e6bb61af3ae29755f93b92f157df026f934ae61)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit af8a9874c32c6b1af8998be9487170b6269dbe1f)
---
src/network/access/qhttp2protocolhandler.cpp | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp
index 88963f89687..707ef8de54e 100644
--- src/network/access/qhttp2protocolhandler.cpp.orig
+++ src/network/access/qhttp2protocolhandler.cpp
@@ -10,10 +10,12 @@
#include <private/qnoncontiguousbytedevice_p.h>

#include <QtNetwork/qabstractsocket.h>
+
#include <QtCore/qloggingcategory.h>
#include <QtCore/qendian.h>
#include <QtCore/qdebug.h>
#include <QtCore/qlist.h>
+#include <QtCore/qnumeric.h>
#include <QtCore/qurl.h>

#include <qhttp2configuration.h>
@@ -90,8 +92,10 @@ std::vector<uchar> assemble_hpack_block(const std::vector<Http2::Frame> &frames)
std::vector<uchar> hpackBlock;

quint32 total = 0;
- for (const auto &frame : frames)
- total += frame.hpackBlockSize();
+ for (const auto &frame : frames) {
+ if (qAddOverflow(total, frame.hpackBlockSize(), &total))
+ return hpackBlock;
+ }

if (!total)
return hpackBlock;

0 comments on commit dff1011

Please sign in to comment.