Skip to content

Fuzzing fixes #483

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- When skipping invalid frames in `ParsingMode::{BestAttempt, Relaxed}`, the parser will no longer be able to go out of the bounds
of the frame content ([issue](https://github.com/Serial-ATA/lofty-rs/issues/458)) ([PR](https://github.com/Serial-ATA/lofty-rs/pull/459))
- **MP4**: Support for flag items (ex. `cpil`) of any size (not just 1 byte) ([issue](https://github.com/Serial-ATA/lofty-rs/issues/457)) ([PR](https://github.com/Serial-ATA/lofty-rs/pull/460))
- **Fuzzing** (Thanks [@qarmin](https://github.com/qarmin)!) ([PR](https://github.com/Serial-ATA/lofty-rs/pull/476)) ([PR](https://github.com/Serial-ATA/lofty-rs/pull/479)):
- **Fuzzing** (Thanks [@qarmin](https://github.com/qarmin)!) ([PR](https://github.com/Serial-ATA/lofty-rs/pull/476)) ([PR](https://github.com/Serial-ATA/lofty-rs/pull/479)) ([PR](https://github.com/Serial-ATA/lofty-rs/pull/483)):
- **MusePack**: Fix panic when ID3v2 tag sizes exceed the stream length ([issue](https://github.com/Serial-ATA/lofty-rs/issues/470))
- **WAV**: Fix panic when calculating bit depth with abnormally large `bytes_per_sample` ([issue](https://github.com/Serial-ATA/lofty-rs/issues/471))
- **WavPack***: Fix panic when encountering wrongly sized blocks ([issue](https://github.com/Serial-ATA/lofty-rs/issues/472))
- **WavPack***: Fix panic when encountering wrongly sized blocks ([issue](https://github.com/Serial-ATA/lofty-rs/issues/472)) ([issue](https://github.com/Serial-ATA/lofty-rs/issues/480))
- **WavPack***: Fix panic when encountering zero-sized blocks ([issue](https://github.com/Serial-ATA/lofty-rs/issues/473))
- **MPEG**: Fix panic when APE tags are incorrectly sized ([issue](https://github.com/Serial-ATA/lofty-rs/issues/474))
- **ID3v2**: Fix panic when parsing non-ASCII `TDAT` and `TIME` frames in `TDRC` conversion ([issue](https://github.com/Serial-ATA/lofty-rs/issues/477))
- **APE**: Fix panic when parsing incorrectly sized header APE tags ([issue](https://github.com/Serial-ATA/lofty-rs/issues/481))

## [0.21.1] - 2024-08-28

Expand Down
6 changes: 5 additions & 1 deletion lofty/src/ape/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ where
}

let ape_header = read_ape_header(data, false)?;
stream_len -= u64::from(ape_header.size);
let Some(new_stream_length) = stream_len.checked_sub(u64::from(ape_header.size))
else {
err!(SizeMismatch);
};
stream_len = new_stream_length;

if parse_options.read_tags {
let ape = read_ape_tag_with_header(data, ape_header, parse_options)?;
Expand Down
58 changes: 18 additions & 40 deletions lofty/src/wavpack/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,28 +302,19 @@ fn get_extended_meta_info(
block_content: &[u8],
properties: &mut WavPackProperties,
) -> Result<()> {
let mut index = 0;
let block_size = block_content.len();
while index < block_size {
if block_size - index < 2 {
let reader = &mut &block_content[..];
loop {
if reader.len() < 2 {
break;
}

let id = block_content[index];
index += 1;

let mut size = u32::from(block_content[index]) << 1;
index += 1;
let id = reader.read_u8()?;
let mut size = u32::from(reader.read_u8()?) << 1;

let is_large = id & ID_FLAG_LARGE_SIZE > 0;
if is_large {
if block_size - index < 2 {
break;
}

size += u32::from(block_content[index]) << 9;
size += u32::from(block_content[index + 1]) << 17;
index += 2;
size += u32::from(reader.read_u8()?) << 9;
size += u32::from(reader.read_u8()?) << 17;
}

if size == 0 {
Expand All @@ -334,19 +325,20 @@ fn get_extended_meta_info(
size -= 1;
}

if (size as usize) >= reader.len() {
err!(SizeMismatch);
}

match id & 0x3F {
ID_NON_STANDARD_SAMPLE_RATE => {
properties.sample_rate =
(&mut &block_content[index..]).read_u24::<LittleEndian>()?;
index += 3;
properties.sample_rate = reader.read_u24::<LittleEndian>()?;
},
ID_DSD => {
if size <= 1 {
decode_err!(@BAIL WavPack, "Encountered an invalid DSD block size");
}

let mut rate_multiplier = u32::from(block_content[index]);
index += 1;
let mut rate_multiplier = u32::from(reader.read_u8()?);

if rate_multiplier > 30 {
parse_mode_choice!(
Expand All @@ -360,75 +352,61 @@ fn get_extended_meta_info(
properties.sample_rate = properties.sample_rate.wrapping_mul(rate_multiplier);

// Skip DSD mode
index += 1;
let _ = reader.read_u8()?;
},
ID_MULTICHANNEL => {
if size <= 1 {
decode_err!(@BAIL WavPack, "Unable to extract channel information");
}

properties.channels = u16::from(block_content[index]);
index += 1;

let reader = &mut &block_content[index..];
properties.channels = u16::from(reader.read_u8()?);

// size - (id length + channel length)
let s = size - 2;
match s {
0 => {
let channel_mask = reader.read_u8()?;
index += 1;

properties.channel_mask = ChannelMask(u32::from(channel_mask));
},
1 => {
let channel_mask = reader.read_u16::<LittleEndian>()?;
index += 2;

properties.channel_mask = ChannelMask(u32::from(channel_mask));
},
2 => {
let channel_mask = reader.read_u24::<LittleEndian>()?;
index += 3;

properties.channel_mask = ChannelMask(channel_mask);
},
3 => {
let channel_mask = reader.read_u32::<LittleEndian>()?;
index += 4;

properties.channel_mask = ChannelMask(channel_mask);
},
4 => {
properties.channels |= u16::from(reader.read_u8()? & 0xF) << 8;
properties.channels += 1;
index += 1;

let channel_mask = reader.read_u24::<LittleEndian>()?;
index += 3;

properties.channel_mask = ChannelMask(channel_mask);
},
5 => {
properties.channels |= u16::from(reader.read_u8()? & 0xF) << 8;
properties.channels += 1;
index += 1;

let channel_mask = reader.read_u32::<LittleEndian>()?;
index += 4;

properties.channel_mask = ChannelMask(channel_mask);
},
_ => decode_err!(@BAIL WavPack, "Encountered invalid channel info size"),
}
},
_ => {
index += size as usize;
let (_, rem) = reader.split_at(size as usize);
*reader = rem;
},
}

if id & ID_FLAG_ODD_SIZE > 0 {
index += 1;
let _ = reader.read_u8()?;
}
}

Expand Down
2 changes: 2 additions & 0 deletions lofty/tests/files/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(missing_docs)]

mod aac;
mod aiff;
mod ape;
Expand Down
11 changes: 11 additions & 0 deletions lofty/tests/fuzz/apefile_read_from.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use lofty::ape::ApeFile;
use lofty::config::ParseOptions;
use lofty::file::AudioFile;

#[test_log::test]
fn panic1() {
let mut reader = crate::get_reader(
"apefile_read_from/crash-6373119c37ca5982277fc75787a0a3c34aadbca7_minimized",
);
let _ = ApeFile::read_from(&mut reader, ParseOptions::default());
}
Binary file not shown.
Binary file not shown.
3 changes: 3 additions & 0 deletions lofty/tests/fuzz/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(missing_docs)]

use lofty::config::ParseOptions;
use lofty::prelude::*;

Expand All @@ -8,6 +10,7 @@ use std::time::Instant;

mod aacfile_read_from;
mod aifffile_read_from;
mod apefile_read_from;
mod flacfile_read_from;
mod id3v2;
mod mp4file_read_from;
Expand Down
8 changes: 8 additions & 0 deletions lofty/tests/fuzz/wavpackfile_read_from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,11 @@ fn panic3() {
);
let _ = WavPackFile::read_from(&mut reader, ParseOptions::default());
}

#[test_log::test]
fn panic4() {
let mut reader = crate::get_reader(
"wavpackfile_read_from/crash-96407368cf46fbf0ef1285c4d84fbd39a919ef2b_minimized",
);
let _ = WavPackFile::read_from(&mut reader, ParseOptions::default());
}
2 changes: 2 additions & 0 deletions lofty/tests/hound.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(missing_docs)]

use lofty::config::ParseOptions;
use lofty::error::Result;
use lofty::iff::wav::WavFile;
Expand Down
2 changes: 2 additions & 0 deletions lofty/tests/picture/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(missing_docs)]

mod format_parsers;
mod from_reader;
mod information;
2 changes: 2 additions & 0 deletions lofty/tests/tags/main.rs
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
#![allow(missing_docs)]

mod conversions;