path: root/src/corelib/kernel/qjnihelpers.cpp
diff options
authorMarc Mutz <>2017-02-14 17:43:35 +0100
committerMarc Mutz <>2017-02-15 11:24:18 +0000
commitaf8771867c3bca9b1bc34d6d82b6603749938d22 (patch)
tree0e24f62052b0663b5ee7c008055da85acdb6ab8c /src/corelib/kernel/qjnihelpers.cpp
parent39820cf8c38f527e178913192d428085af4327b4 (diff)
Fix UB (data race) in QtAndroidPrivate::requestPermissionsSync()
If the QSemaphore::tryAcquire() call times out, we mustn't touch *res, because there was no happens-before relation established between *res = result in the lambda and our returning *res; Fix by returning a default-constructed hash in that case. Add a strategic std::move(). The same problem exists in runOnAndroidThreadSync(), but I have no idea how to solve it, because there the shared object is the runnable itself. Change-Id: I9a2c431144c169fbd545763555d96153143a11bf Reviewed-by: BogDan Vatra <>
Diffstat (limited to 'src/corelib/kernel/qjnihelpers.cpp')
1 files changed, 4 insertions, 2 deletions
diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp
index 028fb1256e..58912aa261 100644
--- a/src/corelib/kernel/qjnihelpers.cpp
+++ b/src/corelib/kernel/qjnihelpers.cpp
@@ -506,8 +506,10 @@ QHash<QString, QtAndroidPrivate::PermissionsResult> QtAndroidPrivate::requestPer
*res = result;
}, true);
- sem->tryAcquire(1, timeoutMs);
- return *res;
+ if (sem->tryAcquire(1, timeoutMs))
+ return std::move(*res);
+ else // mustn't touch *res
+ return QHash<QString, QtAndroidPrivate::PermissionsResult>();
QtAndroidPrivate::PermissionsResult QtAndroidPrivate::checkPermission(const QString &permission)