Medium CVSS 7.5 webkit Integer Overflow 🔧 Commit mapped

Overview

Medium
Severity
7.5
CVSS
No
Exploited ITW
Fixed
Fix Status
DescriptionA remote attacker may be able to cause a denial-of-service
ComponentWebCore Platform/Audio
Bug ClassInteger Overflow
Tracker303959
Fix commit7afdc436a98c (WebKit/WebKit) +5/-1
CWECWE-400, CWE-120 (Buffer overflow)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
CISA KEVNot listed
CreditedNathaniel Oh (@calysteon)
Disclosed2026-02-11

Background

Audio resampler kernel
The per-channel core of WebCore’s sample-rate converter that pulls source frames and produces output frames at a different rate, tracking how much source data is buffered between calls.
m_fillIndex / endIndex
m_fillIndex is the count of source frames already buffered from a prior call; endIndex is the highest source frame index needed for the current output block, so 1 + endIndex - m_fillIndex is the additional frames to fetch.
Unsigned integer underflow
Subtracting a larger unsigned value from a smaller one wraps around to a huge value near the type maximum instead of producing a negative number, since size_t cannot represent negatives.
WTF::safeSub
A WebKit checked-arithmetic helper that performs a subtraction and returns false (writing nothing usable) if the operation overflows/underflows, letting callers bail out safely.
std::span
A non-owning (pointer, length) view over contiguous memory; an incorrectly large length lets consumers read past the backing buffer’s bounds.

Root Cause Analysis

AudioResamplerKernel::getSourceSpan() computes how many input (source) frames it must read to produce a requested block of output frames, then returns a std::span<float> over the source buffer describing that region. The frame count was computed as ‘size_t framesNeeded = 1 + endIndex - m_fillIndex;’, where endIndex is the highest source index needed for this output block and m_fillIndex is the number of source frames already buffered from the previous call (the ‘+1’ accounts for filling up to and including endIndex). This arithmetic silently assumes the invariant 1 + endIndex >= m_fillIndex. If that assumption is violated — i.e. m_fillIndex exceeds 1 + endIndex, which can arise from a crafted combination of resampling rate/scale factor, buffer state, and framesToProcess — the subtraction underflows. Because framesNeeded is an unsigned size_t, the underflow wraps to a near-SIZE_MAX value rather than going negative. That gigantic framesNeeded is then written through *numberOfSourceFramesNeededP and used to size/derive the returned source span, so downstream consumers read far past the end of the actual source buffer: an out-of-bounds read whose length is effectively unbounded, producing a crash (denial of service, as the CVE states).

The fix adds <wtf/CheckedArithmetic.h> and replaces the raw subtraction with WTF::safeSub(1 + endIndex, m_fillIndex, framesNeeded); if the checked subtraction underflows it returns false and getSourceSpan() returns an empty span (‘return { };’) instead of propagating a wrapped length. This restores the invariant by refusing to produce a source span (and refusing to report a frame count) when the computed need would be negative, converting a would-be OOB access into a benign empty-span early return. The precise upstream conditions that let m_fillIndex exceed endIndex+1 are not in the shown diff (only getSourceSpan is changed), so the exact trigger state is an inference from the arithmetic and the resampler’s buffering model.

Key insight
A classic unsigned-underflow-to-huge-length bug: an unchecked ‘a - b’ on size_t buffer indices assumed a >= b, and violating that assumption produced a near-SIZE_MAX span length driving an out-of-bounds read. The fix is the canonical WTF::safeSub guard with an empty-result early return.

Attack Path

  1. Reach the resampler from web content Drive audio through a path that instantiates an AudioResampler — e.g. a Web Audio graph or media element whose source sample rate differs from the output, requiring sample-rate conversion — so AudioResamplerKernel::getSourceSpan() is invoked during rendering.
  2. Control resampling parameters and buffering Choose a playback/resampling ratio (scale factor) and feed frame counts such that the internally tracked m_fillIndex becomes larger than 1 + endIndex for a processing block, e.g. via an extreme or dynamically changed rate.
  3. Trigger the underflow On the next getSourceSpan() call the unsigned subtraction 1 + endIndex - m_fillIndex wraps to a near-SIZE_MAX framesNeeded.
  4. Force the OOB read The oversized framesNeeded is used to size the returned source span (and reported via numberOfSourceFramesNeededP), so the resampling loop reads far beyond the source buffer, dereferencing unmapped/adjacent memory and crashing the process.

Impact Assessment

The primitive is an out-of-bounds read with an attacker-influenced but essentially unbounded length (a wrapped size_t), which reliably faults on unmapped memory and yields a controlled crash — matching the CVE’s denial-of-service classification. It sits in the audio-rendering path within the sandboxed WebContent process (or the media/GPU audio path in configurations where resampling runs there), not the more privileged Network process. While large OOB reads can sometimes be shaped into information disclosure, the diff and the DoS description point to a crash rather than a reliable read primitive, and there is no write, so escalation to memory corruption / RCE from this bug alone is not indicated.

Changed Functions

FunctionChangeNotes
AudioResamplerKernel::getSourceSpan
Source/WebCore/platform/audio/AudioResamplerKernel.cpp
modified Replaced 'size_t framesNeeded = 1 + endIndex - m_fillIndex;' with WTF::safeSub(1 + endIndex, m_fillIndex, framesNeeded) and an early 'return { };' on underflow, preventing an unsigned wraparound from producing an oversized source span.

Files Changed

  • Source/WebCore/platform/audio/AudioResamplerKernel.cpp

Audit Directions

  • Other index arithmetic in the same file/class
    Review the rest of AudioResamplerKernel.cpp and AudioResampler for other size_t index/offset computations (m_fillIndex, endIndex, frame counts) that subtract or add without CheckedArithmetic, especially any that also feed span sizes or numberOfSourceFramesNeeded.
  • Unchecked subtraction feeding span/buffer lengths
    Grep the platform/audio tree for patterns like ‘size_t <name> = … - …;’ whose result is used as a length, span size, or loop bound, and confirm each is either provably non-negative or wrapped in WTF::safeSub / checkedSum-style helpers.
  • Codebase-wide length-from-difference pattern
    More broadly, search for span/buffer constructions where the length is computed as ’end - start’ or ‘1 + end - fill’ on unsigned types (std::span<…>, makeSpan, subspan, memcpy sizes) and audit for missing underflow checks, using #include <wtf/CheckedArithmetic.h> additions in recent commits as a lead for known-fragile call sites.

Original Bug Report

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