CVE-2026-8573
Overview
Files Changed
media/parsers/vp8_parser.cc
Patch
From 42ff1bc2555928f16a43ec23f4f66f28e0976460 Mon Sep 17 00:00:00 2001
From: Ted Meyer <tmathmeyer@chromium.org>
Date: Tue, 24 Mar 2026 18:59:03 -0700
Subject: [PATCH] Add bounds checking to VP8 Accelerator
Previously, an unchecked subtraction between two bitstream values
`first_part_size` and `macroblock_bit_offset` was calculated and sent to
hardware decoders. This change adds validation prevent unsigned int
underflow.
Fixed: 495417883
Change-Id: I348afd828394e68a0796037a46cbee3c129eaefd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7698802
Commit-Queue: Ted (Chromium) Meyer <tmathmeyer@chromium.org>
Reviewed-by: Eugene Zemtsov <eugene@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1604550}
---
diff --git a/media/parsers/vp8_parser.cc b/media/parsers/vp8_parser.cc
index f178604a..ed7c04d2 100644
--- a/media/parsers/vp8_parser.cc
+++ b/media/parsers/vp8_parser.cc
@@ -228,6 +228,13 @@
return false;
}
+ if (fhdr->first_part_size < (bd_.BitOffset() + 7) / 8) {
+ // If a video is created in such a way that the `first_part_size` field in
+ // the bitstream is smaller than the macroblock_bit_offset/8, the frame is
+ // not valid. Calculating the partition size becomes impossible.
+ return false;
+ }
+
fhdr->macroblock_bit_offset = bd_.BitOffset();
fhdr->bool_dec_range = bd_.GetRange();
fhdr->bool_dec_value = bd_.GetBottom();
Original Bug Report
Potential integer underflow in VP8 parser leads to GPU OOB read/write
Flapjack (go/flapjack), an LLM-powered static analysis tool, has identified the following potential security issue.
Overview: The Vp8Parser fails to validate that the size of the compressed frame header does not exceed the first_part_size declared in the VP8 frame tag. This causes an integer underflow when calculating the control partition size for VA-API and V4L2 hardware decoders. The massive underflowed size is passed to GPU drivers and potentially the kernel, leading to out-of-bounds memory access, information leaks, or GPU process RCE.
Affected files:
media/parsers/vp8_parser.ccmedia/gpu/vaapi/vaapi_utils.ccmedia/gpu/v4l2/v4l2_video_decoder_delegate_vp8.ccmedia/gpu/vaapi/test/vp8_decoder.cc
Estimated timestamp from git blame: 2021-11-09
Summary
A potential integer underflow leading to an out-of-bounds read/write was identified in Chromium’s VP8 video decoding utility. The root cause is a lack of validation in media::Vp8Parser::ParseFrameHeader (media/parsers/vp8_parser.cc), which fails to ensure that the number of bits consumed when reading the compressed frame header does not exceed the first_part_size specified in the uncompressed VP8 frame tag.
Technical Details
- Parsing Frame Tag: In
media/parsers/vp8_parser.cc, theVp8Parser::ParseFrameTagmethod extracts thefirst_part_sizefrom the VP8 frame tag (a 19-bit value). An attacker can craft a frame tag where this value is arbitrarily small (e.g.,5). - Parsing Compressed Header: Subsequently,
Vp8Parser::ParseFrameHeaderuses aVp8BoolDecoderto parse the compressed header. Crucially, the decoder is initialized with the entire remaining frame buffer (bytes_left_), not just thefirst_part_sizebytes. The number of bits consumed during this process is stored infhdr->macroblock_bit_offset. - Missing Validation: The parser successfully returns without verifying that the bytes consumed for the compressed header (
(macroblock_bit_offset + 7) / 8) actually fit within thefirst_part_size. - The Underflow: In multiple hardware video decoder delegates, such as
media/gpu/vaapi/vaapi_utils.cc(and similarly inmedia/gpu/vaapi/test/vp8_decoder.cc), the size of the first partition’s macroblock data is calculated by subtracting the header size fromfirst_part_size:If the attacker-controlledslice_param->partition_size[0] = frame_header.first_part_size - ((frame_header.macroblock_bit_offset + 7) / 8);first_part_size(e.g.,5) is smaller than the consumed header size in bytes (e.g.,13), an unsigned integer underflow occurs. Sincepartition_size[0]is an unsigned 32-bit integer (uint32_tin the VA-APIVASliceParameterBufferVP8struct), it wraps around to an extremely large value (e.g.,0xFFFFFFF8).
Impact
- GPU Information Leak / ASLR Bypass: This massive size is passed directly to the VA-API hardware/driver via
vaapi_wrapper_->MapAndCopyAndExecutein the privileged GPU process. The hardware may read massively beyond the end of the provided bitstream buffer. If the driver or hardware interprets this out-of-bounds data as macroblock data and incorporates it into the decoded frame, a cross-origin attacker could render the video to a canvas, extract the pixels, and read arbitrary GPU memory contents. - Remote Code Execution (RCE): If the specific VA-API driver implementation (e.g., Intel media driver, Mesa) performs internal buffer allocations or memory copies (
memcpy) based on this massive partition size before hardware submission, it will result in a heap buffer overflow and arbitrary code execution within the GPU process. - Potential Kernel Sandbox Escape: On V4L2-based platforms (e.g., ChromeOS on ARM), these unvalidated values are copied into a
v4l2_ctrl_vp8_framestructure and passed directly to the kernel viaioctlinmedia/gpu/v4l2/v4l2_video_decoder_delegate_vp8.cc. If the kernel driver performs the same subtraction without underflow validation, it could result in a kernel-level out-of-bounds read/write and a full sandbox escape.
Potential Steps to Reproduce
Note: These are potential steps as a full Proof of Concept (PoC) has not yet been executed.
- Craft a WebM media file containing a VP8 video track.
- Modify a single VP8 keyframe in the bitstream.
- Set the
first_part_sizefield in the uncompressed frame tag to a very small value (e.g.,5). - Ensure the subsequent compressed frame header contains valid boolean entropy data that consumes more bytes than the
first_part_size(e.g., > 40 bits). - Serve this malicious WebM file via an HTML5
<video>element on an attacker-controlled webpage. - When the victim visits the page on a device supporting VA-API or V4L2 hardware decoding, the Chromium media pipeline will parse the frame without error and pass the underflowed size to the GPU driver/kernel.
Evaluated with Chrome root at commit: 9760e6c70cd33a320713361f17c6dcca85648c0f
Results from Flapjack so far have been promising, but it can be wrong in its deductions. At this time, it does not produce proof of concepts or fuzzer tests. If this proves to be a false positive, please close as WAI; data from false positives will be used to improve Flapjack’s accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.