diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2017-02-14 17:43:35 +0100 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2017-02-15 11:24:18 +0000 |
commit | af8771867c3bca9b1bc34d6d82b6603749938d22 (patch) | |
tree | 0e24f62052b0663b5ee7c008055da85acdb6ab8c | |
parent | 39820cf8c38f527e178913192d428085af4327b4 (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 <bogdan@kdab.com>
-rw-r--r-- | src/corelib/kernel/qjnihelpers.cpp | 6 |
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; sem->release(); }, 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) |