High chrome Integer Overflow 📄 Reporter bug report 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInteger overflow in Media
DescriptionInteger overflow in Media
ComponentMedia
Bug ClassInteger Overflow
Tracker514744613
Fix commit023fdd1a49b0 (chromium/third_party/ffmpeg) +11/-1
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-02

Changed Functions

FunctionChangeNotes
if
libavformat/oggparsevorbis.c
modified

Files Changed

  • libavformat/oggparsevorbis.c
From 023fdd1a49b0d8f78f430fd9143fc068dcd0638f Mon Sep 17 00:00:00 2001
From: Dale Curtis <[email protected]>
Date: Tue, 26 May 2026 16:21:46 +0000
Subject: [PATCH] avformat/ogg: Fix overflow and stale oggvorbis_private values

- Prevent integer overflow when summing header lengths; add bounds check.
- Re-initialize priv->vp with the new stream's extradata once all chained
  stream headers are collected.

Signed-off-by: Dale Curtis <[email protected]>
Bug: 514744613
Change-Id: I871341c368d67261b242fed385bdf31b7f75f21a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/third_party/ffmpeg/+/7875774
Reviewed-by: Thomas Guilbert <[email protected]>
---

diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c
index ed81a43..4044ad3 100644
--- a/libavformat/oggparsevorbis.c
+++ b/libavformat/oggparsevorbis.c
@@ -230,8 +230,11 @@
     int i, offset, len, err;
     int buf_len;
     unsigned char *ptr;
+    uint64_t total_len = (uint64_t)priv->len[0] + priv->len[1] + priv->len[2];
+    if (total_len + total_len / 255 + 64 > INT_MAX)
+        return AVERROR_INVALIDDATA;
 
-    len = priv->len[0] + priv->len[1] + priv->len[2];
+    len = total_len;
     buf_len = len + len / 255 + 64;
 
     if (*buf)
@@ -605,6 +608,13 @@
         priv->comment_size = 0;
         av_freep(&priv->setup);
         priv->setup_size = 0;
+
+        av_vorbis_parse_free(&priv->vp);
+        priv->vp = av_vorbis_parse_init(os->new_extradata, os->new_extradata_size);
+        if (!priv->vp) {
+            av_log(s, AV_LOG_ERROR, "Failed to re-initialize Vorbis parser\n");
+            return AVERROR_INVALIDDATA;
+        }
     }
 
     return skip_packet;
Loading diff…

Original Bug Report

reported by [email protected]

Heap Buffer Overflow in FFmpeg Ogg Vorbis Demuxer via Integer Overflow

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. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.

Overview: An integer overflow in the FFmpeg Ogg Vorbis demuxer leads to an undersized heap allocation and a subsequent out-of-bounds write. This vulnerability is reachable in the sandboxed renderer process when processing crafted Ogg Vorbis streams. The issue is exacerbated by Chromium’s removal of default FFmpeg allocation limits.

Affected files:

  • third_party/ffmpeg/libavformat/oggparsevorbis.c
  • third_party/ffmpeg/libavformat/oggdec.c
  • third_party/ffmpeg/libavformat/seek.c
  • third_party/ffmpeg/libavcodec/utils.c
  • media/filters/ffmpeg_glue.cc
  • media/filters/ffmpeg_demuxer.cc

Estimated timestamp from git blame: Unknown (Google3 checkout)

Summary

A potential heap buffer overflow exists in fixup_vorbis_headers within third_party/ffmpeg/libavformat/oggparsevorbis.c. An integer overflow occurs when calculating the total length of Vorbis headers, leading to an undersized buffer allocation. Subsequent operations then write data far beyond the allocated bounds.

Root Cause Analysis

In third_party/ffmpeg/libavformat/oggparsevorbis.c, the function fixup_vorbis_headers calculates the required buffer size by summing the lengths of three header packets stored in priv->len[0..2]:

// third_party/ffmpeg/libavformat/oggparsevorbis.c:234
len = priv->len[0] + priv->len[1] + priv->len[2];
buf_len = len + len / 255 + 64;
...
ptr = *buf = av_realloc(NULL, buf_len);

The variables priv->len[i] are of type unsigned int. Their sum is calculated using 32-bit unsigned arithmetic and can wrap around if the total exceeds $2^{32}$. This wrapped, small value is then assigned to the signed int len, resulting in an undersized buf_len and a correspondingly small heap allocation.

The function then proceeds to write into this buffer using av_xiphlacing and memcpy:

// third_party/ffmpeg/libavformat/oggparsevorbis.c:248
offset += av_xiphlacing(&ptr[offset], priv->len[1]);
for (i = 0; i < 3; i++) {
    memcpy(&ptr[offset], priv->packet[i], priv->len[i]);
    ...
}

av_xiphlacing (third_party/ffmpeg/libavcodec/utils.c:829) iterates while the input length is $\ge 255$, writing one 0xFF byte per iteration. If priv->len[1] is large (e.g., 2GB), it will write millions of bytes into the small allocated buffer. The subsequent memcpy calls also use the original large lengths, providing an attacker with a controlled out-of-bounds write primitive.

Reachability in Chromium

  1. Allocation Limits: Chromium explicitly removes FFmpeg’s default allocation limits in media/base/media.cc:50 by calling av_max_alloc(std::numeric_limits<size_t>::max()). This allows the multi-gigabyte allocations required to set up the large priv->len values.
  2. State Persistence: In third_party/ffmpeg/libavformat/oggdec.c, the os->private state (which contains priv->len) is not cleared during Ogg seeks (ogg_reset) or when encountering a new logical stream in a chained Ogg file if the codec remains the same (ogg_replace_stream). This allows an attacker to accumulate or reuse large header lengths across different parts of the stream processing logic.

Potential Attack Scenario

An attacker could host a malicious Ogg Vorbis file. When a user visits a page and the browser demuxes the file (e.g., during an automatic seek or when encountering chained logical streams), the demuxer could be tricked into accumulating large packet lengths in the oggvorbis_private state. Once all three headers are ‘received’, fixup_vorbis_headers is triggered, causing the overflow and potential code execution in the renderer process.

Suggested Fix

Use safe integer arithmetic (e.g., av_size_mult or checking against INT_MAX) when summing priv->len values in fixup_vorbis_headers. Additionally, ensure that os->private state is properly cleared or re-initialized during stream resets and logical stream switches in oggdec.c.

Evaluated with Chrome root at commit: 29093e11cf509e3593f6229e4b1b075cca356049


Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:

  • If you are familiar with the severity guidelines, you may adjust the severity.
  • If this is a false positive, and there’s no work to be done, please close as WAI.
  • If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.

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.

View on issue tracker