← All issues

FileSystemHandle IndexedDB storage

da007ac

// 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.

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.

🔒

New ref-counting and IPC ownership paths across the process boundary — multiple lifecycle edge cases in this new subsystem are worth investigating.

Subscribe to read more