Qt 6.8.2 + pyside
OBS-URL: https://build.opensuse.org/package/show/KDE:Qt6/qt6-connectivity?expand=0&rev=56
This commit is contained in:
parent
84d9bb7e83
commit
705f1cc024
@ -1,226 +0,0 @@
|
|||||||
From 465e3f3112a9c158aa6dd2f8b9439ae6c2de336f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ivan Solovev <ivan.solovev@qt.io>
|
|
||||||
Date: Thu, 2 Jan 2025 16:48:49 +0100
|
|
||||||
Subject: [PATCH] QLowEnergyControllerPrivateBluez: guard against malformed
|
|
||||||
replies
|
|
||||||
|
|
||||||
The QLowEnergyControllerPrivateBluez::l2cpReadyRead() slot reads the
|
|
||||||
data from a Bluetooth L2CAP socket and then tries to process it
|
|
||||||
according to ATT protocol specs.
|
|
||||||
|
|
||||||
However, the code was missing length and sanity checks at some
|
|
||||||
codepaths in processUnsolicitedReply() and processReply() helper
|
|
||||||
methods, simply relying on the data to be in the proper format.
|
|
||||||
|
|
||||||
This patch adds some minimal checks to make sure that we do not read
|
|
||||||
past the end of the received array and do not divide by zero.
|
|
||||||
|
|
||||||
This problem was originally pointed out by Marc Mutz in an unrelated
|
|
||||||
patch.
|
|
||||||
|
|
||||||
Pick-to: 6.5 5.15
|
|
||||||
Change-Id: I8dcfe031f70ad61fa3d87dc9d771c3fabc6d0edc
|
|
||||||
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
|
|
||||||
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
|
|
||||||
(cherry picked from commit aecbd657c841a2a8c74631ceac96b8ff1f03ab5c)
|
|
||||||
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
|
|
||||||
(cherry picked from commit 53e991671f725c136e9aa824c59ec13934c63fb4)
|
|
||||||
---
|
|
||||||
src/bluetooth/qlowenergycontroller_bluez.cpp | 75 +++++++++++++++++---
|
|
||||||
1 file changed, 66 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/bluetooth/qlowenergycontroller_bluez.cpp b/src/bluetooth/qlowenergycontroller_bluez.cpp
|
|
||||||
index 6f0c9858..2bd0cb68 100644
|
|
||||||
--- a/src/bluetooth/qlowenergycontroller_bluez.cpp
|
|
||||||
+++ b/src/bluetooth/qlowenergycontroller_bluez.cpp
|
|
||||||
@@ -64,14 +64,15 @@ using namespace QBluetooth;
|
|
||||||
|
|
||||||
const int maxPrepareQueueSize = 1024;
|
|
||||||
|
|
||||||
-static void dumpErrorInformation(const QByteArray &response)
|
|
||||||
+/* returns false if the format is incorrect */
|
|
||||||
+static bool dumpErrorInformation(const QByteArray &response)
|
|
||||||
{
|
|
||||||
const char *data = response.constData();
|
|
||||||
if (response.size() != 5
|
|
||||||
|| (static_cast<QBluezConst::AttCommand>(data[0])
|
|
||||||
!= QBluezConst::AttCommand::ATT_OP_ERROR_RESPONSE)) {
|
|
||||||
qCWarning(QT_BT_BLUEZ) << QLatin1String("Not a valid error response");
|
|
||||||
- return;
|
|
||||||
+ return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QBluezConst::AttCommand lastCommand = static_cast<QBluezConst::AttCommand>(data[1]);
|
|
||||||
@@ -126,6 +127,8 @@ static void dumpErrorInformation(const QByteArray &response)
|
|
||||||
|
|
||||||
qCDebug(QT_BT_BLUEZ) << "Error:" << errorCode << "Error description:" << errorString
|
|
||||||
<< "last command:" << lastCommand << "handle:" << handle;
|
|
||||||
+
|
|
||||||
+ return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getUuidSize(const QBluetoothUuid &uuid)
|
|
||||||
@@ -903,6 +906,7 @@ QLowEnergyHandle parseReadByTypeCharDiscovery(
|
|
||||||
{
|
|
||||||
Q_ASSERT(charData);
|
|
||||||
Q_ASSERT(data);
|
|
||||||
+ Q_ASSERT(elementLength >= 5);
|
|
||||||
|
|
||||||
QLowEnergyHandle attributeHandle = bt_get_le16(&data[0]);
|
|
||||||
charData->properties =
|
|
||||||
@@ -912,7 +916,7 @@ QLowEnergyHandle parseReadByTypeCharDiscovery(
|
|
||||||
// Bluetooth LE data comes as little endian
|
|
||||||
if (elementLength == 7) // 16 bit uuid
|
|
||||||
charData->uuid = QBluetoothUuid(bt_get_le16(&data[5]));
|
|
||||||
- else
|
|
||||||
+ else if (elementLength == 21) // 128 bit uuid
|
|
||||||
charData->uuid = QUuid::fromBytes(&data[5], QSysInfo::LittleEndian);
|
|
||||||
|
|
||||||
qCDebug(QT_BT_BLUEZ) << "Found handle:" << Qt::hex << attributeHandle
|
|
||||||
@@ -929,6 +933,7 @@ QLowEnergyHandle parseReadByTypeIncludeDiscovery(
|
|
||||||
{
|
|
||||||
Q_ASSERT(foundServices);
|
|
||||||
Q_ASSERT(data);
|
|
||||||
+ Q_ASSERT(elementLength >= 6);
|
|
||||||
|
|
||||||
QLowEnergyHandle attributeHandle = bt_get_le16(&data[0]);
|
|
||||||
|
|
||||||
@@ -938,9 +943,14 @@ QLowEnergyHandle parseReadByTypeIncludeDiscovery(
|
|
||||||
// data[2] -> included service start handle
|
|
||||||
// data[4] -> included service end handle
|
|
||||||
|
|
||||||
+ // TODO: Spec v. 5.3, Vol. 3, Part G, 4.5.1 mentions that only
|
|
||||||
+ // 16-bit UUID can be returned here. If the UUID is 128-bit,
|
|
||||||
+ // then it is omitted from the response, and should be requested
|
|
||||||
+ // separately with the ATT_READ_REQ command.
|
|
||||||
+
|
|
||||||
if (elementLength == 8) //16 bit uuid
|
|
||||||
foundServices->append(QBluetoothUuid(bt_get_le16(&data[6])));
|
|
||||||
- else
|
|
||||||
+ else if (elementLength == 22) // 128 bit uuid
|
|
||||||
foundServices->append(QUuid::fromBytes(&data[6], QSysInfo::LittleEndian));
|
|
||||||
|
|
||||||
qCDebug(QT_BT_BLUEZ) << "Found included service: " << Qt::hex
|
|
||||||
@@ -949,17 +959,29 @@ QLowEnergyHandle parseReadByTypeIncludeDiscovery(
|
|
||||||
return attributeHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
+Q_DECL_COLD_FUNCTION
|
|
||||||
+static void reportMalformedData(QBluezConst::AttCommand cmd, const QByteArray &response)
|
|
||||||
+{
|
|
||||||
+ qCDebug(QT_BT_BLUEZ, "%s malformed data: %s", qt_getEnumName(cmd),
|
|
||||||
+ response.toHex().constData());
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
void QLowEnergyControllerPrivateBluez::processReply(
|
|
||||||
const Request &request, const QByteArray &response)
|
|
||||||
{
|
|
||||||
Q_Q(QLowEnergyController);
|
|
||||||
|
|
||||||
+ // We already have an isEmpty() check at the only calling site that reads
|
|
||||||
+ // incoming data, so Q_ASSERT is enough.
|
|
||||||
+ Q_ASSERT(!response.isEmpty());
|
|
||||||
+
|
|
||||||
QBluezConst::AttCommand command = static_cast<QBluezConst::AttCommand>(response.constData()[0]);
|
|
||||||
|
|
||||||
bool isErrorResponse = false;
|
|
||||||
// if error occurred 2. byte is previous request type
|
|
||||||
if (command == QBluezConst::AttCommand::ATT_OP_ERROR_RESPONSE) {
|
|
||||||
- dumpErrorInformation(response);
|
|
||||||
+ if (!dumpErrorInformation(response))
|
|
||||||
+ return;
|
|
||||||
command = static_cast<QBluezConst::AttCommand>(response.constData()[1]);
|
|
||||||
isErrorResponse = true;
|
|
||||||
}
|
|
||||||
@@ -972,6 +994,10 @@ void QLowEnergyControllerPrivateBluez::processReply(
|
|
||||||
if (isErrorResponse) {
|
|
||||||
mtuSize = ATT_DEFAULT_LE_MTU;
|
|
||||||
} else {
|
|
||||||
+ if (response.size() < 3) {
|
|
||||||
+ reportMalformedData(command, response);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
const char *data = response.constData();
|
|
||||||
quint16 mtu = bt_get_le16(&data[1]);
|
|
||||||
mtuSize = mtu;
|
|
||||||
@@ -1000,8 +1026,15 @@ void QLowEnergyControllerPrivateBluez::processReply(
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // response[1] == elementLength. According to the spec it should be
|
|
||||||
+ // at least 4 bytes. See Spec v5.3, Vol 3, Part F, 3.4.4.10
|
|
||||||
+ if (response.size() < 2 || response[1] < 4) {
|
|
||||||
+ reportMalformedData(command, response);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
QLowEnergyHandle start = 0, end = 0;
|
|
||||||
- const quint16 elementLength = response.constData()[1];
|
|
||||||
+ const quint16 elementLength = response.constData()[1]; // value checked above
|
|
||||||
const quint16 numElements = (response.size() - 2) / elementLength;
|
|
||||||
quint16 offset = 2;
|
|
||||||
const char *data = response.constData();
|
|
||||||
@@ -1077,16 +1110,25 @@ void QLowEnergyControllerPrivateBluez::processReply(
|
|
||||||
}
|
|
||||||
|
|
||||||
/* packet format:
|
|
||||||
- * if GATT_CHARACTERISTIC discovery
|
|
||||||
+ * if GATT_CHARACTERISTIC discovery (Spec 5.3, Vol. 3, Part G, 4.6)
|
|
||||||
* <opcode><elementLength>
|
|
||||||
* [<handle><property><charHandle><uuid>]+
|
|
||||||
+ * The minimum elementLength is 7 bytes (uuid is always included)
|
|
||||||
*
|
|
||||||
- * if GATT_INCLUDE discovery
|
|
||||||
+ * if GATT_INCLUDE discovery (Spec 5.3, Vol. 3, Part G, 4.5.1)
|
|
||||||
* <opcode><elementLength>
|
|
||||||
* [<handle><startHandle_included><endHandle_included><uuid>]+
|
|
||||||
+ * The minimum elementLength is 6 bytes (uuid can be omitted).
|
|
||||||
*
|
|
||||||
* The uuid can be 16 or 128 bit.
|
|
||||||
*/
|
|
||||||
+
|
|
||||||
+ const quint8 minimumElementLength = attributeType == GATT_CHARACTERISTIC ? 7 : 6;
|
|
||||||
+ if (response.size() < 2 || response[1] < minimumElementLength) {
|
|
||||||
+ reportMalformedData(command, response);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
QLowEnergyHandle lastHandle;
|
|
||||||
const quint16 elementLength = response.constData()[1];
|
|
||||||
const quint16 numElements = (response.size() - 2) / elementLength;
|
|
||||||
@@ -1283,6 +1325,12 @@ void QLowEnergyControllerPrivateBluez::processReply(
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // Spec 5.3, Vol. 3, Part F, 3.4.3.2
|
|
||||||
+ if (response.size() < 6) {
|
|
||||||
+ reportMalformedData(command, response);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
const quint8 format = response[1];
|
|
||||||
quint16 elementLength;
|
|
||||||
switch (format) {
|
|
||||||
@@ -1720,9 +1768,18 @@ void QLowEnergyControllerPrivateBluez::discoverServiceDescriptors(
|
|
||||||
|
|
||||||
void QLowEnergyControllerPrivateBluez::processUnsolicitedReply(const QByteArray &payload)
|
|
||||||
{
|
|
||||||
+ Q_ASSERT(!payload.isEmpty());
|
|
||||||
+
|
|
||||||
const char *data = payload.constData();
|
|
||||||
- bool isNotification = (static_cast<QBluezConst::AttCommand>(data[0])
|
|
||||||
+ const auto command = static_cast<QBluezConst::AttCommand>(data[0]);
|
|
||||||
+ bool isNotification = (command
|
|
||||||
== QBluezConst::AttCommand::ATT_OP_HANDLE_VAL_NOTIFICATION);
|
|
||||||
+
|
|
||||||
+ if (payload.size() < 3) {
|
|
||||||
+ reportMalformedData(command, payload);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
const QLowEnergyHandle changedHandle = bt_get_le16(&data[1]);
|
|
||||||
|
|
||||||
if (QT_BT_BLUEZ().isDebugEnabled()) {
|
|
||||||
--
|
|
||||||
2.48.1
|
|
||||||
|
|
@ -1,3 +1,11 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Jan 31 10:22:53 UTC 2025 - Christophe Marin <christophe@krop.fr>
|
||||||
|
|
||||||
|
- Update to 6.8.2
|
||||||
|
https://www.qt.io/blog/qt-6.8.2-released
|
||||||
|
- Drop patch, merged upstream:
|
||||||
|
* 0001-QLowEnergyControllerPrivateBluez-guard-against-malfo.patch
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Wed Jan 22 16:47:21 UTC 2025 - Antonio Larrosa <alarrosa@suse.com>
|
Wed Jan 22 16:47:21 UTC 2025 - Antonio Larrosa <alarrosa@suse.com>
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
%define real_version 6.8.1
|
%define real_version 6.8.2
|
||||||
%define short_version 6.8
|
%define short_version 6.8
|
||||||
%define tar_name qtconnectivity-everywhere-src
|
%define tar_name qtconnectivity-everywhere-src
|
||||||
%define tar_suffix %{nil}
|
%define tar_suffix %{nil}
|
||||||
@ -27,15 +27,13 @@
|
|||||||
%endif
|
%endif
|
||||||
#
|
#
|
||||||
Name: qt6-connectivity%{?pkg_suffix}
|
Name: qt6-connectivity%{?pkg_suffix}
|
||||||
Version: 6.8.1
|
Version: 6.8.2
|
||||||
Release: 0
|
Release: 0
|
||||||
Summary: Qt 6 connectivity tools and libraries
|
Summary: Qt 6 connectivity tools and libraries
|
||||||
License: GPL-2.0-only OR LGPL-3.0-only OR GPL-3.0-only
|
License: GPL-2.0-only OR LGPL-3.0-only OR GPL-3.0-only
|
||||||
URL: https://www.qt.io
|
URL: https://www.qt.io
|
||||||
Source0: https://download.qt.io/official_releases/qt/%{short_version}/%{real_version}%{tar_suffix}/submodules/%{tar_name}-%{real_version}%{tar_suffix}.tar.xz
|
Source0: https://download.qt.io/official_releases/qt/%{short_version}/%{real_version}%{tar_suffix}/submodules/%{tar_name}-%{real_version}%{tar_suffix}.tar.xz
|
||||||
Source99: qt6-connectivity-rpmlintrc
|
Source99: qt6-connectivity-rpmlintrc
|
||||||
# PATCH-FIX-UPSTREAM
|
|
||||||
Patch0: 0001-QLowEnergyControllerPrivateBluez-guard-against-malfo.patch
|
|
||||||
BuildRequires: pkgconfig
|
BuildRequires: pkgconfig
|
||||||
BuildRequires: qt6-core-private-devel
|
BuildRequires: qt6-core-private-devel
|
||||||
BuildRequires: qt6-network-private-devel
|
BuildRequires: qt6-network-private-devel
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:ccfd46e7ad2290710788274e145fb1f224d8a5ce360764ec10824b5908a6441c
|
|
||||||
size 1067952
|
|
3
qtconnectivity-everywhere-src-6.8.2.tar.xz
Normal file
3
qtconnectivity-everywhere-src-6.8.2.tar.xz
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:e617120e084ac369fd6064f2c177de9e1c2cd9989a1f1774eea131800d52812a
|
||||||
|
size 1069068
|
Loading…
x
Reference in New Issue
Block a user