summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2023-09-20 19:38:25 -0700
committerThiago Macieira <thiago.macieira@intel.com>2023-10-17 19:08:25 -0700
commitde24134aa7795a05ba271a751bf76792f9a3ff98 (patch)
tree50007c95925b466788c2e3c9ed1666ab75353e3b /src/corelib/io
parent1c5575f194656e7b4392f2b18669010a39f5b274 (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.cpp17
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);