{"id":"RUSTSEC-2026-0332","aliases":[],"status":"published","title":"`WaveFormat::parse` reads past the end of a `\u0026WAVEFORMATEX`","description":"`WaveFormat::parse` is a safe function that takes a `\u0026WAVEFORMATEX`, which is\nonly valid for reads of `size_of::\u003cWAVEFORMATEX\u003e()` (18) bytes. When the header\nhas `wFormatTag == WAVE_FORMAT_EXTENSIBLE` and `cbSize \u003e= 22`, the function\nreinterprets the reference as a `WAVEFORMATEXTENSIBLE` and reads 40 bytes.\nNothing in the signature guarantees that the header sits at the start of a\nlarger buffer, so safe code can trigger an out-of-bounds read:\n\n```rust\nuse wasapi::WaveFormat;\nuse windows::Win32::Media::Audio::WAVEFORMATEX;\nuse windows::Win32::Media::KernelStreaming::WAVE_FORMAT_EXTENSIBLE;\n\nlet header = WAVEFORMATEX {\n    wFormatTag: WAVE_FORMAT_EXTENSIBLE as u16,\n    nChannels: 2,\n    nSamplesPerSec: 48000,\n    nAvgBytesPerSec: 384000,\n    nBlockAlign: 8,\n    wBitsPerSample: 32,\n    cbSize: 22,\n};\n// Reads 22 bytes past the end of `header`.\nlet _ = WaveFormat::parse(\u0026header);\n```\n\nA more likely way to hit this is to copy the header out of a format pointer\nreturned by WASAPI (`let fmt = unsafe { *ptr };`) and pass `\u0026fmt`. The copy\nkeeps `cbSize`, but not the 22 bytes that follow it. The bytes read past the\nend are returned as the channel mask and subformat of the parsed format.\n\nThe flaw was corrected in commit `2562db7`, released in 0.25.0. `parse` is now\nan `unsafe fn` that takes a `*const WAVEFORMATEX`, and the caller must\nguarantee that the pointer is valid for reads of\n`size_of::\u003cWAVEFORMATEX\u003e() + cbSize` bytes. `WaveFormat::parse_from_blob_bytes`\n(available since 0.23.0) is the safe alternative and checks the slice length\nagainst `cbSize`.","facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"published":"2026-09-08T12:00:00Z","modified":"2026-10-07T14:45:03Z","fixes":[{"ecosystem":"crates.io","package":"wasapi","fixed_in":["0.25.0"],"sources":["osv"]}],"affected":[{"source":"osv","ecosystem":"crates.io","package":"wasapi","ranges":[{"type":"SEMVER","events":[{"introduced":"0.20.0"},{"fixed":"0.25.0"}]}]}],"references":[{"url":"https://crates.io/crates/wasapi","tags":["package"]},{"url":"https://rustsec.org/advisories/RUSTSEC-2026-0332.html","tags":["advisory"]},{"url":"https://github.com/HEnquist/wasapi-rs/issues/65","tags":["report"]},{"url":"https://github.com/HEnquist/wasapi-rs/pull/64","tags":["web"]}],"sources":{"osv":[{"id":"RUSTSEC-2026-0332","title":"`WaveFormat::parse` reads past the end of a `\u0026WAVEFORMATEX`","description":"`WaveFormat::parse` is a safe function that takes a `\u0026WAVEFORMATEX`, which is\nonly valid for reads of `size_of::\u003cWAVEFORMATEX\u003e()` (18) bytes. When the header\nhas `wFormatTag == WAVE_FORMAT_EXTENSIBLE` and `cbSize \u003e= 22`, the function\nreinterprets the reference as a `WAVEFORMATEXTENSIBLE` and reads 40 bytes.\nNothing in the signature guarantees that the header sits at the start of a\nlarger buffer, so safe code can trigger an out-of-bounds read:\n\n```rust\nuse wasapi::WaveFormat;\nuse windows::Win32::Media::Audio::WAVEFORMATEX;\nuse windows::Win32::Media::KernelStreaming::WAVE_FORMAT_EXTENSIBLE;\n\nlet header = WAVEFORMATEX {\n    wFormatTag: WAVE_FORMAT_EXTENSIBLE as u16,\n    nChannels: 2,\n    nSamplesPerSec: 48000,\n    nAvgBytesPerSec: 384000,\n    nBlockAlign: 8,\n    wBitsPerSample: 32,\n    cbSize: 22,\n};\n// Reads 22 bytes past the end of `header`.\nlet _ = WaveFormat::parse(\u0026header);\n```\n\nA more likely way to hit this is to copy the header out of a format pointer\nreturned by WASAPI (`let fmt = unsafe { *ptr };`) and pass `\u0026fmt`. The copy\nkeeps `cbSize`, but not the 22 bytes that follow it. The bytes read past the\nend are returned as the channel mask and subformat of the parsed format.\n\nThe flaw was corrected in commit `2562db7`, released in 0.25.0. `parse` is now\nan `unsafe fn` that takes a `*const WAVEFORMATEX`, and the caller must\nguarantee that the pointer is valid for reads of\n`size_of::\u003cWAVEFORMATEX\u003e() + cbSize` bytes. `WaveFormat::parse_from_blob_bytes`\n(available since 0.23.0) is the safe alternative and checks the slice length\nagainst `cbSize`.","status":"published","published":"2026-09-08T12:00:00Z","modified":"2026-10-07T14:45:03.058104767Z","updated_at":"2026-11-02T15:53:40.430679Z"}]}}
