Low chrome OOB 🔧 Commit mapped

Overview

Low
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactBuffer overflow in WebRTC
DescriptionBuffer overflow in WebRTC
ComponentWebRTC
Bug ClassOOB
Tracker542449805
Fix commit437408bd428c (src) +1/-3
CISA KEVNot listed
Creditedk-kyuno
Disclosed2026-09-08

Background

WebRTC H.264 encoder wrapper
The webrtc::H264EncoderImpl class that adapts raw I420 video frames for an underlying H.264 codec, including creating downscaled buffers for simulcast layers.
I420 planar format
A YUV pixel layout where a full-resolution luma (Y) plane is accompanied by two half-resolution chroma (U/V) planes, each subsampled by 2 in both dimensions.
Stride
The number of bytes/samples per row in an image plane, which for chroma planes must cover ceil(width/2) samples so odd resolutions retain their final odd chroma pixel.
`I420Buffer::Create`
A WebRTC factory that allocates an I420 frame buffer, optionally taking explicit Y/U/V strides or, when omitted, computing correct default strides.

Root Cause Analysis

In H264EncoderImpl::SetRates (the code creating downscaled_buffers_), I420Buffer::Create was invoked with explicit stride arguments where the U and V strides were computed as configurations_[i].width / 2, an integer division that rounds down. The correct chroma stride for I420 is ceil(width/2) (i.e., (width + 1) / 2), which rounds up so that odd-width frames retain the extra chroma sample for their last odd pixel column. For any layer whose configured width is odd, the explicit stride under-allocated each chroma row by one sample, violating the invariant that a plane’s allocation must be large enough to hold every sample the encoder subsequently writes.

The fix removes the incorrect explicit stride arguments entirely and passes only width and height, letting I420Buffer::Create compute the correct default (rounded-up) chroma strides. This works because the default-stride path already implements the correct ceil rounding, eliminating the under-allocation.

Key insight
The single core mistake was rounding chroma stride down with integer division (width / 2) instead of up (ceil(width/2)), which under-sizes the buffer for odd resolutions; the fix deletes the hand-computed strides so I420Buffer::Create supplies its already-correct default strides.

Attack Path

  1. Establish a media session A remote peer negotiates a WebRTC connection that causes the victim to encode H.264 video with the affected wrapper.
  2. Force an odd resolution The attacker steers simulcast/downscale configuration so at least one layer’s configurations_[i].width is odd, making width / 2 differ from the required ceil(width/2).
  3. Allocate the undersized buffer Rate/resolution setup calls I420Buffer::Create with the too-small U/V stride, producing a downscaled_buffers_ entry lacking one chroma sample per row.
  4. Trigger the overflow Encoding writes the full (rounded-up) chroma plane into the undersized allocation, writing out of bounds past the buffer.

Impact Assessment

An attacker able to drive H.264 encoding at an odd resolution can cause a small heap buffer overflow (out-of-bounds write of chroma samples) within the process running WebRTC’s video encoder. The overflow is bounded and data-dependent rather than attacker-controlled in content, and the precondition is that the encoding pipeline selects an odd-width configuration. Given the low severity and constrained write, the practical impact is primarily memory corruption/instability rather than a demonstrated control-flow hijack.

Changed Functions

FunctionChangeNotes
if
modules/video_coding/codecs/h264/h264_encoder_impl.cc
modified

Files Changed

  • modules/video_coding/codecs/h264/h264_encoder_impl.cc

Audit Directions

  • Chroma stride rounding
    Search for chroma/subsampled dimensions computed with width / 2 or / 2 integer division and confirm they use ceil/(x + 1) / 2 wherever odd resolutions are possible.
  • Explicit-stride buffer allocation
    Audit callers that pass hand-computed strides to I420Buffer::Create (or similar allocators) and prefer the default-stride overload unless a custom stride is genuinely required.
  • Odd-resolution handling
    Review video scaling and simulcast paths for assumptions that widths/heights are even, since odd dimensions expose off-by-one under-allocation and overflow.
From 437408bd428c915b11f44df4f35cf1834acd61c9 Mon Sep 17 00:00:00 2001
From: Ilya Nikolaevskiy <ilnik@webrtc.org>
Date: Wed, 05 Aug 2026 10:51:13 +0200
Subject: [PATCH] Use default strides in allocated buffer in h264 encoder wrapper

The explicit values were incorrect: u/v strides were half-width rounded
down, but it has to be rounded up: for odd resolutions there are supposed to be extra u/v samples for last odd pixels.

Bug: chromium:542449805
Change-Id: I06f85d4cba737f69699f056057ebf039094bbffe
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/493940
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Auto-Submit: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#48298}
---

diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl.cc b/modules/video_coding/codecs/h264/h264_encoder_impl.cc
index 69db6ff..0056291 100644
--- a/modules/video_coding/codecs/h264/h264_encoder_impl.cc
+++ b/modules/video_coding/codecs/h264/h264_encoder_impl.cc
@@ -335,9 +335,7 @@
     // Create downscaled image buffers.
     if (i > 0) {
       downscaled_buffers_[i - 1] = I420Buffer::Create(
-          configurations_[i].width, configurations_[i].height,
-          configurations_[i].width, configurations_[i].width / 2,
-          configurations_[i].width / 2);
+          configurations_[i].width, configurations_[i].height);
     }
 
     // Codec_settings uses kbits/second; encoder uses bits/second.
Loading diff…

Original Bug Report

The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.