summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2023-07-26 16:25:00 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-07-27 08:35:20 +0000
commitce39c827d9baee3d0c30d4ba61293300de6e8d2e (patch)
tree7acf5ce2ad608012ab25c897f6814174353c41f0
parent655be1471c6f8b289a4e2b7a66bd5af18f6fdc58 (diff)
GeoClue2 plugin: fix potential heap-use-after-free errors
The error can be observed if we try to switch the backend when processing the errorOccurred() signal from geoclue2 backend. The error was triggered by the following scenario: * start an application using geoclue2 plugin * try to start monitoring without the proper geoclue2 configuration * this calls QGeoPositionInfoSourceGeoclue2::startClient(), where m_client->Start() returns a reply with an error. As a result, the errorOccurred() signal is emitted. * the application handles this signal, and switches the backend. This leads to the QGeoPositionInfoSourceGeoclue2 instance being removed. * after the signal is processed we return to the lambda and try to delete m_client -> error, as m_client was already deleted. Fix it by deleting m_client before emitting the signal. Once that was fixed, a similar error occurred for the scopedWatcher. The reason is similar - the pointer which is stored in the scopedWatcher was already deleted when QGeoPositionInfoSourceGeoclue2 d-tor was called, and after that it was used again in the scopedWatcher's deleter. Fix it by explicitly resetting the scopedWatcher before emitting the errorOccurred() signal. Change-Id: I2659cac406542398f0d1f843efe9f22a5f1e5cc3 Reviewed-by: Alex Blasche <alexander.blasche@qt.io> (cherry picked from commit 03a37f36b9d967205ec70c49ad21e438df362936) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp8
1 files changed, 5 insertions, 3 deletions
diff --git a/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp b/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp
index 737d62d0..222a6399 100644
--- a/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp
+++ b/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp
@@ -266,15 +266,17 @@ void QGeoPositionInfoSourceGeoclue2::startClient()
const auto watcher = new QDBusPendingCallWatcher(reply, this);
connect(watcher, &QDBusPendingCallWatcher::finished,
[this](QDBusPendingCallWatcher *watcher) {
- const QScopedPointer<QDBusPendingCallWatcher, QScopedPointerDeleteLater>
- scopedWatcher(watcher);
+ QScopedPointer<QDBusPendingCallWatcher, QScopedPointerDeleteLater> scopedWatcher(watcher);
const QDBusPendingReply<> reply = *scopedWatcher;
if (reply.isError()) {
const auto error = reply.error();
qCCritical(lcPositioningGeoclue2) << "Unable to start the client:"
<< error.name() << error.message();
- setError(AccessError);
delete m_client;
+ scopedWatcher.reset();
+ // This can potentially lead to calling ~QGeoPositionInfoSourceGeoclue2(),
+ // so do all the cleanup before.
+ setError(AccessError);
} else {
qCDebug(lcPositioningGeoclue2) << "Client successfully started";