diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2018-06-28 18:36:36 -0700 |
---|---|---|
committer | Mårten Nordheim <marten.nordheim@qt.io> | 2018-07-25 12:40:04 +0000 |
commit | 9a04453b50ea22d6060aeb49250cf3e263d86ad3 (patch) | |
tree | c394218aa7a1aecabd5272725d5cef8b81df46d9 /src | |
parent | fdb780b897fc2964dc70c286ee3102d7ce6327ea (diff) |
Fix the fix for mmap() overflow check
The code I introduced in 4ee74257940e2ed21b653b986ad02a746e8438a6 only
dealt with systems that reasonably used a 64-bit off_t parameter. Turns
out that we don't turn on largefile support on 32-bit Android, which
meant that the fix caused a regression.
[ChangeLog][QtCore][QFile] Fixed a regression that caused QFile::map()
to succeed or produce incorrect results when trying to map a file at an
offset beyond 4 GB on 32-bit Android systems and on some special Linux
configurations.
Task-number: QTBUG-69148
Change-Id: I2c133120577fa12a32d444488bac3e341966f8d7
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/io/qfsfileengine_unix.cpp | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index bc39ea73ee..bbd262e2f9 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -634,6 +634,7 @@ bool QFSFileEngine::setFileTime(const QDateTime &newDate, FileTime time) uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags) { + qint64 maxFileOffset = std::numeric_limits<QT_OFF_T>::max(); #if (defined(Q_OS_LINUX) || defined(Q_OS_ANDROID)) && Q_PROCESSOR_WORDSIZE == 4 // The Linux mmap2 system call on 32-bit takes a page-shifted 32-bit // integer so the maximum offset is 1 << (32+12) (the shift is always 12, @@ -642,9 +643,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla // and Bionic): all of them do the right shift, but don't confirm that the // result fits into the 32-bit parameter to the kernel. - static qint64 MaxFileOffset = (Q_INT64_C(1) << (32+12)) - 1; -#else - static qint64 MaxFileOffset = std::numeric_limits<QT_OFF_T>::max(); + maxFileOffset = qMin((Q_INT64_C(1) << (32+12)) - 1, maxFileOffset); #endif Q_Q(QFSFileEngine); @@ -653,7 +652,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla return 0; } - if (offset < 0 || offset > MaxFileOffset + if (offset < 0 || offset > maxFileOffset || size < 0 || quint64(size) > quint64(size_t(-1))) { q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL))); return 0; |