Skip to content

Commit 5661d18

Browse files
committed
MP4: Fix panic on improperly sized freeform idents
1 parent 5956023 commit 5661d18

File tree

4 files changed

+21
-6
lines changed

4 files changed

+21
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3030
- Fix panic when reading properties of a file with no timescale specified ([issue](https://github.com/Serial-ATA/lofty-rs/issues/418))
3131
- 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))
3232
- Fix panic when `data` atom length is less than 16 bytes ([issue](https://github.com/Serial-ATA/lofty-rs/issues/429))
33+
- Fix panic with improperly sized freeform identifiers ([issue](https://github.com/Serial-ATA/lofty-rs/issues/430))
3334
- Fix panic when `hdlr` atom is an unexpected length ([issue](https://github.com/Serial-ATA/lofty-rs/issues/435))
3435
- **WAV**:
3536
- Fix panic when reading properties with large written bytes per second ([issue](https://github.com/Serial-ATA/lofty-rs/issues/420))

lofty/src/mp4/atom_info.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ impl AtomInfo {
199199
err!(BadAtom("Found an incomplete freeform identifier"));
200200
}
201201

202-
atom_ident = parse_freeform(data, len, reader_size, parse_mode)?;
202+
atom_ident = parse_freeform(data, len - ATOM_HEADER_LEN, parse_mode)?;
203203
} else {
204204
atom_ident = AtomIdent::Fourcc(identifier);
205205
}
@@ -224,7 +224,6 @@ impl AtomInfo {
224224
fn parse_freeform<R>(
225225
data: &mut R,
226226
atom_len: u64,
227-
reader_size: u64,
228227
parse_mode: ParsingMode,
229228
) -> Result<AtomIdent<'static>>
230229
where
@@ -237,8 +236,9 @@ where
237236
err!(BadAtom("Found an incomplete freeform identifier"));
238237
}
239238

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

243243
Ok(AtomIdent::Freeform {
244244
mean: mean.into(),
@@ -249,13 +249,13 @@ where
249249
fn freeform_chunk<R>(
250250
data: &mut R,
251251
name: &[u8],
252-
reader_size: u64,
252+
reader_size: &mut u64,
253253
parse_mode: ParsingMode,
254254
) -> Result<String>
255255
where
256256
R: Read + Seek,
257257
{
258-
let atom = AtomInfo::read(data, reader_size, parse_mode)?;
258+
let atom = AtomInfo::read(data, *reader_size, parse_mode)?;
259259

260260
match atom {
261261
Some(AtomInfo {
@@ -267,6 +267,10 @@ where
267267
err!(BadAtom("Found an incomplete freeform identifier chunk"));
268268
}
269269

270+
if len >= *reader_size {
271+
err!(SizeMismatch);
272+
}
273+
270274
// Version (1)
271275
// Flags (3)
272276
data.seek(SeekFrom::Current(4))?;
@@ -275,6 +279,8 @@ where
275279
let mut content = try_vec![0; (len - 12) as usize];
276280
data.read_exact(&mut content)?;
277281

282+
*reader_size -= len;
283+
278284
utf8_decode(content).map_err(|_| {
279285
LoftyError::new(ErrorKind::BadAtom(
280286
"Found a non UTF-8 string while reading freeform identifier",

lofty/tests/fuzz/mp4file_read_from.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,11 @@ fn panic4() {
3939
);
4040
let _ = Mp4File::read_from(&mut reader, ParseOptions::new());
4141
}
42+
43+
#[test]
44+
fn panic5() {
45+
let mut reader = crate::get_reader(
46+
"mp4file_read_from/steam_at_mention_IDX_97_RAND_34488648178055098192895.m4a",
47+
);
48+
let _ = Mp4File::read_from(&mut reader, ParseOptions::new());
49+
}

0 commit comments

Comments
 (0)