aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2015-06-04 22:34:12 +0200
committerMichael Niedermayer <michael@niedermayer.cc>2015-08-20 14:29:11 +0200
commit5709ac5c42a7d566d9373e7084be04d4962338b3 (patch)
tree2bfcaa7651735b4fd063c937246cf0430d76f80b
parent4121c1db15e121d85a9ed44372948701bbcea78a (diff)
downloadffmpeg-5709ac5c42a7d566d9373e7084be04d4962338b3.tar.gz
avcodec/adpcm: Check for overreads
See: vlc ticket 14649 Reported-by: carl Signed-off-by: Michael Niedermayer <michaelni@gmx.at> (cherry picked from commit 3c803ed9cb23e5a8d76b6c31d8a8c71cac27e769) Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavcodec/adpcm.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c
index 2f95a6ff45..f7ca208993 100644
--- a/libavcodec/adpcm.c
+++ b/libavcodec/adpcm.c
@@ -574,6 +574,8 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
case AV_CODEC_ID_ADPCM_IMA_DK4:
if (avctx->block_align > 0)
buf_size = FFMIN(buf_size, avctx->block_align);
+ if (buf_size < 4 * ch)
+ return AVERROR_INVALIDDATA;
nb_samples = 1 + (buf_size - 4 * ch) * 2 / ch;
break;
case AV_CODEC_ID_ADPCM_IMA_RAD:
@@ -587,13 +589,15 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
int bsamples = ff_adpcm_ima_block_samples[avctx->bits_per_coded_sample - 2];
if (avctx->block_align > 0)
buf_size = FFMIN(buf_size, avctx->block_align);
+ if (buf_size < 4 * ch)
+ return AVERROR_INVALIDDATA;
nb_samples = 1 + (buf_size - 4 * ch) / (bsize * ch) * bsamples;
break;
}
case AV_CODEC_ID_ADPCM_MS:
if (avctx->block_align > 0)
buf_size = FFMIN(buf_size, avctx->block_align);
- nb_samples = 2 + (buf_size - 7 * ch) * 2 / ch;
+ nb_samples = (buf_size - 6 * ch) * 2 / ch;
break;
case AV_CODEC_ID_ADPCM_SBPRO_2:
case AV_CODEC_ID_ADPCM_SBPRO_3:
@@ -606,6 +610,8 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb,
case AV_CODEC_ID_ADPCM_SBPRO_4: samples_per_byte = 2; break;
}
if (!s->status[0].step_index) {
+ if (buf_size < ch)
+ return AVERROR_INVALIDDATA;
nb_samples++;
buf_size -= ch;
}
@@ -1524,6 +1530,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data,
*got_frame_ptr = 1;
+ if (avpkt->size < bytestream2_tell(&gb)) {
+ av_log(avctx, AV_LOG_ERROR, "Overread of %d < %d\n", avpkt->size, bytestream2_tell(&gb));
+ return avpkt->size;
+ }
+
return bytestream2_tell(&gb);
}