[15] [WebKit] Pin WebPageProxy across completion handlers via RefPtr promotion
diff에서는 여러 WebPageProxy completion handler 내의 WeakPtr<WebPageProxy>/WeakPtr<WebProcessProxy> 캡처를 RefPtr로 승격시키고 있습니다. 패치 이전의 if (!weakThis) return; weakThis->send(...); 형태는 main run loop에서 원자적으로 동작하지 않습니다. null 검사와 역참조 사이에 객체가 소멸될 수 있다는 점 때문에 High로 평가됩니다.
loadSimulatedRequest, loadAlternateHTML, reload, executeEditCommand, contextMenuItemSelected, didPerformDictionaryLookup, scheduleSetObscuredContentInsetsDispatch — 이 7개 함수에 걸쳐 동일한 패턴이 적용되었습니다. 각 함수에서 WeakPtr 캡처는 lambda 상단에서 한 번 RefPtr로 승격된 뒤, 이후 모든 호출에 사용됩니다.
Source/WebKit/UIProcess/WebPageProxy.cpp
WeakPtr 승격 지연: null 검사 이후 참조 미보유로 소멸 후 메서드 호출이 발생하는 패턴.
Patch Details
각 lambda는 메서드를 호출하기 전에 weak 캡처를 RefPtr(또는 Ref)로 승격합니다. loadSimulatedRequest가 가장 심각한 사례로, null 검사가 전혀 없는 상태에서 weakProcess를 직접 역참조하고 있었습니다. 나머지 호출 지점들은 if (!weakThis) return; 형태를 사용해 생존 여부는 확인했지만, 이후 호출에서 대상 객체의 소멸을 막지는 못했습니다.
Background
WeakPtr::operator bool은 현재 생존 여부만을 알려줄 뿐, 객체의 lifetime을 연장하지 않습니다. WebPageProxy의 completion handler는 main run loop(callOnMainRunLoop)에서 dispatch되거나, 비동기 sandbox-extension 처리 후 실행됩니다. null 검사와 최종 역참조 사이에, 관계없는 소유자가 WebPageProxy / WebProcessProxy에 대한 마지막 Ref를 해제할 가능성이 있습니다.
Analysis
패치 이전 코드에는 두 가지 subpattern이 존재했습니다:
(1) weakProcess->send(...); // null 검사 없이 직접 역참조, UAF 직행
(2) if (!weakThis) return; // 생존 확인 시점
... // 관련 없는 작업
weakThis->send(...); // 이 시점에서 dangling 가능
이 race는 main run loop 내부에서 발생합니다. null 검사와 역참조 사이에 completion handler가 관련 없는 작업을 실행하는 것만으로, 다른 event-loop task가 proxy를 소멸시키기에 충분합니다. fix는 WebKit의 표준 idiom에 해당하며, RefPtr로 단 한 번 승격한 뒤 lambda 실행 동안 해당 참조를 유지합니다.
이 primitive는 completion-handler dispatch를 통해 WebPageProxy / WebProcessProxy에 도달하는 UAF입니다. exploit은 page teardown 도중 dispatch race를 유도하는 형태로 구성됩니다.
이 취약점은 navigation 및 edit-command 경로 전반에서 UI-process completion-handler의 lifetime 불변성을 약화시킵니다.
Audit directions
- completion handler 내 모든
WeakPtr캡처 (Source/WebKit/UIProcess전체). lambda 컨텍스트에서weakThis/WeakPtr {를 검색하고, 상단에RefPtr승격이 이루어지는지 확인합니다. callOnMainRunLoop으로 dispatch된 callback 중 sandbox 처리나 비동기 경로에 진입하는 경우를 살펴볼 필요가 있습니다. dispatch 경계가 바로WeakPtrnull 검사를 TOCTOU로 만드는 지점입니다.WebProcessProxycompletion-handler 사용 지점도 점검 대상입니다. 동일한 race가 process 수준에도 존재하며, 승격 패턴이 일치해야 합니다.