Fix integer underflow when reading Vorbis comments

When skipping a comment, the total number of expected comments goes
down. But it should not fall below zero.

This issue was benign: in the case of wraparound, we would still read to
the end of the block as usual, and no further. The 'comments_len'
variable was only used after that to report a format error in case of a
mismatch between how many comments we read, and how many the header said
there would be. The preallocation for the comments vector has already
happened at that point, so this could not cause a large allocation.

This issue was caught on CI by LibFuzzer.
This commit is contained in:
Ruud van Asseldonk 2019-09-16 20:26:42 +02:00
parent e7602c24c0
commit 33d19ae9a5
2 changed files with 9 additions and 1 deletions

View File

@ -447,7 +447,7 @@ fn read_vorbis_comment_block<R: ReadBytes>(input: &mut R, length: u32) -> Result
// For every comment, there is a length-prefixed string of the form
// "NAME=value".
while bytes_left >= 4 {
while bytes_left >= 4 && comments.len() < comments_len as usize {
let comment_len = try!(input.read_le_u32());
bytes_left -= 4;
@ -455,7 +455,11 @@ fn read_vorbis_comment_block<R: ReadBytes>(input: &mut R, length: u32) -> Result
return fmt_err("Vorbis comment too long for Vorbis comment block")
}
// Some older versions of libflac allowed writing zero-length Vorbis
// comments. ALthough such files are invalid, they do occur in the wild,
// so we skip over the empty comment.
if comment_len == 0 {
// Does not overflow because `comments_len > comments.len() >= 0`.
comments_len -= 1;
continue;
}
@ -487,6 +491,10 @@ fn read_vorbis_comment_block<R: ReadBytes>(input: &mut R, length: u32) -> Result
}
}
if bytes_left != 0 {
return fmt_err("Vorbis comment block has excess data")
}
if comments.len() != comments_len as usize {
return fmt_err("Vorbis comment block contains wrong number of entries")
}