[18] Navigation API null-deref via reload() in pageswap handler
pageswaphandler 안에서navigation.reload()를 재진입 호출하면 renderer에서 null dereference가 발생하는 문제를 수정합니다. 패치 이전에는 중첩된 reload가HistoryController::updateForCommit()이 역참조하려던 provisionalDocumentLoader를 제거했습니다.
Source/WebCore/page/Navigation.cpp
Patch Details
Navigation::reload()가 frame()->loader().isDispatchingPageSwapEvent()를 확인하도록 수정되었습니다. 해당 값이 true이면 InvalidStateError로 거부합니다. 이 guard는 Bug 303364에서 Navigation::navigate()에 이미 적용된 것과 동일합니다.
Pageswap event handler 내부에서 호출되는 Navigation API 진입점에 re-entrancy guard가 누락되어, 중첩된 코드가 외부 호출자가 여전히 의존하는 provisional commit state를 무효화할 수 있는 패턴.
reload가 commit 단계에 도달하면 pageswap이 발생합니다. 이 handler 안에서 navigation.reload()를 동기적으로 호출하면 sync policy check가 실행되면서 FrameLoader::m_provisionalDocumentLoader가 제거됩니다. handler가 반환되면 updateForCommit()이 이미 null이 된 loader를 역참조하게 됩니다.
이 수정은 명확한 variant fix에 해당합니다. commit 메시지에서 Bug 303364를 명시하며, navigate()에 적용된 동일한 guard를 reload()로 이식한 것입니다. 원본 fix 이후 몇 달이 지나 variant fix가 뒤따르는 패턴은 이 subsystem에서 반복적으로 나타납니다.
이 vulnerability는 same-origin script가 WebContent를 항상 동일하게 crash시킬 수 있게 함으로써 renderer process 가용성을 약화시킵니다. crash 이상으로의 확장을 위해서는 dangling state가 memory-safety primitive로 재사용되어야 하는데, 이 diff에서는 그 근거가 직접 드러나지 않습니다.
Audit directions
- Other Navigation API entry points lacking the guard.
traverseTo,back,forward,updateCurrentEntry와 항목 변경 helper들이frame()->loader().isDispatchingPageSwapEvent()를 올바르게 참조하는지 점검합니다. - Native commit-pipeline functions dereferencing
provisionalDocumentLoader()after JS-observable events.HistoryController::updateForCommit()와 인접한 commit-time 메서드를 점검합니다. pageswap, beforeunload, unload, pagehide, navigate-event dispatch 이후에 load-state pointer를 읽는 모든 지점을 확인해야 합니다. isDispatching*predicates with partial coverage. 해당 predicate를 검색하여 보호 범위로 의도된 API surface 전체를 목록화합니다.