Skip to content

symphonia-metadata: integer overflow panic at ape.rs:226 on crafted APEv2 header (size near u32::MAX) #526

Description

@ekhodzitsky

Summary

symphonia-metadata 0.6.0 panics with attempt to add with overflow at src/ape.rs:226 when parsing an APEv2 tag header whose size field is near u32::MAX with the header-present flag set. Found by libfuzzer in a ~60-second run against symphonia::default::get_probe().probe().

The bug is present on the current main branch — ape.rs:226 is unchanged (latest touch of that file is 2026-06-07, and the arithmetic there is the same as the published crate).

Vulnerable code

// src/ape.rs — raw u32 from untrusted input
let size = reader.read_u32()?;
// ...
// src/ape.rs:226 — no overflow check
let real_size = size + if has_header { 32 } else { 0 };

Minimized reproducer (36 bytes, hex)

2b e3 e3 41 50 45 54 41 47 45 58 d0 07 00 00 e3
ff ff ff ff e3 ff e3 13 0a ff ff f1 df 41 50 3f
13 a3 0a
Bytes Value Meaning
4–11 APETAGEX APEv2 magic — gates entry to the header reader
12–15 d0 07 00 00 (2000 LE) APEv2 version branch
16–19 e3 ff ff ff size = 0xFFFFFFE3 (4294967267)
20–23 bit 31 set has_header = true

4294967267 + 32 = 4294967299 > u32::MAX → panic.

Repro

Feed the 36 bytes to symphonia::default::get_probe().probe(...) on untrusted input (APE tags can also ride on MP3, so this is reachable from ordinary audio-file probing).

Suggested fix

// Saturating:
let real_size = size.saturating_add(if has_header { 32 } else { 0 });

// Or explicit rejection:
if size > u32::MAX - 32 {
    return decode_error("ape: tag size field overflows u32");
}
let real_size = size + if has_header { 32 } else { 0 };

Happy to open a PR if that's welcome. Thanks for Symphonia!

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