Bug 1781116 - QuotaManager needs to deal with SQLite path canonicalization/symlink piercing; r=asuth,dom-storage-reviewers

Depends on D171440

Differential Revision: https://phabricator.services.mozilla.com/D171869
This commit is contained in:
Jan Varga 2023-03-07 15:56:51 +00:00
Родитель 1866e770fd
Коммит c0343f9fe5
2 изменённых файлов: 65 добавлений и 2 удалений

Просмотреть файл

@ -3415,7 +3415,7 @@
value: false
mirror: always
#ifdef XP_WIN
#if defined(XP_WIN)
# Preference that is used to set nsILocalFileWin::useDOSDevicePathSyntax
# attribute for all local file instances created by QuotaManager and its
# clients. The value of this preference is cached so changing the preference
@ -3433,6 +3433,13 @@
type: RelaxedAtomicBool
value: true
mirror: always
#elif defined(XP_UNIX)
# Preference that is used to enable the overriding of Unix xFullPathname
# implementation in QuotaVFS.
- name: dom.quotaManager.overrideXFullPathnameUnix
type: RelaxedAtomicBool
value: true
mirror: always
#endif
# How many times we should retry directory removal or renaming if access was

Просмотреть файл

@ -8,10 +8,12 @@
#include "mozilla/dom/quota/PersistenceType.h"
#include "mozilla/dom/quota/QuotaManager.h"
#include "mozilla/dom/quota/QuotaObject.h"
#include "mozilla/dom/quota/ResultExtensions.h"
#include "nsDirectoryServiceDefs.h"
#include "nsEscape.h"
#include "mozilla/StaticPrefs_storage.h"
#ifdef XP_WIN
#if defined(XP_WIN) || defined(XP_UNIX)
# include "mozilla/StaticPrefs_dom.h"
#endif
@ -428,6 +430,60 @@ int QuotaFullPathname(sqlite3_vfs* vfs, const char* zName, int nOut,
}
zOut[index] = '\0';
return SQLITE_OK;
}
#elif defined(XP_UNIX)
// SQLite canonicalizes (resolves path components) file paths on Unix which
// doesn't work well with file path sanity checks in quota manager. This is
// especially a problem on mac where /var is a symlink to /private/var.
// Since QuotaVFS is used only by quota clients which never access databases
// outside of PROFILE/storage, we override Unix xFullPathname with own
// implementation that doesn't do any canonicalization.
if (StaticPrefs::dom_quotaManager_overrideXFullPathnameUnix()) {
if (nOut < 0) {
// Match the return code used by SQLite's xFullPathname implementation
// here and below.
return SQLITE_CANTOPEN;
}
QM_TRY_INSPECT(
const auto& path, ([&zName]() -> Result<nsString, nsresult> {
NS_ConvertUTF8toUTF16 name(zName);
if (name.First() == '/') {
return name;
}
QM_TRY_INSPECT(const auto& file,
MOZ_TO_RESULT_INVOKE_TYPED(nsCOMPtr<nsIFile>,
NS_GetSpecialDirectory,
NS_OS_CURRENT_WORKING_DIR));
QM_TRY(MOZ_TO_RESULT(file->Append(name)));
QM_TRY_RETURN(
MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(nsString, file, GetPath));
}()),
SQLITE_CANTOPEN);
QM_TRY_INSPECT(const auto& quotaFile, QM_NewLocalFile(path),
SQLITE_CANTOPEN);
QM_TRY_INSPECT(
const auto& quotaPath,
MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(nsString, quotaFile, GetPath),
SQLITE_CANTOPEN);
NS_ConvertUTF16toUTF8 sqlitePath(quotaPath);
if (sqlitePath.Length() > (unsigned int)nOut) {
return SQLITE_CANTOPEN;
}
nsCharTraits<char>::copy(zOut, sqlitePath.get(), sqlitePath.Length());
zOut[sqlitePath.Length()] = '\0';
return SQLITE_OK;
}
#endif