Display-only NativeImages recorded across processes
Component: WebKit Site Isolation | d1179a9
Source/WebKit/GPUProcess/GPUProcess.cpp
Source/WebKit/GPUProcess/graphics/RemoteSnapshotIdentifier.h
Site isolation 환경에서는 cross-origin iframe이 별도의 WebContent process에서 동작합니다. 그래서 이런 iframe을 포함한 페이지는 어느 한 process도 단독으로 rasterize할 수 없습니다. 이 문제를 해결하기 위해 snapshot은 GPU process에서 RemoteSnapshot을 통해 기록됩니다. 이때 process 간 pixel 전달에는 IOSurface가 사용되는데, 이는 mach port 기반의 공유 surface입니다.
Chrome::createDisplayOnlyImage()는 GPU process에 rendering을 기록하고, 다른 process의 frame이 여기에 그릴 수 있도록 합니다. 반환값은 NativeImage에 대한 promise이며, web process는 이 이미지를 화면에 표시할 수만 있고 읽을 수는 없습니다. 먼저 GPU process가 IOSurface에 그린 뒤 이를 UI process에 전달하고, 이후 surface의 관리는 UI process가 맡습니다. 한편 web process가 받는 것은 DisplayOnlyImageProxy뿐이며, 이 객체가 파괴되는 시점에 이미지가 해제됩니다. 또한 snapshot identifier가 process-qualified 형태로 변경되었습니다.
Significance
서로 다른 process의 frame을 하나의 snapshot으로 합성하면서도, 어떤 web process도 cross-origin pixel을 볼 수 없게 됩니다. Site isolation 환경의 view transition을 위한 기반 작업입니다.
Audit directions
권한이 높은 cross-process surface이지만 아직 호출 지점이 없습니다. 따라서 fuzzing을 거쳤을 가능성은 낮습니다. 또한 rasterize된 handle은 opaque_ipc_types.tracking.in에 NeedsReview로 표시되어 있습니다.
먼저 completeDisplayOnlyImage/releaseDisplayOnlyImage에 전달된 identifier가 실제로 요청을 보낸 process에 속하는지, UI process가 검증하는지 확인할 필요가 있습니다. 이 검증은 pageHostedAs와 ProcessQualified 처리 경로를 따라 살펴보면 됩니다.
다음으로 기록 도중 web process나 GPU process가 종료되는 경우의 lifetime 처리를 점검해야 합니다. 관련 지점은 removeSnapshotsForProcess, removeDisplayOnlyImagesForProcess, remotePageProcessDidTerminate입니다. 호출 순서 문제도 함께 살펴볼 필요가 있습니다. 예를 들어 complete가 두 번 호출되는 경우, complete 이전에 release가 호출되는 경우, identifier가 중복되는 경우가 해당합니다.
마지막으로, compromised web process가 UI process로 하여금 다른 process의 surface를 표시하거나 해제하게 만들 수 있는지 확인해야 합니다. 아울러 IOSurface handle의 크기와 format이 요청된 size 및 scale과 일치하는지 검증되는지도 점검이 필요합니다.