diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2023-07-26 16:25:00 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-07-27 08:35:20 +0000 |
commit | ce39c827d9baee3d0c30d4ba61293300de6e8d2e (patch) | |
tree | 7acf5ce2ad608012ab25c897f6814174353c41f0 | |
parent | 655be1471c6f8b289a4e2b7a66bd5af18f6fdc58 (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.cpp | 8 |
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"; |