← All issues

[18] Navigation API null-deref via reload() in pageswap handler

Severity: Medium | Component: WebCore Navigation API | 8e3ad95

Rated Medium because the diff fixes a renderer-reachable null deref via re-entrant navigation.reload() inside a pageswap handler. Pre-fix, the nested reload cleared the provisional DocumentLoader that HistoryController::updateForCommit() was about to dereference.

Source/WebCore/page/Navigation.cpp

- if (!protect(window->document())->isFullyActive() || window->document()->unloadCounter())
+ if (RefPtr document = window->document(); !document->isFullyActive() || frame()->loader().isDispatchingPageSwapEvent() || document->unloadCounter())
return createErrorResult(WTF::move(committed), WTF::move(finished), ExceptionCode::InvalidStateError, "Invalid state"_s);

Navigation::reload() now consults frame()->loader().isDispatchingPageSwapEvent() and rejects with InvalidStateError if true — the same guard already present in Navigation::navigate() per Bug 303364.

Missing re-entrancy guard on a Navigation API entry point invoked from inside a pageswap event handler, allowing nested code to invalidate provisional commit state the outer caller still depends on.

A reload reaching the committed phase fires pageswap; the handler synchronously calling navigation.reload() ran a sync policy check that cleared FrameLoader::m_provisionalDocumentLoader. When the handler returned, updateForCommit() dereferenced the now-null loader.

🔒

Ownership and lifetime implications across the FrameLoader commit pipeline, plus how far this crash can plausibly be escalated under realistic web-content conditions.

Subscribe to read more

🔒

Four reusable audit patterns covering Navigation API entry-point symmetry and re-entrancy-guard coverage across the FrameLoader commit pipeline, with concrete starting points for variant discovery.

Subscribe to read more