Firefox · DOM
CVE-2026-117878
Logic Error in DOM
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
VersionChangeOpdom/indexedDB/ActorsParent.cpp |
modified | |
ifdom/indexedDB/ActorsParent.cpp |
modified |
Files Changed
dom/indexedDB/ActorsParent.cpp
Patch
diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp
index 05f7d8a0b0c..08d64cf16b6 100644
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -3068,6 +3068,7 @@ class FactoryOp : public DatabaseOperationBase,
Maybe<nsString> mDatabaseName;
Maybe<nsCString> mDatabaseId;
Maybe<nsString> mDatabaseFilePath;
+ Maybe<nsString> mDatabaseFilenameBase;
int64_t mDirectoryLockId;
const PersistenceType mPersistenceType;
State mState;
@@ -3180,6 +3181,9 @@ class FactoryOp : public DatabaseOperationBase,
virtual void SendBlockedNotification() = 0;
private:
+ static nsAutoString GetDatabaseFilenameBase(const nsAString& aDatabaseName,
+ bool aIsPrivate);
+
// Test whether this FactoryOp needs to wait for the given op.
bool MustWaitFor(const FactoryOp& aExistingOp);
@@ -3336,7 +3340,6 @@ class DeleteDatabaseOp final : public FactoryRequestOp {
class VersionChangeOp;
nsString mDatabaseDirectoryPath;
- nsString mDatabaseFilenameBase;
uint64_t mPreviousVersion;
public:
@@ -6198,54 +6201,6 @@ uint32_t TelemetryIdForFile(nsIFile* aFile) {
});
}
-nsAutoString GetDatabaseFilenameBase(const nsAString& aDatabaseName,
- bool aIsPrivate) {
- nsAutoString databaseFilenameBase;
-
- if (aIsPrivate) {
- MOZ_DIAGNOSTIC_ASSERT(gStorageDatabaseNameMutex);
-
- MutexAutoLock lock(*gStorageDatabaseNameMutex);
-
- if (!gStorageDatabaseNameHashtable) {
- gStorageDatabaseNameHashtable = new StorageDatabaseNameHashtable();
- }
-
- databaseFilenameBase.Append(
- gStorageDatabaseNameHashtable->LookupOrInsertWith(aDatabaseName, []() {
- return NSID_TrimBracketsUTF16(nsID::GenerateUUID());
- }));
-
- return databaseFilenameBase;
- }
-
- // WARNING: do not change this hash function. See the comment in HashName()
- // for details.
- databaseFilenameBase.AppendInt(HashName(aDatabaseName));
-
- nsAutoCString escapedName;
- if (!NS_Escape(NS_ConvertUTF16toUTF8(aDatabaseName), escapedName,
- url_XPAlphas)) {
- MOZ_CRASH("Can't escape database name!");
- }
-
- const char* forwardIter = escapedName.BeginReading();
- const char* backwardIter = escapedName.EndReading() - 1;
-
- nsAutoCString substring;
- while (forwardIter <= backwardIter && substring.Length() < 21) {
- if (substring.Length() % 2) {
- substring.Append(*backwardIter--);
- } else {
- substring.Append(*forwardIter++);
- }
- }
-
- databaseFilenameBase.AppendASCII(substring.get(), substring.Length());
-
- return databaseFilenameBase;
-}
-
const CommonIndexOpenCursorParams& GetCommonIndexOpenCursorParams(
const OpenCursorParams& aParams) {
switch (aParams.type()) {
@@ -15159,14 +15114,15 @@ nsresult FactoryOp::Open() {
}
if (mDatabaseName.isSome()) {
+ mDatabaseFilenameBase = Some(GetDatabaseFilenameBase(
+ mDatabaseName.ref(), mOriginMetadata.mIsPrivate));
nsCString databaseId;
QuotaManager::GetStorageId(mPersistenceType, mOriginMetadata.mOrigin,
Client::IDB, databaseId);
databaseId.Append('*');
- databaseId.Append(NS_ConvertUTF16toUTF8(GetDatabaseFilenameBase(
- mDatabaseName.ref(), mOriginMetadata.mIsPrivate)));
+ databaseId.Append(NS_ConvertUTF16toUTF8(*mDatabaseFilenameBase));
mDatabaseId = Some(std::move(databaseId));
@@ -15181,10 +15137,8 @@ nsresult FactoryOp::Open() {
QM_TRY(MOZ_TO_RESULT(dbFile->Append(
NS_LITERAL_STRING_FROM_CSTRING(IDB_DIRECTORY_NAME))));
- QM_TRY(MOZ_TO_RESULT(dbFile->Append(
- GetDatabaseFilenameBase(mDatabaseName.ref(),
- mOriginMetadata.mIsPrivate) +
- kSQLiteSuffix)));
+ QM_TRY(MOZ_TO_RESULT(
+ dbFile->Append(*mDatabaseFilenameBase + kSQLiteSuffix)));
QM_TRY_RETURN(
MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(nsString, dbFile, GetPath));
@@ -15410,6 +15364,54 @@ nsresult FactoryOp::SendVersionChangeMessages(
return NS_OK;
} // namespace indexedDB
+nsAutoString FactoryOp::GetDatabaseFilenameBase(const nsAString& aDatabaseName,
+ bool aIsPrivate) {
+ nsAutoString databaseFilenameBase;
+
+ if (aIsPrivate) {
+ MOZ_DIAGNOSTIC_ASSERT(gStorageDatabaseNameMutex);
+
+ MutexAutoLock lock(*gStorageDatabaseNameMutex);
+
+ if (!gStorageDatabaseNameHashtable) {
+ gStorageDatabaseNameHashtable = new StorageDatabaseNameHashtable();
+ }
+
+ databaseFilenameBase.Append(
+ gStorageDatabaseNameHashtable->LookupOrInsertWith(aDatabaseName, []() {
+ return NSID_TrimBracketsUTF16(nsID::GenerateUUID());
+ }));
+
+ return databaseFilenameBase;
+ }
+
+ // WARNING: do not change this hash function. See the comment in HashName()
+ // for details.
+ databaseFilenameBase.AppendInt(HashName(aDatabaseName));
+
+ nsAutoCString escapedName;
+ if (!NS_Escape(NS_ConvertUTF16toUTF8(aDatabaseName), escapedName,
+ url_XPAlphas)) {
+ MOZ_CRASH("Can't escape database name!");
+ }
+
+ const char* forwardIter = escapedName.BeginReading();
+ const char* backwardIter = escapedName.EndReading() - 1;
+
+ nsAutoCString substring;
+ while (forwardIter <= backwardIter && substring.Length() < 21) {
+ if (substring.Length() % 2) {
+ substring.Append(*backwardIter--);
+ } else {
+ substring.Append(*forwardIter++);
+ }
+ }
+
+ databaseFilenameBase.AppendASCII(substring.get(), substring.Length());
+
+ return databaseFilenameBase;
+}
+
bool FactoryOp::MustWaitFor(const FactoryOp& aExistingOp) {
AssertIsOnOwningThread();
@@ -15641,12 +15643,9 @@ nsresult OpenDatabaseOp::DoDatabaseWork() {
#endif
}
- const auto databaseFilenameBase =
- GetDatabaseFilenameBase(databaseName, mOriginMetadata.mIsPrivate);
-
QM_TRY_INSPECT(const auto& markerFile,
CloneFileAndAppend(*dbDirectory, kIdbDeletionMarkerFilePrefix +
- databaseFilenameBase));
+ *mDatabaseFilenameBase));
QM_TRY_INSPECT(const bool& exists,
MOZ_TO_RESULT_INVOKE_MEMBER(markerFile, Exists));
@@ -15656,14 +15655,14 @@ nsresult OpenDatabaseOp::DoDatabaseWork() {
// previous operation.
// Note: only update usage to the QuotaManager when mEnforcingQuota == true
QM_TRY(MOZ_TO_RESULT(RemoveDatabaseFilesAndDirectory(
- *dbDirectory, databaseFilenameBase,
+ *dbDirectory, *mDatabaseFilenameBase,
mEnforcingQuota ? quotaManager : nullptr, persistenceType,
mOriginMetadata, databaseName)));
}
QM_TRY_INSPECT(
const auto& dbFile,
- CloneFileAndAppend(*dbDirectory, databaseFilenameBase + kSQLiteSuffix));
+ CloneFileAndAppend(*dbDirectory, *mDatabaseFilenameBase + kSQLiteSuffix));
mTelemetryId = TelemetryIdForFile(dbFile);
@@ -15679,7 +15678,7 @@ nsresult OpenDatabaseOp::DoDatabaseWork() {
QM_TRY_INSPECT(
const auto& fmDirectory,
- CloneFileAndAppend(*dbDirectory, databaseFilenameBase +
+ CloneFileAndAppend(*dbDirectory, *mDatabaseFilenameBase +
kFileManagerDirectoryNameSuffix));
IndexedDatabaseManager* const idm = IndexedDatabaseManager::Get();
@@ -16832,8 +16831,6 @@ nsresult DeleteDatabaseOp::DoDatabaseWork() {
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
- const nsAString& databaseName = mCommonParams.metadata().name();
-
QuotaManager* const quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager);
@@ -16846,12 +16843,9 @@ nsresult DeleteDatabaseOp::DoDatabaseWork() {
QM_TRY_UNWRAP(mDatabaseDirectoryPath, MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(
nsString, directory, GetPath));
- mDatabaseFilenameBase =
- GetDatabaseFilenameBase(databaseName, mOriginMetadata.mIsPrivate);
-
QM_TRY_INSPECT(
const auto& dbFile,
- CloneFileAndAppend(*directory, mDatabaseFilenameBase + kSQLiteSuffix));
+ CloneFileAndAppend(*directory, *mDatabaseFilenameBase + kSQLiteSuffix));
#ifdef DEBUG
{
@@ -17025,7 +17019,7 @@ nsresult DeleteDatabaseOp::VersionChangeOp::RunOnIOThread() {
}
nsresult rv = RemoveDatabaseFilesAndDirectory(
- *directory, mDeleteDatabaseOp->mDatabaseFilenameBase, quotaManager,
+ *directory, *mDeleteDatabaseOp->mDatabaseFilenameBase, quotaManager,
persistenceType, mDeleteDatabaseOp->mOriginMetadata,
mDeleteDatabaseOp->mCommonParams.metadata().name());
if (NS_WARN_IF(NS_FAILED(rv))) {
Loading diff…
References
On This Page