Medium CVSS 4.3 webkit UAF 🔧 Commit mapped

Overview

Medium
Severity
4.3
CVSS
No
Exploited ITW
Fixed
Fix Status
DescriptionProcessing maliciously crafted web content may lead to an unexpected process crash
ComponentWebCore Platform/Audio
Bug ClassUAF
Tracker273176
Fix commitb7ccdb65258e (WebKit/WebKit)
CWECWE-416 (Use-after-free)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:L
CISA KEVNot listed
CreditedHuang Xilin of Ant Group Light-Year Security Lab
Disclosed2024-07-29

Background

MultiChannelResampler / AudioBus
Audio resampling helper whose AudioBus holds per-channel sample buffers.
setChannelMemory
Points an AudioBus channel at a caller-provided memory block instead of owned storage — an aliasing optimization.
AudioWorklet
Runs author JS on the real-time audio rendering thread, driving processing concurrently with graph changes.
Buffer aliasing
Referencing externally-owned memory whose size/lifetime the referencing object does not control, risking stale/OOB access.

Root Cause Analysis

MultiChannelResampler resamples multi-channel audio. As an optimization it avoided allocating memory for the first channel by borrowing the caller-provided output buffer as the channel-0 backing store of its internal m_multiChannelBus: the constructor created the AudioBus without memory and only allocated AudioFloatArrays for channels 1..N-1 (m_channelsMemory), and process()/provideInputForChannel() called m_multiChannelBus->setChannelMemory(0, buffer.data(), framesToProcess) to point channel 0 at the caller’s transient buffer. That makes the AudioBus alias external memory whose lifetime and size are not owned by the resampler; when the resampler is driven from an AudioWorklet (author JS on the real-time audio thread) the borrowed buffer can be reused/freed or have a different length across the concurrent processing, so the AudioBus references stale or wrong-sized memory — a use-after-free / out-of-bounds on the audio channel data (the regression test is audioworklet-concurrent-resampler-crash).

The fix removes the borrowing optimization: the AudioBus is created with its own owned memory (AudioBus::create(numberOfChannels, requestFrames)), the separate m_channelsMemory vector is deleted, and process() no longer aliases the caller’s buffer for channel 0 (the ASSERT is relaxed from == to <= length).

The restored invariant is that the resampler’s AudioBus owns all its channel memory, so no channel points at externally-owned, potentially-stale buffers.

Key insight
The resampler borrowed the caller’s transient buffer as its AudioBus channel-0 memory instead of owning it, so concurrent AudioWorklet processing could leave the bus pointing at stale/wrong-sized memory; owning all channel memory removes the UAF/OOB.

Attack Path

  1. Set up an AudioWorklet resampling graph Create a WebAudio graph that drives a MultiChannelResampler with author code running in an AudioWorkletProcessor on the audio thread.
  2. Trigger channel-0 buffer borrowing Processing points the internal AudioBus’s channel 0 at the caller-provided transient buffer instead of owned memory.
  3. Invalidate the borrowed buffer Concurrent/re-entrant worklet processing reuses, resizes, or frees that buffer while the AudioBus still references it.
  4. Use-after-free / OOB The resampler reads/writes channel 0 through the stale external pointer, corrupting memory in the WebContent process.

Impact Assessment

A use-after-free / out-of-bounds on audio channel memory caused by aliasing a caller-owned buffer in the resampler’s AudioBus, reachable from WebAudio/AudioWorklet in the WebContent process. Concurrent worklet processing gives attacker-influenced timing over the stale buffer; the observable is a crash, with corruption potential. Confined to WebContent; rated medium.

Changed Functions

FunctionChangeNotes
MultiChannelResampler::MultiChannelResampler
Source/WebCore/platform/audio/MultiChannelResampler.cpp
modified Creates m_multiChannelBus with owned memory (AudioBus::create(numberOfChannels, requestFrames)) and drops the m_channelsMemory borrowing optimization.
MultiChannelResampler::process
Source/WebCore/platform/audio/MultiChannelResampler.cpp
modified No longer aliases the caller's buffer as channel-0 memory via setChannelMemory; relaxes the length ASSERT to <=.
MultiChannelResampler::m_channelsMemory (removed)
Source/WebCore/platform/audio/MultiChannelResampler.h
modified Removes the externally-borrowed channel-memory vector and the AudioArray include.

Audit Directions

  • Other setChannelMemory borrowers
    grep platform/audio for setChannelMemory / external buffer aliasing where the AudioBus outlives or races the borrowed buffer.
  • AudioWorklet-thread lifetimes
    Audit audio DSP objects driven from AudioWorklet for buffers borrowed across process() calls.
  • Length assumptions
    Review resampler/bus code assuming framesToProcess exactly equals a fixed length rather than <=.

Original Bug Report

The reporter's bug is still restricted on the tracker.