Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 917854a9c245b87b333e23ed4b195505d574a333
https://github.com/WebKit/WebKit/commit/917854a9c245b87b333e23ed4b195505d574a333
Author: Sihui Liu <[email protected]>
Date: 2026-06-03 (Wed, 03 Jun 2026)
Changed paths:
A
LayoutTests/storage/indexeddb/index-unique-negative-zero-private-expected.txt
A LayoutTests/storage/indexeddb/index-unique-negative-zero-private.html
A LayoutTests/storage/indexeddb/resources/index-unique-negative-zero.js
M Source/WebCore/Modules/indexeddb/IDBKeyData.h
M Source/WebCore/Modules/indexeddb/server/MemoryIndex.cpp
M Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
M Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h
M Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp
M Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.h
M Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp
M Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h
M Source/WebKit/NetworkProcess/storage/NetworkStorageManager.cpp
Log Message:
-----------
[IndexedDB] Use-After-Free caused by use of `-0.0` for HashMap Key
rdar://172834266
Reviewed by Brady Eidson.
IndexValueStore uses HashMap with key type IDBKeyData to store index records.
For IDBKeyData, when its type is Number
or Date, the value passed to Hasher is a double. Since Hasher uses the raw bits
to create the hash, -0.0 and +0.0
produce different hashes, meaning the HashMap can have two separate entries for
IDBKeyData values of -0.0 and +0.0.
However, IDBKeyData::operator== returns true for -0.0 and +0.0 because it uses
IEEE 754 comparison. This inconsistency
can corrupt the map: for example, an attempt to remove the entry for +0.0 can
match and destroy the entry for -0.0
instead, leaving a cursor still referencing the freed entry (see the new test).
To fix this, normalize -0.0 to +0.0
before passing to Hasher.
This patch also fixes two other issues. First, MemoryIndex::transactionAborted
does not invalidate existing cursors when
a transaction is aborted, so a cursor may hold a reference to an index record
that is destroyed during the rollback.
This patch fixes that by calling notifyCursorsOfAllRecordsChanged() before
replaying the rollback.
Second, the network process does not validate the
DidFinishHandlingVersionChangeTransaction message. An uncompromised
web content process will not send this message while the version change
transaction is still in progress (i.e. before it
is committed or aborted). The network process should verify this before
proceeding, as the handler resets internal state
such as UniqueIDBDatabase::m_versionChangeTransaction, which could lead to
unexpected behavior.
Test: storage/indexeddb/index-unique-negative-zero-private.html
*
LayoutTests/storage/indexeddb/index-unique-negative-zero-private-expected.txt:
Added.
* LayoutTests/storage/indexeddb/index-unique-negative-zero-private.html: Added.
* LayoutTests/storage/indexeddb/resources/index-unique-negative-zero.js: Added.
(prepareDatabase):
(onOpenSuccess.transaction.onabort):
(onOpenSuccess):
(insertSecondRecord):
(secondRecordFailed):
(testCount.request.onsuccess):
(testCount):
(testCursor.request.onsuccess):
(testCursor):
* Source/WebCore/Modules/indexeddb/IDBKeyData.h:
(WebCore::add):
* Source/WebCore/Modules/indexeddb/server/MemoryIndex.cpp:
(WebCore::IDBServer::MemoryIndex::transactionAborted):
* Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::isVersionChangeTransactionFinishingOrFinished
const):
* Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h:
* Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.h:
* Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::abort):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::abortWithoutCallback):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::commit):
* Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h:
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::isFinishingOrFinished const):
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::setIsFinishingOrFinished):
* Source/WebKit/NetworkProcess/storage/NetworkStorageManager.cpp:
(WebKit::NetworkStorageManager::didFinishHandlingVersionChangeTransaction):
Originally-landed-as: 305413.585@rapid/safari-7624.2.5.110-branch
(95b97d3d6fc0). rdar://176061219
Canonical link: https://commits.webkit.org/314464@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications