summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorLouai Al-Khanji <louai.al-khanji@theqtcompany.com>2015-09-21 15:39:16 +0300
committerLouai Al-Khanji <louai.al-khanji@theqtcompany.com>2015-09-30 05:35:16 +0000
commitac0184d6085d9e4f7f59352e563055311f4d8792 (patch)
treeba5b41d3faf5c01402136a1d567cb2ed7722660a /src/corelib/kernel
parent813f468a14fb84af43c1f8fc0a1430277358eba2 (diff)
Add qt_safe_ftok wrapper for ftok
The ftok function unfortunately can return duplicate keys even for different files if the same project id is used. This is discussed e.g. in Stevens' "Advanced Programming in the UNIX Environment". We want the key to be predictable so we cannot just pass a random number as the project id. To reduce the propability of key collisions we hash the file name with the project number as seed for a predictable value. This is the same approach taken e.g. by Apache, but the real fix is to move away from System V IPC completely once this is feasible on our supported platforms. Task-number: QTBUG-48375 Change-Id: If1a57f215f7ddd147aa38919907cfb83db07aea0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qcore_unix_p.h14
-rw-r--r--src/corelib/kernel/qsharedmemory_systemv.cpp2
-rw-r--r--src/corelib/kernel/qsystemsemaphore_systemv.cpp2
3 files changed, 16 insertions, 2 deletions
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index c744873fce..f80dcb5a50 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -47,6 +47,7 @@
#include "qplatformdefs.h"
#include "qatomic.h"
+#include "qhash.h"
#ifndef Q_OS_UNIX
# error "qcore_unix_p.h included on a non-Unix system"
@@ -322,6 +323,19 @@ union qt_semun {
unsigned short *array; /* array for GETALL, SETALL */
};
+#ifndef QT_POSIX_IPC
+#ifndef QT_NO_SHAREDMEMORY
+#ifndef Q_OS_ANDROID
+static inline key_t qt_safe_ftok(const QByteArray &filename, int proj_id)
+{
+ // Unfortunately ftok can return colliding keys even for different files.
+ // Try to add some more entropy via qHash.
+ return ::ftok(filename.constData(), qHash(filename, proj_id));
+}
+#endif // !Q_OS_ANDROID
+#endif // !QT_NO_SHAREDMEMORY
+#endif // !QT_POSIX_IPC
+
QT_END_NAMESPACE
#endif
diff --git a/src/corelib/kernel/qsharedmemory_systemv.cpp b/src/corelib/kernel/qsharedmemory_systemv.cpp
index 29fee12c0b..0d2eea49e9 100644
--- a/src/corelib/kernel/qsharedmemory_systemv.cpp
+++ b/src/corelib/kernel/qsharedmemory_systemv.cpp
@@ -82,7 +82,7 @@ key_t QSharedMemoryPrivate::handle()
return 0;
}
- unix_key = ftok(QFile::encodeName(nativeKey).constData(), 'Q');
+ unix_key = qt_safe_ftok(QFile::encodeName(nativeKey), 'Q');
if (-1 == unix_key) {
errorString = QSharedMemory::tr("%1: ftok failed").arg(QLatin1String("QSharedMemory::handle:"));
error = QSharedMemory::KeyError;
diff --git a/src/corelib/kernel/qsystemsemaphore_systemv.cpp b/src/corelib/kernel/qsystemsemaphore_systemv.cpp
index 32a4bdef51..490de5f9ee 100644
--- a/src/corelib/kernel/qsystemsemaphore_systemv.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_systemv.cpp
@@ -85,7 +85,7 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
createdFile = (1 == built);
// Get the unix key for the created file
- unix_key = ftok(QFile::encodeName(fileName).constData(), 'Q');
+ unix_key = qt_safe_ftok(QFile::encodeName(fileName), 'Q');
if (-1 == unix_key) {
errorString = QCoreApplication::tr("%1: ftok failed", "QSystemSemaphore").arg(QLatin1String("QSystemSemaphore::handle:"));
error = QSystemSemaphore::KeyError;