mirror of https://git.ffmpeg.org/ffmpeg.git
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>
This commit is contained in:
parent
13aa82bbbb
commit
2884688bd5
|
@ -119,7 +119,7 @@ read_header:
|
||||||
8 * FFMIN(field_size, buf_end - buf_ptr - sos_offs));
|
8 * FFMIN(field_size, buf_end - buf_ptr - sos_offs));
|
||||||
s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16));
|
s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16));
|
||||||
s->start_code = SOS;
|
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))
|
(avctx->err_recognition & AV_EF_EXPLODE))
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
|
||||||
int Al, const uint8_t *mb_bitmask,
|
int Al, const uint8_t *mb_bitmask,
|
||||||
|
int mb_bitmask_size,
|
||||||
const AVFrame *reference)
|
const AVFrame *reference)
|
||||||
{
|
{
|
||||||
int i, mb_x, mb_y;
|
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;
|
GetBitContext mb_bitmask_gb;
|
||||||
int bytes_per_pixel = 1 + (s->bits > 8);
|
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);
|
init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height);
|
||||||
|
}
|
||||||
|
|
||||||
s->restart_count = 0;
|
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,
|
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 len, nb_components, i, h, v, predictor, point_transform;
|
||||||
int index, id, ret;
|
int index, id, ret;
|
||||||
|
@ -1397,7 +1403,7 @@ next_field:
|
||||||
} else {
|
} else {
|
||||||
if ((ret = mjpeg_decode_scan(s, nb_components,
|
if ((ret = mjpeg_decode_scan(s, nb_components,
|
||||||
prev_shift, point_transform,
|
prev_shift, point_transform,
|
||||||
mb_bitmask, reference)) < 0)
|
mb_bitmask, mb_bitmask_size, reference)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1963,7 +1969,7 @@ eoi_parser:
|
||||||
goto the_end;
|
goto the_end;
|
||||||
case SOS:
|
case SOS:
|
||||||
s->cur_scan++;
|
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))
|
(avctx->err_recognition & AV_EF_EXPLODE))
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -137,7 +137,8 @@ int ff_mjpeg_decode_dqt(MJpegDecodeContext *s);
|
||||||
int ff_mjpeg_decode_dht(MJpegDecodeContext *s);
|
int ff_mjpeg_decode_dht(MJpegDecodeContext *s);
|
||||||
int ff_mjpeg_decode_sof(MJpegDecodeContext *s);
|
int ff_mjpeg_decode_sof(MJpegDecodeContext *s);
|
||||||
int ff_mjpeg_decode_sos(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,
|
int ff_mjpeg_find_marker(MJpegDecodeContext *s,
|
||||||
const uint8_t **buf_ptr, const uint8_t *buf_end,
|
const uint8_t **buf_ptr, const uint8_t *buf_end,
|
||||||
const uint8_t **unescaped_buf_ptr, int *unescaped_buf_size);
|
const uint8_t **unescaped_buf_ptr, int *unescaped_buf_size);
|
||||||
|
|
|
@ -295,11 +295,11 @@ static int mxpeg_decode_frame(AVCodecContext *avctx,
|
||||||
AV_GET_BUFFER_FLAG_REF)) < 0)
|
AV_GET_BUFFER_FLAG_REF)) < 0)
|
||||||
return ret;
|
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))
|
if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} 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))
|
if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue