CVE-2026-11198
Overview
Files Changed
media/parsers/h265_parser.cc
Patch
From 327947c30e1f16bf02f2f590dfff39721eed44a5 Mon Sep 17 00:00:00 2001
From: Eugene Zemtsov <eugene@chromium.org>
Date: Thu, 23 Apr 2026 12:32:46 -0700
Subject: [PATCH] media: Conditionally enforce strict HEVC coding block size limits
* log2_min_luma_coding_block_size_minus3 in [0, 3]
* ctb_log2_size_y in [4, 6]
Bug: 504395300
Change-Id: I1a3f19ad6a335d64b52275ffddfc3edc59338fca
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7788568
Commit-Queue: Eugene Zemtsov <eugene@chromium.org>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1619699}
---
diff --git a/media/parsers/h265_parser.cc b/media/parsers/h265_parser.cc
index e5c50d6..2b41700 100644
--- a/media/parsers/h265_parser.cc
+++ b/media/parsers/h265_parser.cc
@@ -719,9 +719,8 @@
}
READ_UE_OR_RETURN(&sps->log2_min_luma_coding_block_size_minus3);
- // This enforces that min_cb_log2_size_y below will be <= 30 and prevents
- // integer overflow math there.
- TRUE_OR_RETURN(sps->log2_min_luma_coding_block_size_minus3 <= 27);
+ IN_RANGE_IF_OR_RETURN(sps->log2_min_luma_coding_block_size_minus3, 0, 3,
+ validate_extended_bitstream_);
READ_UE_OR_RETURN(&sps->log2_diff_max_min_luma_coding_block_size);
int min_cb_log2_size_y = sps->log2_min_luma_coding_block_size_minus3 + 3;
@@ -731,7 +730,8 @@
return kInvalidStream;
sps->ctb_log2_size_y = ctb_log2_size_y.ValueOrDefault(0);
- TRUE_OR_RETURN(sps->ctb_log2_size_y <= 30);
+ IN_RANGE_IF_OR_RETURN(sps->ctb_log2_size_y, 4, 6,
+ validate_extended_bitstream_);
int min_cb_size_y = 1 << min_cb_log2_size_y;
int ctb_size_y = 1 << sps->ctb_log2_size_y;
sps->pic_width_in_ctbs_y = base::ClampCeil(
Original Bug Report
Potential memory corruption in HW video drivers due to loose H.265 parser bounds
Project Fortify, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports without the Chrome Security team. Please see go/chrome-ai-generated-security-bugs-faq for more information.
Overview: Chrome’s H.265 bitstream parser enforces loose validation bounds on several SPS and PPS syntax elements, exceeding the maximum limits defined in the H.265 specification. These out-of-spec values are passed directly to underlying hardware drivers via VAAPI and V4L2 without further clamping. This can potentially lead to memory corruption in the GPU process or Linux kernel if the drivers assume the inputs are specification-compliant.
Affected files:
media/parsers/h265_parser.ccmedia/gpu/vaapi/h265_vaapi_video_decoder_delegate.ccmedia/gpu/v4l2/v4l2_video_decoder_delegate_h265.cc
Estimated timestamp from git blame: 2023-04-18
Vulnerability Details
Chrome’s H.265 (HEVC) parser handles bitstream validation before delegating the decoding process to hardware drivers (such as VAAPI on Linux or V4L2 on ChromeOS). The implementation in media/parsers/h265_parser.cc uses base::CheckedNumeric and certain bounds checks to prevent immediate 32-bit integer overflows during Chrome’s internal calculations. However, it fails to enforce the strict architectural maximums dictated by the H.265 specification (ISO/IEC 23008-2).
Specifically, the following Sequence Parameter Set (SPS) and Picture Parameter Set (PPS) fields are allowed to reach values vastly exceeding their specification limits:
log2_min_luma_coding_block_size_minus3: Accepted up to 27 (Spec max typically ~3).ctb_log2_size_y: Computed and allowed up to 30 (Spec limit 6).max_transform_hierarchy_depth_inter/intra: Accepted up to 28 (Spec max 4).diff_cu_qp_delta_depth: Accepted up to 27.log2_parallel_merge_level_minus2: Accepted up to 28.
Once parsed, these out-of-bounds parameters are copied verbatim into driver-facing structures without any further clamping:
- VAAPI: In
media/gpu/vaapi/h265_vaapi_video_decoder_delegate.cc, macros likeFROM_SPS_TO_PPcopy the values into aVAPictureParameterBufferHEVCstruct. This is then submitted to the user-mode driver viavaapi_wrapper_->SubmitBuffer(). - V4L2: In
media/gpu/v4l2/v4l2_video_decoder_delegate_h265.cc, macros likeSPS_TO_V4L2SPScopy the values into av4l2_ctrl_hevc_spsstruct, which is pushed directly into the Linux kernel via theVIDIOC_S_EXT_CTRLSioctl.
Hardware drivers generally assume that the upstream userspace framework (Chrome) has validated the bitstream parameters to specification bounds. Drivers often use parameters like log2_min_luma_coding_block_size_minus3 as bitwise shift exponents (e.g., 1 << (val + 3)). A value of 27 can result in massive integer overflows during internal allocation size calculations. Additionally, parameters like max_transform_hierarchy_depth are often used to constrain recursion depths or index fixed-size local arrays. Passing 28 instead of 4 can easily lead to deep recursion (stack exhaustion) or out-of-bounds array writes within the driver.
This leads to potential memory corruption in the GPU process (via VAAPI) or a potential sandbox escape/kernel compromise (via V4L2).
Suggested Steps to Trigger
Please note: These are potential steps to trigger the issue, as our tooling does not currently have the ability to run code or verify a full proof of concept.
- An attacker crafts a malicious HEVC video bitstream where SPS and PPS NAL units contain syntax elements (like
log2_min_luma_coding_block_size_minus3andmax_transform_hierarchy_depth_inter) set to their maximum parser-allowed values (e.g., 27 and 28 respectively). - The attacker embeds this malicious video stream into a webpage using
<video>, MSE, or WebCodecs. - A victim visits the webpage on a platform utilizing hardware-accelerated HEVC decoding (e.g., Linux with VAAPI or ChromeOS with V4L2).
- The renderer parses the container and passes the raw stream to the GPU/Video Decoder process.
H265Parserparses the bitstream, accepts the massively out-of-spec values, and passes them to the decoder delegates.- The delegates copy the unsanitized values into
VAPictureParameterBufferHEVC(VAAPI) orv4l2_ctrl_hevc_sps(V4L2) and submit them to the hardware driver. - The underlying driver processes the oversized values, resulting in an integer overflow or out-of-bounds write during hardware initialization or decoding.
Suggested Fix
Update media/parsers/h265_parser.cc to enforce strict H.265 specification bounds for all SPS and PPS syntax elements, rather than just bounds that prevent internal integer overflows. Alternatively, explicit clamping and strict validation against specification maximums should be implemented in H265VaapiVideoDecoderDelegate and H265V4L2VideoDecoderDelegate before populating the driver structures.
Evaluated with Chrome root at commit: 7353d249d9cacf9c7218e1d7b8a39cf39c72d646
Results so far have been promising, but there can be wrong deductions. If this proves to be a false positive, please close as WAI; data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.