avcodec/twinvq: Check block_align

Fixes: signed integer overflow: 538976288 * 8 cannot be represented in type 'int'
Fixes: 18348/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_METASOUND_fuzzer-6681325716635648

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Michael Niedermayer 2019-10-22 15:41:51 +02:00
parent 50001cd440
commit 97f778e9c5
1 changed files with 10 additions and 7 deletions

View File

@ -771,23 +771,26 @@ av_cold int ff_twinvq_decode_init(AVCodecContext *avctx)
{ {
int ret; int ret;
TwinVQContext *tctx = avctx->priv_data; TwinVQContext *tctx = avctx->priv_data;
int64_t frames_per_packet;
tctx->avctx = avctx; tctx->avctx = avctx;
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
if (!avctx->block_align) { if (!avctx->block_align) {
avctx->block_align = tctx->frame_size + 7 >> 3; avctx->block_align = tctx->frame_size + 7 >> 3;
} else if (avctx->block_align * 8 < tctx->frame_size) { }
av_log(avctx, AV_LOG_ERROR, "Block align is %d bits, expected %d\n", frames_per_packet = avctx->block_align * 8LL / tctx->frame_size;
avctx->block_align * 8, tctx->frame_size); if (frames_per_packet <= 0) {
av_log(avctx, AV_LOG_ERROR, "Block align is %"PRId64" bits, expected %d\n",
avctx->block_align * (int64_t)8, tctx->frame_size);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
tctx->frames_per_packet = avctx->block_align * 8 / tctx->frame_size; if (frames_per_packet > TWINVQ_MAX_FRAMES_PER_PACKET) {
if (tctx->frames_per_packet > TWINVQ_MAX_FRAMES_PER_PACKET) { av_log(avctx, AV_LOG_ERROR, "Too many frames per packet (%"PRId64")\n",
av_log(avctx, AV_LOG_ERROR, "Too many frames per packet (%d)\n", frames_per_packet);
tctx->frames_per_packet);
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
tctx->frames_per_packet = frames_per_packet;
tctx->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); tctx->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
if (!tctx->fdsp) { if (!tctx->fdsp) {