High chrome Integer Overflow 📄 Reporter bug report 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInteger overflow in Chromecast
DescriptionInteger overflow in Chromecast
ComponentChromecast
Bug ClassInteger Overflow
Tracker500587568
Fix commit52e0efb0d221 (chromium/src) +13/-3
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-30

Changed Functions

FunctionChangeNotes
playback_rate_
chromecast/media/audio/audio_fader.cc
modified

Files Changed

  • chromecast/media/audio/audio_fader.cc
  • chromecast/media/audio/cast_audio_bus.cc
From 52e0efb0d221766111a85558a5da7bde7b652242 Mon Sep 17 00:00:00 2001
From: Simeon Anfinrud <[email protected]>
Date: Mon, 11 May 2026 20:56:57 -0700
Subject: [PATCH] [chromecast] Fix Integer overflow in CastAudioBus allocation

Use base::CheckMul to safely calculate the allocation size in CastAudioBus::Create, preventing integer overflow and subsequent heap buffer overflows. Added an upper bound check for fade_frames_ in AudioFader to prevent excessively large allocations.

Bug: 500587568
Test: Compiled and passed unit tests.
Change-Id: I91ffee3b96117578f9ef1de3070ffb879236a39c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7765496
Commit-Queue: Sandeep Vijayasekar <[email protected]>
Auto-Submit: Simeon Anfinrud <[email protected]>
Reviewed-by: Sandeep Vijayasekar <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1629040}
---

diff --git a/chromecast/media/audio/audio_fader.cc b/chromecast/media/audio/audio_fader.cc
index bf2eb677..563a78579 100644
--- a/chromecast/media/audio/audio_fader.cc
+++ b/chromecast/media/audio/audio_fader.cc
@@ -37,7 +37,10 @@
       sample_rate_(provider_->sample_rate()),
       playback_rate_(playback_rate) {
   DCHECK(provider_);
-  DCHECK_GT(fade_frames_, 0);
+  CHECK_GT(fade_frames_, 0);
+  // Cap the maximum fade length to 10 seconds at 192kHz to prevent
+  // excessive memory allocation and potential integer overflows later.
+  CHECK_LT(fade_frames_, 192000 * 10);
   DCHECK_GT(num_channels_, 0u);
   DCHECK_LE(num_channels_, kMaxChannels);
   DCHECK_GT(sample_rate_, 0);
diff --git a/chromecast/media/audio/cast_audio_bus.cc b/chromecast/media/audio/cast_audio_bus.cc
index b70e8cc..505b579 100644
--- a/chromecast/media/audio/cast_audio_bus.cc
+++ b/chromecast/media/audio/cast_audio_bus.cc
@@ -7,17 +7,24 @@
 #include <algorithm>
 #include <cstring>
 
+#include "base/check_op.h"
 #include "base/compiler_specific.h"
 #include "base/memory/ptr_util.h"
+#include "base/numerics/checked_math.h"
 
 namespace chromecast {
 namespace media {
 
 CastAudioBus::CastAudioBus(int channels, int frames) : frames_(frames) {
-  data_.reset(new float[channels * frames]);
+  CHECK_GE(channels, 0);
+  CHECK_GE(frames, 0);
+  size_t size = base::CheckMul(static_cast<size_t>(channels),
+                               static_cast<size_t>(frames))
+                    .ValueOrDie();
+  data_.reset(new float[size]);
   channel_data_.reserve(channels);
   for (int i = 0; i < channels; ++i)
-    channel_data_.push_back(UNSAFE_TODO(data_.get() + i * frames));
+    channel_data_.push_back(UNSAFE_TODO(data_.get() + static_cast<size_t>(i) * frames));
 }
 
 CastAudioBus::~CastAudioBus() = default;
Loading diff…

Original Bug Report

reported by [email protected]

Potential Integer overflow in CastAudioBus allocation allows heap overflow in Chromecast mixer

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 security team.

Overview: An integer overflow in the CastAudioBus constructor allows for an undersized heap allocation when a large fade_frames value is provided via the unsandboxed Chromecast mixer service. An attacker connecting via the unauthenticated Unix Domain Socket can exploit this on 32-bit platforms to cause a massive, attacker-controlled heap buffer overflow, potentially leading to local privilege escalation or sandbox escape.

Affected files:

  • chromecast/media/audio/cast_audio_bus.cc
  • chromecast/media/audio/audio_fader.cc
  • chromecast/media/cma/backend/mixer/mixer_input_connection.cc
  • chromecast/media/audio/net/audio_socket_service_uds.cc

Estimated timestamp from git blame: 2025-11-18

Background

The Chromecast mixer service (typically running as an unsandboxed process) exposes an abstract Unix Domain Socket (UDS) at /tmp/mixer-service that accepts connections via AudioSocketService. The authentication callback for this socket unconditionally returns true (chromecast/media/audio/net/audio_socket_service_uds.cc:65), allowing any unprivileged process or sandboxed renderer to connect.

Vulnerability Mechanism

When an attacker connects and sends a mixer_service::Generic message, they can initialize an audio stream using OutputStreamParams. The fade_frames parameter in this message is extracted without any maximum bounds checking (chromecast/media/cma/backend/mixer/mixer_input_connection.cc:394-398).

This unvalidated fade_frames value is passed down to instantiate an AudioFader and ultimately a CastAudioBus. In the CastAudioBus constructor, an allocation size is calculated using a 32-bit signed integer multiplication:

// chromecast/media/audio/cast_audio_bus.cc
CastAudioBus::CastAudioBus(int channels, int frames) : frames_(frames) {
  data_.reset(new float[channels * frames]);
  channel_data_.reserve(channels);
  for (int i = 0; i < channels; ++i)
    channel_data_.push_back(UNSAFE_TODO(data_.get() + i * frames));
}

If an attacker sets channels to 32 (the maximum allowed) and frames to 1,073,741,825 (0x40000001), the multiplication 32 * 1,073,741,825 overflows to 32. This results in a tiny 128-byte allocation (new float[32]).

On 32-bit architectures (standard for Chromecast ARM devices), the subsequent pointer arithmetic data_.get() + i * frames scales the frames by sizeof(float). For channel 1, this offset is 1,073,741,825 * 4, which wraps modulo 2^32 to exactly 4 bytes. Consequently, all 32 channel pointers alias safely into the same tiny 128-byte heap buffer.

During audio playback, AudioFader attempts to fill its massive buffer by requesting fade_frames_ - buffered_frames_ (roughly 1 billion frames) from its provider. This triggers MixerInputConnection::FillFromQueue, where std::copy_n copies the attacker’s queued audio payloads directly into the undersized channel_data_ pointers. Because the attacker’s payloads are larger than the 128-byte allocation, this results in a severe out-of-bounds heap write.

Potential Attacker Steps (Suggested)

Note: These are theoretical steps based on source code analysis.

  1. Connect to the mixer service UDS socket at /tmp/mixer-service.
  2. Send a mixer_service::Generic message with OutputStreamParams.
  3. Set num_channels to 32 and fade_frames to 0x40000001.
  4. Configure timestamped_audio_config with never_crop = true to bypass cropping logic in MixerInputConnection::FillTimestampedAudio.
  5. Stream thousands of frames of raw audio data containing a malicious payload (e.g., fake vtable pointers or ROP chains).
  6. When the StreamMixer engine requests playback data, the massive std::copy_n triggers, overwriting adjacent heap metadata and objects, leading to RCE within the mixer service.

Suggested Fix

  1. Validate fade_frames when parsing OutputStreamParams to ensure it falls within reasonable system limits.
  2. Use base::CheckedNumeric inside CastAudioBus::Create and the CastAudioBus constructor to prevent integer overflows during size calculations, returning a failure or crashing safely if an overflow is detected.

Evaluated with Chrome root at commit: 137d451a126685dd5010e6609db9f6d4a78d8234


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.

View on issue tracker