diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2023-09-20 19:38:25 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2023-10-17 19:08:25 -0700 |
commit | de24134aa7795a05ba271a751bf76792f9a3ff98 (patch) | |
tree | 50007c95925b466788c2e3c9ed1666ab75353e3b /src/corelib/io | |
parent | 1c5575f194656e7b4392f2b18669010a39f5b274 (diff) |
moveToTrash/Unix: avoid TOCTOU in creating the unique file name
This is not a security issue because we still use QIODevice::NewOnly
(O_EXCL) and loop again. But because we do so, we don't need to check
for existence with QFile::exists() in the first place.
Pick-to: 6.6
Change-Id: I9d43e5b91eb142d6945cfffd1786c98a39781517
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qfilesystemengine_unix.cpp | 17 |
1 files changed, 6 insertions, 11 deletions
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 950939597a..582d48ef8d 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -1338,14 +1338,9 @@ bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source, */ QString uniqueTrashedName = u'/' + sourcePath.fileName(); QString infoFileName; - int counter = 0; QFile infoFile; - auto makeUniqueTrashedName = [sourcePath, &counter]() -> QString { - return QString::asprintf("/%ls-%04d", qUtf16Printable(sourcePath.fileName()), ++counter); - }; - do { - while (QFile::exists(trashDir.filePath(filesDir) + uniqueTrashedName)) - uniqueTrashedName = makeUniqueTrashedName(); + auto openMode = QIODevice::NewOnly | QIODevice::WriteOnly | QIODevice::Text; + for (int counter = 0; !infoFile.open(openMode); ++counter) { /* "The $trash/info directory contains an "information file" for every file and directory in $trash/files. This file MUST have exactly the same name as the file or directory in @@ -1358,12 +1353,12 @@ bool QFileSystemEngine::moveFileToTrash(const QFileSystemEntry &source, filename, and then opening with O_EXCL. If that succeeds the creation was atomic (at least on the same machine), if it fails you need to pick another filename." */ - infoFileName = trashDir.filePath(infoDir) + uniqueTrashedName = QString::asprintf("/%ls-%04d", qUtf16Printable(sourcePath.fileName()), + counter); + QString infoFileName = trashDir.filePath(infoDir) + uniqueTrashedName + ".trashinfo"_L1; infoFile.setFileName(infoFileName); - if (!infoFile.open(QIODevice::NewOnly | QIODevice::WriteOnly | QIODevice::Text)) - uniqueTrashedName = makeUniqueTrashedName(); - } while (!infoFile.isOpen()); + } QString pathForInfo = sourcePath.filePath(); const QStorageInfo storageInfo(pathForInfo); |