From: Anthony Hurtado <[email protected]> vpk_read_packet() divides vpk->last_block_size and (par->block_align - vpk->last_block_size) by par->ch_layout.nb_channels without checking for zero.
While vpk_read_header() validates nb_channels > 0, the codec parameters may become zero through format probing misidentification (VPK probe score is 2/3 of AVPROBE_SCORE_MAX) or codec parameter reset, causing SIGFPE. Fix by: - Checking nb_channels != 0 before division in vpk_read_packet - Returning EOF for empty last blocks (last_block_size == 0) - Validating block_count > 0 in vpk_read_header - Validating last_block_size <= block_align in vpk_read_header Found by fuzzing with libFuzzer + AddressSanitizer. Reproduces with 10 distinct inputs. Signed-off-by: Anthony Hurtado <[email protected]> --- libavformat/vpk.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libavformat/vpk.c b/libavformat/vpk.c index f6270a1..7ad0ebe 100644 --- a/libavformat/vpk.c +++ b/libavformat/vpk.c @@ -68,7 +68,11 @@ static int vpk_read_header(AVFormatContext *s) if (samples_per_block <= 0) return AVERROR_INVALIDDATA; vpk->block_count = (st->duration + (samples_per_block - 1)) / samples_per_block; + if (!vpk->block_count) + return AVERROR_INVALIDDATA; vpk->last_block_size = (st->duration % samples_per_block) * 16 * st->codecpar->ch_layout.nb_channels / 28; + if (vpk->last_block_size > (unsigned)st->codecpar->block_align) + return AVERROR_INVALIDDATA; if (offset < avio_tell(s->pb)) return AVERROR_INVALIDDATA; @@ -87,6 +91,10 @@ static int vpk_read_packet(AVFormatContext *s, AVPacket *pkt) vpk->current_block++; if (vpk->current_block == vpk->block_count) { + if (!par->ch_layout.nb_channels) + return AVERROR_INVALIDDATA; + if (!vpk->last_block_size) + return AVERROR_EOF; unsigned size = vpk->last_block_size / par->ch_layout.nb_channels; unsigned skip = (par->block_align - vpk->last_block_size) / par->ch_layout.nb_channels; uint64_t pos = avio_tell(s->pb); -- 2.47.3 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
