From 7de89a84c31fb1601d13141f3e1774a2432c8002 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 12 Dec 2023 22:08:07 +0100 Subject: [PATCH] [PATCH] HPack: fix incorrect integer overflow check MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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. Manual conflict resolutions: - qAddOverflow doesn't exist in Qt 5, use private add_overflow predecessor API instead Change-Id: I7599f2e75ff7f488077b0c60b81022591005661c Reviewed-by: Allan Sandfeld Jensen (cherry picked from commit ee5da1f2eaf8932aeca02ffea6e4c618585e29e3) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit debeb8878da2dc706ead04b6072ecbe7e5313860) Reviewed-by: Thiago Macieira Reviewed-by: Marc Mutz (cherry picked from commit 811b9eef6d08d929af8708adbf2a5effb0eb62d7) (cherry picked from commit f931facd077ce945f1e42eaa3bead208822d3e00) (cherry picked from commit 9ef4ca5ecfed771dab890856130e93ef5ceabef5) Reviewed-by: MÃ¥rten Nordheim Gbp-Pq: Name CVE-2023-51714.diff --- 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 fddb5feca..315f3e234 100644 --- a/src/network/access/http2/hpacktable.cpp +++ b/src/network/access/http2/hpacktable.cpp @@ -40,6 +40,7 @@ #include "hpacktable_p.h" #include +#include #include #include @@ -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::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::max() - 32)) return HeaderSize(); return HeaderSize(true, quint32(sum + 32)); } -- 2.30.2