Skip to content

Commit

Permalink
QStandardPaths: Don't change permissions of XDG_RUNTIME_DIR
Browse files Browse the repository at this point in the history
Conform to the XDG Base Directory Specification:
"If, when attempting to write a file, the destination directory
is non-existent an attempt should be made to create it with
permission 0700. If the destination directory exists already
the permissions should not be changed."

At the same time the spec states about XDG_RUNTIME_DIR that
"its Unix access mode MUST be 0700", so don't consider the
directory with wrong permissions correct and use a fallback.

Task-number: QTBUG-68338
Pick-to: 5.15 5.12
Change-Id: I03c6b35b3f7d5ceb8e6326695bfc8207da92ea67
Reviewed-by: Thiago Macieira <[email protected]>
Reviewed-by: David Faure <[email protected]>
  • Loading branch information
avolkov-astra committed Nov 30, 2020
1 parent d27d2b5 commit 68de00e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 30 deletions.
59 changes: 30 additions & 29 deletions src/corelib/io/qstandardpaths_unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,30 @@ static QLatin1String xdg_key_name(QStandardPaths::StandardLocation type)
}
#endif

static QByteArray unixPermissionsText(QFile::Permissions permissions)
{
mode_t perms = 0;
if (permissions & QFile::ReadOwner)
perms |= S_IRUSR;
if (permissions & QFile::WriteOwner)
perms |= S_IWUSR;
if (permissions & QFile::ExeOwner)
perms |= S_IXUSR;
if (permissions & QFile::ReadGroup)
perms |= S_IRGRP;
if (permissions & QFile::WriteGroup)
perms |= S_IWGRP;
if (permissions & QFile::ExeGroup)
perms |= S_IXGRP;
if (permissions & QFile::ReadOther)
perms |= S_IROTH;
if (permissions & QFile::WriteOther)
perms |= S_IWOTH;
if (permissions & QFile::ExeOther)
perms |= S_IXOTH;
return '0' + QByteArray::number(perms, 8);
}

static bool checkXdgRuntimeDir(const QString &xdgRuntimeDir)
{
auto describeMetaData = [](const QFileSystemMetaData &metaData) -> QByteArray {
Expand All @@ -113,27 +137,7 @@ static bool checkXdgRuntimeDir(const QString &xdgRuntimeDir)
else
description += "a block device";

// convert QFileSystemMetaData permissions back to Unix
mode_t perms = 0;
if (metaData.permissions() & QFile::ReadOwner)
perms |= S_IRUSR;
if (metaData.permissions() & QFile::WriteOwner)
perms |= S_IWUSR;
if (metaData.permissions() & QFile::ExeOwner)
perms |= S_IXUSR;
if (metaData.permissions() & QFile::ReadGroup)
perms |= S_IRGRP;
if (metaData.permissions() & QFile::WriteGroup)
perms |= S_IWGRP;
if (metaData.permissions() & QFile::ExeGroup)
perms |= S_IXGRP;
if (metaData.permissions() & QFile::ReadOther)
perms |= S_IROTH;
if (metaData.permissions() & QFile::WriteOther)
perms |= S_IWOTH;
if (metaData.permissions() & QFile::ExeOther)
perms |= S_IXOTH;
description += " permissions 0" + QByteArray::number(perms, 8);
description += " permissions " + unixPermissionsText(metaData.permissions());

return description
+ " owned by UID " + QByteArray::number(metaData.userId())
Expand Down Expand Up @@ -186,14 +190,11 @@ static bool checkXdgRuntimeDir(const QString &xdgRuntimeDir)

// "and he MUST be the only one having read and write access to it. Its Unix access mode MUST be 0700."
if (metaData.permissions() != wantedPerms) {
// attempt to correct:
QSystemError error;
if (!QFileSystemEngine::setPermissions(entry, wantedPerms, error)) {
qErrnoWarning("QStandardPaths: could not set correct permissions on runtime directory "
"'%ls', which is %s", qUtf16Printable(xdgRuntimeDir),
describeMetaData(metaData).constData());
return false;
}
qWarning("QStandardPaths: wrong permissions on runtime directory %ls, %s instead of %s",
qUtf16Printable(xdgRuntimeDir),
unixPermissionsText(metaData.permissions()).constData(),
unixPermissionsText(wantedPerms).constData());
return false;
}

return true;
Expand Down
8 changes: 7 additions & 1 deletion tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,12 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data()
d.mkdir("runtime");
QFile::setPermissions(p, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner |
QFile::ExeGroup | QFile::ExeOther);
return updateRuntimeDir(p);
updateRuntimeDir(p);
QTest::ignoreMessage(QtWarningMsg,
QString("QStandardPaths: wrong permissions on runtime directory %1, "
"0711 instead of 0700")
.arg(p).toLatin1());
return fallbackXdgRuntimeDir();
});

addRow("environment:wrong-owner", [](QDir &) {
Expand Down Expand Up @@ -593,6 +598,7 @@ void tst_qstandardpaths::testCustomRuntimeDirectory_data()
clearRuntimeDir();
QString p = fallbackXdgRuntimeDir();
d.mkdir(p); // probably has wrong permissions
QFile::setPermissions(p, QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner);
return p;
});

Expand Down

0 comments on commit 68de00e

Please sign in to comment.