From b9a721eaaa345a9311d9e1993f6fdfda2b1eb5f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Wed, 17 Feb 2021 09:54:48 +0100 Subject: [PATCH] QNetworkInformation: Revise locking during creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Potential issue caught by the MÃ¥rten static analyzer. In case another thread somehow ended up creating and returning an instance while another was waiting to relock it would deallocate the previous instance, which could lead to some bad situations. Change-Id: I6e1843f8a483b2c3e0540e998c383e41f59c8655 Reviewed-by: Timur Pocheptsov (cherry picked from commit c98e92b8ca7fd295482ee99f095c220b6f389169) Reviewed-by: Qt Cherry-pick Bot --- src/network/kernel/qnetworkinformation.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/network/kernel/qnetworkinformation.cpp b/src/network/kernel/qnetworkinformation.cpp index 9696a4fcc23..d10024bf05e 100644 --- a/src/network/kernel/qnetworkinformation.cpp +++ b/src/network/kernel/qnetworkinformation.cpp @@ -168,22 +168,21 @@ QNetworkInformation *QNetworkInformationPrivate::create(QStringView name) { if (!dataHolder()) return nullptr; - QMutexLocker locker(&dataHolder->instanceMutex); #ifdef DEBUG_LOADING qDebug().nospace() << "create() called with name=\"" << name << "\". instanceHolder initialized? " << !!dataHolder->instanceHolder; #endif - if (dataHolder->instanceHolder) - return dataHolder->instanceHolder.get(); - - locker.unlock(); if (!initializeList()) { #ifdef DEBUG_LOADING qDebug("Failed to initialize list, returning."); #endif return nullptr; } - locker.relock(); + + QMutexLocker locker(&dataHolder->instanceMutex); + if (dataHolder->instanceHolder) + return dataHolder->instanceHolder.get(); + QNetworkInformationBackend *backend = nullptr; if (!name.isEmpty()) { @@ -231,24 +230,22 @@ QNetworkInformation *QNetworkInformationPrivate::create(QNetworkInformation::Fea { if (!dataHolder()) return nullptr; - QMutexLocker locker(&dataHolder->instanceMutex); #ifdef DEBUG_LOADING qDebug().nospace() << "create() called with features=\"" << features << "\". instanceHolder initialized? " << !!dataHolder->instanceHolder; #endif - if (dataHolder->instanceHolder) - return dataHolder->instanceHolder.get(); if (features == 0) return nullptr; - locker.unlock(); if (!initializeList()) { #ifdef DEBUG_LOADING qDebug("Failed to initialize list, returning."); #endif return nullptr; } - locker.relock(); + QMutexLocker locker(&dataHolder->instanceMutex); + if (dataHolder->instanceHolder) + return dataHolder->instanceHolder.get(); const auto supportsRequestedFeatures = [features](QNetworkInformationBackendFactory *factory) { return factory && (factory->featuresSupported() & features) == features;