QSharedMemory: fix semaphore creation in legacy mode

The legacy mode was using the new nativeKey to create a semaphore.
As a result, on macOS the name of the semaphore key file was the same
as the name of the shared memory key file.
This lead to a situation when the file was mistakenly deleted when
destroying any instance of the shared memory, not only the one that
created it.
Fix it by using QSystemSemaphore::legacyNativeKey() in legacy mode.

Add a test to verify that we cannot re-create a shared memory with the
same key. The test was failing on macOS without the fix.

Fixes: QTBUG-111855
Pick-to: 6.6
Change-Id: Ib0bc41791e889b1888bbb8aa9044c6b053b63a5a
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Ivan Solovev 2023-11-02 14:36:02 +01:00
parent 742f45f7cf
commit 02c42b26e1
2 changed files with 31 additions and 1 deletions

View File

@ -258,7 +258,11 @@ bool QSharedMemoryPrivate::initKey(SemaphoreAccessMode mode)
if (!cleanHandle())
return false;
#if QT_CONFIG(systemsemaphore)
systemSemaphore.setNativeKey(semaphoreNativeKey(), 1, mode);
const QString legacyKey = QNativeIpcKeyPrivate::legacyKey(nativeKey);
const QNativeIpcKey semKey = legacyKey.isEmpty()
? semaphoreNativeKey()
: QSystemSemaphore::legacyNativeKey(legacyKey, nativeKey.type());
systemSemaphore.setNativeKey(semKey, 1, mode);
if (systemSemaphore.error() != QSystemSemaphore::NoError) {
QString function = "QSharedMemoryPrivate::initKey"_L1;
errorString = QSharedMemory::tr("%1: unable to set key on lock (%2)")

View File

@ -78,6 +78,9 @@ private slots:
void uniqueKey_data();
void uniqueKey();
// legacy
void createWithSameKey();
protected:
void remove(const QNativeIpcKey &key);
@ -899,6 +902,29 @@ void tst_QSharedMemory::uniqueKey()
QCOMPARE(nativeEqual, setEqual);
}
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
void tst_QSharedMemory::createWithSameKey()
{
const QString key = u"legacy_key"_s;
const qsizetype sz = 100;
QSharedMemory mem1(key);
QVERIFY(mem1.create(sz));
{
QSharedMemory mem2(key);
QVERIFY(!mem2.create(sz));
QVERIFY(mem2.attach());
}
// and the second create() should fail as well, QTBUG-111855
{
QSharedMemory mem2(key);
QVERIFY(!mem2.create(sz));
QVERIFY(mem2.attach());
}
}
QT_WARNING_POP
QTEST_MAIN(tst_QSharedMemory)
#include "tst_qsharedmemory.moc"