diff --git a/CHANGELOG.md b/CHANGELOG.md index 1455652a..ce50e979 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - **Timestamp**: `Timestamp::parse` with empty inputs will return `None` when not using `ParsingMode::Strict` ([PR](https://github.com/Serial-ATA/lofty-rs/pull/416)) +### Fixed +- **Fuzzing** (Thanks [@qarmin](https://github.com/qarmin)!) ([PR](https://github.com/Serial-ATA/lofty-rs/pull/TODO)): + - **FLAC**: Fix panic when reading properties of a file with incorrect block sizes ([issue](https://github.com/Serial-ATA/lofty-rs/issues/422)) + ## [0.20.1] - 2024-07-02 ### Fixed diff --git a/lofty/src/error.rs b/lofty/src/error.rs index 2f4b8ca6..4b945e37 100644 --- a/lofty/src/error.rs +++ b/lofty/src/error.rs @@ -30,6 +30,7 @@ pub enum ErrorKind { /// /// This occurs when the size of an item is written as one value, but that size is either too /// big or small to be valid within the bounds of that item. + // TODO: Should probably have context SizeMismatch, /// Errors that occur while decoding a file FileDecoding(FileDecodingError), diff --git a/lofty/src/flac/read.rs b/lofty/src/flac/read.rs index 4bdd9c9d..49e5fe38 100644 --- a/lofty/src/flac/read.rs +++ b/lofty/src/flac/read.rs @@ -6,7 +6,7 @@ use crate::error::Result; use crate::flac::block::{BLOCK_ID_PICTURE, BLOCK_ID_STREAMINFO, BLOCK_ID_VORBIS_COMMENTS}; use crate::id3::v2::read::parse_id3v2; use crate::id3::{find_id3v2, FindId3v2Config, ID3FindResults}; -use crate::macros::decode_err; +use crate::macros::{decode_err, err}; use crate::ogg::read::read_comments; use crate::picture::Picture; @@ -71,7 +71,7 @@ where while !last_block { let block = Block::read(data, |block_type| { - block_type == BLOCK_ID_VORBIS_COMMENTS + (block_type == BLOCK_ID_VORBIS_COMMENTS && parse_options.read_tags) || (block_type == BLOCK_ID_PICTURE && parse_options.read_cover_art) })?; @@ -109,7 +109,7 @@ where continue; } - if block.ty == BLOCK_ID_PICTURE && parse_options.read_tags { + if block.ty == BLOCK_ID_PICTURE && parse_options.read_cover_art { log::debug!("Encountered a FLAC picture block, parsing"); match Picture::from_flac_bytes(&block.content, false, parse_options.parsing_mode) { @@ -134,6 +134,12 @@ where let current = data.stream_position()?; let end = data.seek(SeekFrom::End(0))?; + // In the event that a block lies about its size, the current position could be + // completely wrong. + if current > end { + err!(SizeMismatch); + } + (end - current, end) }; diff --git a/lofty/tests/fuzz/assets/flacfile_read_from/flac_with_id3v2_IDX_39_RAND_108668567929800767822112.flac b/lofty/tests/fuzz/assets/flacfile_read_from/flac_with_id3v2_IDX_39_RAND_108668567929800767822112.flac new file mode 100755 index 00000000..c1d3dce9 Binary files /dev/null and b/lofty/tests/fuzz/assets/flacfile_read_from/flac_with_id3v2_IDX_39_RAND_108668567929800767822112.flac differ diff --git a/lofty/tests/fuzz/flacfile_read_from.rs b/lofty/tests/fuzz/flacfile_read_from.rs index ec032f39..d9a0f4e6 100644 --- a/lofty/tests/fuzz/flacfile_read_from.rs +++ b/lofty/tests/fuzz/flacfile_read_from.rs @@ -1,7 +1,16 @@ -use crate::oom_test; +use crate::{get_reader, oom_test}; +use lofty::config::ParseOptions; +use lofty::file::AudioFile; use lofty::flac::FlacFile; #[test] fn oom1() { oom_test::("flacfile_read_from/oom-9268264e9bc5e2124e4d63cbff8cff0b0dec6644"); } + +#[test] +fn panic1() { + let mut reader = + get_reader("flacfile_read_from/flac_with_id3v2_IDX_39_RAND_108668567929800767822112.flac"); + let _ = FlacFile::read_from(&mut reader, ParseOptions::default()); +}