Skip to content

Commit

Permalink
MP4: Fix panic on improperly sized freeform idents
Browse files Browse the repository at this point in the history
  • Loading branch information
Serial-ATA committed Jul 23, 2024
1 parent 5956023 commit 5661d18
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix panic when reading properties of a file with no timescale specified ([issue](https://github.com/Serial-ATA/lofty-rs/issues/418))
- Fix panics when reading improperly sized freeform atom identifiers ([issue](https://github.com/Serial-ATA/lofty-rs/issues/425)) ([issue](https://github.com/Serial-ATA/lofty-rs/issues/426))
- Fix panic when `data` atom length is less than 16 bytes ([issue](https://github.com/Serial-ATA/lofty-rs/issues/429))
- Fix panic with improperly sized freeform identifiers ([issue](https://github.com/Serial-ATA/lofty-rs/issues/430))
- Fix panic when `hdlr` atom is an unexpected length ([issue](https://github.com/Serial-ATA/lofty-rs/issues/435))
- **WAV**:
- Fix panic when reading properties with large written bytes per second ([issue](https://github.com/Serial-ATA/lofty-rs/issues/420))
Expand Down
18 changes: 12 additions & 6 deletions lofty/src/mp4/atom_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ impl AtomInfo {
err!(BadAtom("Found an incomplete freeform identifier"));
}

atom_ident = parse_freeform(data, len, reader_size, parse_mode)?;
atom_ident = parse_freeform(data, len - ATOM_HEADER_LEN, parse_mode)?;
} else {
atom_ident = AtomIdent::Fourcc(identifier);
}
Expand All @@ -224,7 +224,6 @@ impl AtomInfo {
fn parse_freeform<R>(
data: &mut R,
atom_len: u64,
reader_size: u64,
parse_mode: ParsingMode,
) -> Result<AtomIdent<'static>>
where
Expand All @@ -237,8 +236,9 @@ where
err!(BadAtom("Found an incomplete freeform identifier"));
}

let mean = freeform_chunk(data, b"mean", reader_size, parse_mode)?;
let name = freeform_chunk(data, b"name", reader_size - 4, parse_mode)?;
let mut atom_len = atom_len;
let mean = freeform_chunk(data, b"mean", &mut atom_len, parse_mode)?;
let name = freeform_chunk(data, b"name", &mut atom_len, parse_mode)?;

Ok(AtomIdent::Freeform {
mean: mean.into(),
Expand All @@ -249,13 +249,13 @@ where
fn freeform_chunk<R>(
data: &mut R,
name: &[u8],
reader_size: u64,
reader_size: &mut u64,
parse_mode: ParsingMode,
) -> Result<String>
where
R: Read + Seek,
{
let atom = AtomInfo::read(data, reader_size, parse_mode)?;
let atom = AtomInfo::read(data, *reader_size, parse_mode)?;

match atom {
Some(AtomInfo {
Expand All @@ -267,6 +267,10 @@ where
err!(BadAtom("Found an incomplete freeform identifier chunk"));
}

if len >= *reader_size {
err!(SizeMismatch);
}

// Version (1)
// Flags (3)
data.seek(SeekFrom::Current(4))?;
Expand All @@ -275,6 +279,8 @@ where
let mut content = try_vec![0; (len - 12) as usize];
data.read_exact(&mut content)?;

*reader_size -= len;

utf8_decode(content).map_err(|_| {
LoftyError::new(ErrorKind::BadAtom(
"Found a non UTF-8 string while reading freeform identifier",
Expand Down
Binary file not shown.
8 changes: 8 additions & 0 deletions lofty/tests/fuzz/mp4file_read_from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,11 @@ fn panic4() {
);
let _ = Mp4File::read_from(&mut reader, ParseOptions::new());
}

#[test]
fn panic5() {
let mut reader = crate::get_reader(
"mp4file_read_from/steam_at_mention_IDX_97_RAND_34488648178055098192895.m4a",
);
let _ = Mp4File::read_from(&mut reader, ParseOptions::new());
}

0 comments on commit 5661d18

Please sign in to comment.