From 7ca66b1e66e73a0cb35705df04507ef9f3440cab Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 9 Dec 2016 16:53:30 -0800 Subject: Fix race condition in QFactoryLoader: lock the mutex we already have The process of loading a plugin is examplified by the qLoadPlugin function (though not all users of QFactoryLoader use this function, they all do something similar): const int index = loader->indexOf(key); if (index != -1) { QObject *factoryObject = loader->instance(index); if (FactoryInterface *factory = qobject_cast(factoryObject)) if (PluginInterface *result = factory->create(key, std::forward(args)...)) return result; } QFactoryLoader::indexOf already locked the mutex, but not QFactoryLoader::instance. This commit fixes that. Note that calling the virtual create() in the plugin's factory is not protected by the mutex. Each plugin's factory must be thread-safe and also create an object that works on any thread too. It's also the responsibility of the caller of qLoadPlugin to ensure that it's called thread-safely. Task-number: QTBUG-42855 Change-Id: I63e21df51c7448bc8b5ffffd148ebee33d4c47de Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Marc Mutz --- src/corelib/plugin/qfactoryloader.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/corelib/plugin') diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index c09dc6c22b..b8e18cc9a8 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -282,6 +282,7 @@ QObject *QFactoryLoader::instance(int index) const return 0; #ifndef QT_NO_LIBRARY + QMutexLocker lock(&d->mutex); if (index < d->libraryList.size()) { QLibraryPrivate *library = d->libraryList.at(index); if (library->instance || library->loadPlugin()) { @@ -297,6 +298,7 @@ QObject *QFactoryLoader::instance(int index) const return 0; } index -= d->libraryList.size(); + lock.unlock(); #endif QVector staticPlugins = QPluginLoader::staticPlugins(); -- cgit v1.2.3