[FFmpeg-trac] #7250(avcodec:new): There are several potential out-of-bounds access vulnerabilities because of missing check for avctx->height and avctx->width
FFmpeg
trac at avcodec.org
Fri Jun 8 06:27:31 EEST 2018
#7250: There are several potential out-of-bounds access vulnerabilities because of
missing check for avctx->height and avctx->width
-------------------------------------+-------------------------------------
Reporter: Yooooooha | Type: defect
Status: new | Priority: normal
Component: avcodec | Version: git-
Keywords: out-of- | master
bounds | Blocked By:
Blocking: | Reproduced by developer: 0
Analyzed by developer: 0 |
-------------------------------------+-------------------------------------
'''Summary of the bug:'''
There are several potential out-of-bounds access vulnerabilities because
of missing check for avctx->height and avctx->width.
'''Files and its function that should be patches.'''
libavcodec/smc.c: smc_decode_init
libavcodec/tiertexseqv.c: seqvideo_decode_init
libavcodec/qtrle.c: qtrle_decode_init
libavcodec/cinepak.c: cinepak_decode_init
libavcodec/msrle.c: msrle_decode_init
libavcodec/dsicinvideo.c: cinvideo_decode_init
libavcodec/msvideo1.c: msvideo1_decode_init
'''Below are the proposal patches for each file above.'''
libavcodec/smc.c: smc_decode_init
{{{
static av_cold int smc_decode_init(AVCodecContext *avctx)
{
SmcContext *s = avctx->priv_data;
s->avctx = avctx;
avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ if (!avctx->width || !avctx->height ||
+ (avctx->width & 1) || (avctx->height & 1)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n",
+ avctx->width, avctx->height);
+ return AVERROR(EINVAL);
+ }
s->frame = av_frame_alloc();
if (!s->frame)
return AVERROR(ENOMEM);
return 0;
}
}}}
libavcodec/tiertexseqv.c: seqvideo_decode_init
{{{
static av_cold int seqvideo_decode_init(AVCodecContext *avctx)
{
SeqVideoContext *seq = avctx->priv_data;
int ret;
seq->avctx = avctx;
avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ if (!avctx->width || !avctx->height ||
+ (avctx->width & 1) || (avctx->height & 1)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n",
+ avctx->width, avctx->height);
+ return AVERROR(EINVAL);
+ }
ret = ff_set_dimensions(avctx, 256, 128);
if (ret < 0)
return ret;
seq->frame = av_frame_alloc();
if (!seq->frame)
return AVERROR(ENOMEM);
return 0;
}
}}}
libavcodec/qtrle.c: qtrle_decode_init
{{{
static av_cold int qtrle_decode_init(AVCodecContext *avctx)
{
QtrleContext *s = avctx->priv_data;
s->avctx = avctx;
switch (avctx->bits_per_coded_sample) {
case 1:
case 2:
case 4:
case 8:
case 33:
case 34:
case 36:
case 40:
avctx->pix_fmt = AV_PIX_FMT_PAL8;
break;
case 16:
avctx->pix_fmt = AV_PIX_FMT_RGB555;
break;
case 24:
avctx->pix_fmt = AV_PIX_FMT_RGB24;
break;
case 32:
avctx->pix_fmt = AV_PIX_FMT_RGB32;
break;
default:
av_log (avctx, AV_LOG_ERROR, "Unsupported colorspace: %d
bits/sample?\n",
avctx->bits_per_coded_sample);
return AVERROR_INVALIDDATA;
}
+ if (!avctx->width || !avctx->height ||
+ (avctx->width & 1) || (avctx->height & 1)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n",
+ avctx->width, avctx->height);
+ return AVERROR(EINVAL);
+ }
s->frame = av_frame_alloc();
if (!s->frame)
return AVERROR(ENOMEM);
return 0;
}
}}}
libavcodec/cinepak.c: cinepak_decode_init
{{{
static av_cold int cinepak_decode_init(AVCodecContext *avctx)
{
CinepakContext *s = avctx->priv_data;
s->avctx = avctx;
s->width = (avctx->width + 3) & ~3;
s->height = (avctx->height + 3) & ~3;
s->sega_film_skip_bytes = -1; /* uninitialized state */
// check for paletted data
if (avctx->bits_per_coded_sample != 8) {
s->palette_video = 0;
avctx->pix_fmt = AV_PIX_FMT_RGB24;
} else {
s->palette_video = 1;
avctx->pix_fmt = AV_PIX_FMT_PAL8;
}
+ if (!avctx->width || !avctx->height ||
+ (avctx->width & 1) || (avctx->height & 1)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n",
+ avctx->width, avctx->height);
+ return AVERROR(EINVAL);
+ }
s->frame = av_frame_alloc();
if (!s->frame)
return AVERROR(ENOMEM);
return 0;
}
}}}
libavcodec/msrle.c: msrle_decode_init
{{{
static av_cold int msrle_decode_init(AVCodecContext *avctx)
{
MsrleContext *s = avctx->priv_data;
int i;
s->avctx = avctx;
switch (avctx->bits_per_coded_sample) {
case 1:
avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
break;
case 4:
case 8:
avctx->pix_fmt = AV_PIX_FMT_PAL8;
break;
case 24:
avctx->pix_fmt = AV_PIX_FMT_BGR24;
break;
default:
av_log(avctx, AV_LOG_ERROR, "unsupported bits per sample\n");
return AVERROR_INVALIDDATA;
}
+ if (!avctx->width || !avctx->height ||
+ (avctx->width & 1) || (avctx->height & 1)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n",
+ avctx->width, avctx->height);
+ return AVERROR(EINVAL);
+ }
s->frame = av_frame_alloc();
if (!s->frame)
return AVERROR(ENOMEM);
if (avctx->extradata_size >= 4)
for (i = 0; i < FFMIN(avctx->extradata_size, AVPALETTE_SIZE)/4;
i++)
s->pal[i] = 0xFFU<<24 | AV_RL32(avctx->extradata+4*i);
return 0;
}
}}}
libavcodec/dsicinvideo.c: cinvideo_decode_init
{{{
static av_cold int cinvideo_decode_init(AVCodecContext *avctx)
{
CinVideoContext *cin = avctx->priv_data;
cin->avctx = avctx;
avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ if (!avctx->width || !avctx->height ||
+ (avctx->width & 1) || (avctx->height & 1)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n",
+ avctx->width, avctx->height);
+ return AVERROR(EINVAL);
+ }
cin->frame = av_frame_alloc();
if (!cin->frame)
return AVERROR(ENOMEM);
cin->bitmap_size = avctx->width * avctx->height;
if (allocate_buffers(cin))
return AVERROR(ENOMEM);
return 0;
}
}}}
libavcodec/msvideo1.c: msvideo1_decode_init
{{{
static av_cold int msvideo1_decode_init(AVCodecContext *avctx)
{
Msvideo1Context *s = avctx->priv_data;
s->avctx = avctx;
/* figure out the colorspace based on the presence of a palette */
if (s->avctx->bits_per_coded_sample == 8) {
s->mode_8bit = 1;
avctx->pix_fmt = AV_PIX_FMT_PAL8;
if (avctx->extradata_size >= AVPALETTE_SIZE)
memcpy(s->pal, avctx->extradata, AVPALETTE_SIZE);
} else {
s->mode_8bit = 0;
avctx->pix_fmt = AV_PIX_FMT_RGB555;
}
+ if (!avctx->width || !avctx->height ||
+ (avctx->width & 1) || (avctx->height & 1)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n",
+ avctx->width, avctx->height);
+ return AVERROR(EINVAL);
+ }
s->frame = av_frame_alloc();
if (!s->frame)
return AVERROR(ENOMEM);
return 0;
}
}}}
--
Ticket URL: <https://trac.ffmpeg.org/ticket/7250>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list