← All reports

WebCodecs VPX encoder encoded uninitialized data from 10-bit frames

Feed WebCodecs a 10-bit frame and its encoder ships uninitialized heap as video.

Component: WebCore WebCodecs | 790f56e

WebCodecs VideoEncoder는 platform CVPixelBuffer를 backing으로 하는 VideoFrame을 입력으로 받습니다. 이 frame은 native buffer 형태로 libwebrtc의 VP8/VP9/AV1 encoder에 전달됩니다. 이후 encoder는 ToI420()을 호출하며, Cocoa에서는 이 호출이 -[RTCCVPixelBuffer toI420]에 해당합니다. 문제는 이 method가 8-bit NV12와 32-bit RGB만 처리한다는 점입니다. 그 외 format이 들어오면 미리 allocate해 둔 I420 buffer를 채우지 않은 채 그대로 반환했습니다. 이때 별도의 error도 보고되지 않았습니다.

이번 패치로 LibWebRTCVPXInternalVideoEncoder::encode()는 8-bit NV12가 아닌 모든 pixel buffer를 BT709 8-bit NV12로 변환하도록 수정되었습니다. 변환 과정에서 frame의 range는 그대로 유지됩니다. 또한 frame의 color space를 BT709로 설정하고, encoder마다 첫 번째 변환을 한 번만 log로 남기도록 했습니다. buffer가 없는 경우에는 encode가 실패 처리됩니다. 패치 이전에는 RGB 입력만 변환 대상이었습니다.

VP9 profile 2 decoder가 생성하는 frame과 같은 10-bit frame은 채워지지 않은 I420 buffer를 기반으로 encode되었고, 그 결과 초기화되지 않은 heap byte가 JavaScript에서 읽을 수 있는 bitstream에 포함되었습니다. 즉 web content에서 도달 가능한 heap disclosure 가능성이 존재했던 셈입니다. 다만 fix는 하나의 호출 지점에 format allowlist를 둔 것이며, toI420 자체는 변경되지 않았습니다.

toI420의 근본 동작은 여전히 그대로 남아 있습니다. 따라서 -[RTCCVPixelBuffer toI420]의 다른 호출 지점을 살펴볼 필요가 있습니다. 지원되지 않는 format을 여전히 받을 수 있는 다른 native buffer 처리 경로도 마찬가지입니다. 구체적으로는 다른 encoder, scaling 및 cropAndScale 경로, H264/HEVC WebCodecs와 WebRTC sender가 점검 대상입니다. 한편 새 검사는 통과하지만 range, subsampling, plane layout이 다른 8-bit NV12 변형도 확인해야 합니다. 새로 추가된 변환 로직에서는 홀수 크기, stride, visible rect/crop, 변환 실패 시의 처리를 점검할 필요가 있습니다. 마지막으로, 보고되는 decoder configuration이 변환 과정에서 덮어쓴 color space 및 range와 일관되게 유지되는지 확인해야 합니다.