diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-01-31 17:57:17 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-01-31 18:34:08 +0100 |
commit | 2884688bd51a808ccda3c0e13367619cd79e0579 (patch) | |
tree | 67476bc1055452cc5719b31aa41e949b2206f3fd | |
parent | 13aa82bbbb71c04bdcecf1341be4a23aee271bec (diff) | |
download | ffmpeg-2884688bd51a808ccda3c0e13367619cd79e0579.tar.gz |
avcodec/mjpegdec: pass into ff_mjpeg_decode_sos() and check bitmask size
Fixes: heap array overread
Fixes: asan_heap-oob_149b2bc_6577_m1.mxg
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/mjpegbdec.c | 2 | ||||
-rw-r--r-- | libavcodec/mjpegdec.c | 14 | ||||
-rw-r--r-- | libavcodec/mjpegdec.h | 3 | ||||
-rw-r--r-- | libavcodec/mxpegdec.c | 4 |
4 files changed, 15 insertions, 8 deletions
diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c index f061f0bc26..61640952ff 100644 --- a/libavcodec/mjpegbdec.c +++ b/libavcodec/mjpegbdec.c @@ -119,7 +119,7 @@ read_header: 8 * FFMIN(field_size, buf_end - buf_ptr - sos_offs)); s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16)); s->start_code = SOS; - if (ff_mjpeg_decode_sos(s, NULL, NULL) < 0 && + if (ff_mjpeg_decode_sos(s, NULL, 0, NULL) < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) return AVERROR_INVALIDDATA; } diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 4430e750c9..464b1d8369 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1100,6 +1100,7 @@ static void shift_output(MJpegDecodeContext *s, uint8_t *ptr, int linesize) static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, int Al, const uint8_t *mb_bitmask, + int mb_bitmask_size, const AVFrame *reference) { int i, mb_x, mb_y; @@ -1109,8 +1110,13 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, GetBitContext mb_bitmask_gb; int bytes_per_pixel = 1 + (s->bits > 8); - if (mb_bitmask) + if (mb_bitmask) { + if (mb_bitmask_size != (s->mb_width * s->mb_height + 7)>>3) { + av_log(s->avctx, AV_LOG_ERROR, "mb_bitmask_size mismatches\n"); + return AVERROR_INVALIDDATA; + } init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height); + } s->restart_count = 0; @@ -1265,7 +1271,7 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, } int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, - const AVFrame *reference) + int mb_bitmask_size, const AVFrame *reference) { int len, nb_components, i, h, v, predictor, point_transform; int index, id, ret; @@ -1397,7 +1403,7 @@ next_field: } else { if ((ret = mjpeg_decode_scan(s, nb_components, prev_shift, point_transform, - mb_bitmask, reference)) < 0) + mb_bitmask, mb_bitmask_size, reference)) < 0) return ret; } } @@ -1963,7 +1969,7 @@ eoi_parser: goto the_end; case SOS: s->cur_scan++; - if ((ret = ff_mjpeg_decode_sos(s, NULL, NULL)) < 0 && + if ((ret = ff_mjpeg_decode_sos(s, NULL, 0, NULL)) < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) goto fail; break; diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h index 1ec241b1e6..1317404219 100644 --- a/libavcodec/mjpegdec.h +++ b/libavcodec/mjpegdec.h @@ -137,7 +137,8 @@ int ff_mjpeg_decode_dqt(MJpegDecodeContext *s); int ff_mjpeg_decode_dht(MJpegDecodeContext *s); int ff_mjpeg_decode_sof(MJpegDecodeContext *s); int ff_mjpeg_decode_sos(MJpegDecodeContext *s, - const uint8_t *mb_bitmask, const AVFrame *reference); + const uint8_t *mb_bitmask,int mb_bitmask_size, + const AVFrame *reference); int ff_mjpeg_find_marker(MJpegDecodeContext *s, const uint8_t **buf_ptr, const uint8_t *buf_end, const uint8_t **unescaped_buf_ptr, int *unescaped_buf_size); diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c index 8eee3b8e9e..155d348905 100644 --- a/libavcodec/mxpegdec.c +++ b/libavcodec/mxpegdec.c @@ -295,11 +295,11 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; - ret = ff_mjpeg_decode_sos(jpg, s->mxm_bitmask, reference_ptr); + ret = ff_mjpeg_decode_sos(jpg, s->mxm_bitmask, s->bitmask_size, reference_ptr); if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) return ret; } else { - ret = ff_mjpeg_decode_sos(jpg, NULL, NULL); + ret = ff_mjpeg_decode_sos(jpg, NULL, 0, NULL); if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) return ret; } |