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. Change-Id: I9d43e5b91eb142d6945cfffd1786c98a39781517 (cherry picked from commit de24134aa7795a05ba271a751bf76792f9a3ff98) Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
This commit is contained in:
parent
4aba04d2ca
commit
28064908e0
@ -1329,14 +1329,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
|
||||
@ -1349,12 +1344,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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user