FileSystemHandle IndexedDB storage
// LayoutTests WPT — race window the KeepAlive object closes:
const getRequest = store.get('key');
await requestWatcher(t, getRequest).wait_for('success');
await promiseForRequest(t, store.delete('key')); // record gone
await promiseForTransaction(t, tx);
const retrieved = getRequest.result; // KeepAlive must still hold FSM ref here
assert_true(await handle.isSameEntry(retrieved));
The File System Access API grants pages persistent handles to user-local filesystem entries. IndexedDB serializes JS values via the Structured Clone Algorithm. Allowing handles to round-trip through IDB lets a page persist a filesystem reference and reconstruct a live handle asynchronously. In WebKit's multi-process model the NetworkProcess is the trusted storage broker — it owns FileSystemStorageManager and SQLiteIDBBackingStore — while the WebProcess is untrusted.
This commit implements storing FileSystemFileHandle and FileSystemDirectoryHandle objects in IndexedDB. The wire form serializes only the handle's global identifier; the NetworkProcess resolves the full (kind, path, name) record via FileSystemStorageManager on put and re-attaches it on get. A new FileSystemHandleStorageKeepAlive refcounted object in the WebProcess holds a NetworkProcess-side FSM reference over IPC to prevent UAF during async JS deserialization — the gap between IDB result delivery and the moment JS first reads request.result.
Significance
This wires two high-privilege APIs — File System Access and IndexedDB — across the WebProcess/NetworkProcess boundary, introducing new IPC surface, a new ref-counting subsystem, and new cross-origin enforcement paths, all historically rich territory for security bugs.
Audit directions
FileSystemHandleStorageKeepAliveref-counting path. Double-free or under-release could leave a WebProcess holding a dangling filesystem reference. A malicious WebProcess could probe whether it can sendRemoveGlobalIdentifierReferencesfor identifiers it never registered, or send duplicate removal messages to drive the ref count negative.- 'Stash resolved records on IDBValue' side channel. NetworkProcess-internal state attached to
IDBValuedoes not go through IPC serialization. If cursor iteration or batchedgetAllRecordspaths fail to propagate or clear these stashed records correctly, handle metadata could leak across transactions or origins. - Origin isolation.
clientOriginflows throughIDBResultData(not IPC-serialized) and controls which FSM entries are registered. The four result paths (getRecordSuccess,getAllRecordsSuccess,openCursorSuccess,iterateCursorSuccess) each independently carry this origin — any path that omits or misroutes it could allow cross-origin handle access. SQLiteMemoryIDBBackingStorestub (in-memory variant used in private browsing) explicitly does not implementFileSystemHandleRecords— verify it correctly rejects or ignores handle storage rather than silently succeeding with a dangling identifier.