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>
This commit is contained in:
Marc Mutz 2017-02-14 17:43:35 +01:00
parent 39820cf8c3
commit af8771867c

View File

@ -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)