QFuture: fix continuation cleanup
Not clearing the continuationData could lead to use-after-free when there is an attempt to cancel an already finished future, which belongs to an already-destroyed promise. This patch fixes it be explicitly resetting continuationData to nullptr in the clearContinuation() method, which is called from the QPromise destructor. Task-number: QTBUG-103514 Change-Id: I6418b3f5ad04f2fdc13a196ae208009eaa5de367 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> (cherry picked from commit b34bea5e96370986ea5dfc499fc2ec6366fda627) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
390ce392c8
commit
dba4d78441
@ -847,6 +847,7 @@ void QFutureInterfaceBase::cleanContinuation()
|
||||
QMutexLocker lock(&d->continuationMutex);
|
||||
d->continuation = nullptr;
|
||||
d->continuationState = QFutureInterfaceBasePrivate::Cleaned;
|
||||
d->continuationData = nullptr;
|
||||
}
|
||||
|
||||
void QFutureInterfaceBase::runContinuation() const
|
||||
|
@ -221,6 +221,7 @@ private slots:
|
||||
void whenAnyDifferentTypesWithFailed();
|
||||
|
||||
void continuationsDontLeak();
|
||||
void cancelAfterFinishWithContinuations();
|
||||
|
||||
void unwrap();
|
||||
|
||||
@ -4721,6 +4722,31 @@ void tst_QFuture::continuationsDontLeak()
|
||||
QCOMPARE(InstanceCounter::count, 0);
|
||||
}
|
||||
|
||||
// This test checks that we do not get use-after-free
|
||||
void tst_QFuture::cancelAfterFinishWithContinuations()
|
||||
{
|
||||
QFuture<void> future;
|
||||
bool continuationIsRun = false;
|
||||
bool cancelCalled = false;
|
||||
{
|
||||
QPromise<void> promise;
|
||||
future = promise.future();
|
||||
|
||||
future.then([&continuationIsRun]() {
|
||||
continuationIsRun = true;
|
||||
}).onCanceled([&cancelCalled]() {
|
||||
cancelCalled = true;
|
||||
});
|
||||
|
||||
promise.start();
|
||||
promise.finish();
|
||||
}
|
||||
|
||||
QVERIFY(continuationIsRun);
|
||||
future.cancel();
|
||||
QVERIFY(!cancelCalled);
|
||||
}
|
||||
|
||||
void tst_QFuture::unwrap()
|
||||
{
|
||||
// The nested future succeeds
|
||||
|
Loading…
x
Reference in New Issue
Block a user