Medium chrome Logic Error 📄 Reporter bug report 🔧 Commit mapped

Overview

Medium
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactInsufficient validation of untrusted input in Chromecast
DescriptionInsufficient validation of untrusted input in Chromecast
ComponentChromecast
Bug ClassLogic Error
Tracker501659253
Fix commitbb4ed0adaae5 (chromium/src) +6/-1
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-02

Changed Functions

FunctionChangeNotes
if
chromecast/media/cma/backend/mixer/mixer_input_connection.cc
modified

Files Changed

  • chromecast/media/cma/backend/mixer/mixer_input_connection.cc
From bb4ed0adaae5aef5fca649e3f7be8ba619b7de27 Mon Sep 17 00:00:00 2001
From: Andrew Paseltiner <apaseltiner@chromium.org>
Date: Wed, 15 Apr 2026 05:12:47 -0700
Subject: [PATCH] [Cast] Validate playback rate in MixerInputConnection

This CL adds a runtime check to ensure the playback rate is positive in
MixerInputConnection::SetMediaPlaybackRate. If the rate is non-positive,
the request is ignored and an error is logged. Previously, such rates
could lead to a negative buffer offset and a heap out-of-bounds read in
release builds where DCHECKs are disabled.

Fixed: 501659253
Change-Id: Idd45e90ee2f28fbabc5dffb190e0ce05223411bf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7762266
Reviewed-by: Simeon Anfinrud <sanfin@chromium.org>
Commit-Queue: Andrew Paseltiner <apaseltiner@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1615072}
---

diff --git a/chromecast/media/cma/backend/mixer/mixer_input_connection.cc b/chromecast/media/cma/backend/mixer/mixer_input_connection.cc
index f7bb2ac..17637e8 100644
--- a/chromecast/media/cma/backend/mixer/mixer_input_connection.cc
+++ b/chromecast/media/cma/backend/mixer/mixer_input_connection.cc
@@ -638,7 +638,12 @@
 void MixerInputConnection::SetMediaPlaybackRate(double rate) {
   DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
   LOG(INFO) << this << " SetMediaPlaybackRate rate=" << rate;
-  DCHECK_GT(rate, 0);
+  // Non-positive playback rates are invalid and can lead to out-of-bounds
+  // memory access (crbug.com/501659253).
+  if (rate <= 0) {
+    LOG(ERROR) << "Invalid playback rate: " << rate;
+    return;
+  }
 
   base::AutoLock lock(lock_);
   if (state_ == State::kGotEos || state_ == State::kRemoved) {
Loading diff…

Original Bug Report

reported by vm...@google.com

Heap OOB Read in Cast Mixer Service via negative playback rate

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.

Overview: A potential heap out-of-bounds read exists in the Cast mixer service when handling a negative playback rate. The validation for the playback rate is compiled out in release builds, leading to a negative buffer offset calculation and subsequent out-of-bounds read from the heap.

Affected files:

  • chromecast/media/cma/backend/mixer/mixer_input_connection.cc
  • chromecast/media/audio/playback_rate_shifter.cc

Estimated timestamp from git blame: 2025-11-18

Summary

A potential heap out-of-bounds (OOB) read vulnerability exists in the Chromecast mixer service, which runs in the privileged cast_shell browser process. The vulnerability stems from insufficient validation of the playback_rate parameter in IPC messages. A DCHECK intended to prevent non-positive playback rates is compiled out in release builds. This allows a local attacker to supply a negative playback rate, which results in a negative buffer offset being used as an index for memory access, leading to an OOB read.

Vulnerability Details

The Cast mixer service accepts connections from local clients over a UNIX domain socket (e.g., \0/tmp/mixer-service). An unprivileged local process can connect to this socket, create an output stream, and send control messages.

When processing a SetPlaybackRate IPC message, the value is handled by MixerInputConnection::SetMediaPlaybackRate (chromecast/media/cma/backend/mixer/mixer_input_connection.cc:638):

void MixerInputConnection::SetMediaPlaybackRate(double rate) {
  // ...
  DCHECK_GT(rate, 0); // Only validated via DCHECK
  // ...
  SetMediaPlaybackRateLocked(rate);
}

In release builds, the DCHECK_GT is compiled out, allowing a negative rate (e.g., -1.0) to be passed to SetMediaPlaybackRateLocked and stored in playback_rate_.

If the stream is configured to use timestamped audio (pts_is_timestamp_), playback synchronization is handled by MixerInputConnection::FillTimestampedAudio. When calculating how much audio to crop to catch up to real-time, the code calculates frames_to_crop:

// chromecast/media/cma/backend/mixer/mixer_input_connection.cc:1229
const int frames_to_crop =
    (never_crop_ ? 0
                 : std::round(error * input_samples_per_second_ *
                              playback_rate_ / 1e6));

If the client supplies an audio buffer with an artificially old timestamp, the synchronization error will be a large positive value. Because playback_rate_ is negative, the resulting frames_to_crop becomes a large negative integer.

This negative value is then added to current_buffer_offset_:

// chromecast/media/cma/backend/mixer/mixer_input_connection.cc:1245
current_buffer_offset_ += frames_to_crop;

Subsequently, MixerInputConnection::FillFromQueue uses current_buffer_offset_ to compute the source pointer for a memory copy operation:

// chromecast/media/cma/backend/mixer/mixer_input_connection.cc:1289
const float* buffer_samples = GetAudioData(buffer);
for (int c = 0; c < num_channels_; ++c) {
  const float* buffer_channel =
      UNSAFE_TODO(buffer_samples + (buffer_frames * c));
  std::copy_n(UNSAFE_TODO(buffer_channel + current_buffer_offset_),
              frames_to_copy, UNSAFE_TODO(channels[c] + write_offset));
}

Because current_buffer_offset_ is a large negative number, buffer_channel + current_buffer_offset_ points backward into preceding heap memory, resulting in an out-of-bounds read.

Potential Exploitation

An attacker with local code execution (e.g., in a sandboxed renderer process) could potentially exploit this to leak memory from the privileged cast_shell process:

  1. The attacker connects to the mixer service UDS and configures a timestamped audio stream.
  2. The attacker sends a set_playback_rate IPC message with -1.0.
  3. The attacker sends an audio buffer with a timestamp far in the past to generate a large positive error.
  4. The mixer triggers the OOB read, pulling heap memory into the internal audio pipeline. The PlaybackRateShifter buffers this data in its AudioRendererAlgorithm.
  5. Before the AudioRendererAlgorithm drops or distorts the data due to the negative rate, the attacker sends a second IPC message setting the playback rate back to 1.0.
  6. The mixer resumes normal playback, draining the buffered OOB heap data and mixing it into the master audio output.
  7. The attacker connects to the mixer service via a second unauthenticated socket connection, requests a loopback stream, and captures the master audio output containing the leaked heap memory.

Note: These are suggested steps based on code analysis; we do not currently have a working proof of concept to demonstrate full exploitation.

Suggested Fix

Replace the DCHECK_GT(rate, 0); in MixerInputConnection::SetMediaPlaybackRate with a robust runtime check that enforces positive, bounded playback rates in all builds, or clamp the value to a safe range before applying it.

Evaluated with Chrome root at commit: 096fc8fdbfacf2546485756d03f160a3d04fcc9b


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