aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2014-12-14 20:52:13 +0100
committerAnton Khirnov <anton@khirnov.net>2014-12-20 10:53:28 +0100
commitda4f5d9d77882bee568266d764b95b51f81b7871 (patch)
treec77eb1ed734a2d478d2068320f8d5be35b76ae94 /libavcodec
parent931f5b235112f1c2a09dead36f0a228061d23942 (diff)
downloadffmpeg-da4f5d9d77882bee568266d764b95b51f81b7871.tar.gz
mjpegdec: check for pixel format changes
Fixes possible invalid memory access. Based on code by Michael Niedermayer <michaelni@gmx.at> CC: libav-stable@libav.org Bug-ID: CVE-2014-8541 Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind (cherry picked from commit 809c3023b699c54c90511913d3b6140dd2436550) Signed-off-by: Anton Khirnov <anton@khirnov.net> (cherry picked from commit aa7a19b41774ce5f8a4e43f3692a4f9d90aa5c92) Signed-off-by: Anton Khirnov <anton@khirnov.net>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/mjpegdec.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index 8210fd3f00..9db72ff63e 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -215,18 +215,20 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
{
- int len, nb_components, i, width, height, pix_fmt_id, ret;
+ int h_count[MAX_COMPONENTS] = { 0 };
+ int v_count[MAX_COMPONENTS] = { 0 };
+ int len, nb_components, i, width, height, bits, pix_fmt_id, ret;
/* XXX: verify len field validity */
len = get_bits(&s->gb, 16);
- s->bits = get_bits(&s->gb, 8);
+ bits = get_bits(&s->gb, 8);
if (s->pegasus_rct)
- s->bits = 9;
- if (s->bits == 9 && !s->pegasus_rct)
+ bits = 9;
+ if (bits == 9 && !s->pegasus_rct)
s->rct = 1; // FIXME ugly
- if (s->bits != 8 && !s->lossless) {
+ if (bits != 8 && !s->lossless) {
av_log(s->avctx, AV_LOG_ERROR, "only 8 bits/component accepted\n");
return -1;
}
@@ -253,7 +255,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
return AVERROR_INVALIDDATA;
}
}
- if (s->ls && !(s->bits <= 8 || nb_components == 1)) {
+ if (s->ls && !(bits <= 8 || nb_components == 1)) {
avpriv_report_missing_feature(s->avctx,
"JPEG-LS that is not <= 8 "
"bits/component or 16-bit gray");
@@ -265,25 +267,25 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
for (i = 0; i < nb_components; i++) {
/* component id */
s->component_id[i] = get_bits(&s->gb, 8) - 1;
- s->h_count[i] = get_bits(&s->gb, 4);
- s->v_count[i] = get_bits(&s->gb, 4);
+ h_count[i] = get_bits(&s->gb, 4);
+ v_count[i] = get_bits(&s->gb, 4);
/* compute hmax and vmax (only used in interleaved case) */
- if (s->h_count[i] > s->h_max)
- s->h_max = s->h_count[i];
- if (s->v_count[i] > s->v_max)
- s->v_max = s->v_count[i];
+ if (h_count[i] > s->h_max)
+ s->h_max = h_count[i];
+ if (v_count[i] > s->v_max)
+ s->v_max = v_count[i];
s->quant_index[i] = get_bits(&s->gb, 8);
if (s->quant_index[i] >= 4)
return AVERROR_INVALIDDATA;
- if (!s->h_count[i] || !s->v_count[i]) {
+ if (!h_count[i] || !v_count[i]) {
av_log(s->avctx, AV_LOG_ERROR,
"Invalid sampling factor in component %d %d:%d\n",
- i, s->h_count[i], s->v_count[i]);
+ i, h_count[i], v_count[i]);
return AVERROR_INVALIDDATA;
}
av_log(s->avctx, AV_LOG_DEBUG, "component %d %d:%d id: %d quant:%d\n",
- i, s->h_count[i], s->v_count[i],
+ i, h_count[i], v_count[i],
s->component_id[i], s->quant_index[i]);
}
@@ -296,10 +298,14 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
s->rgb = 1;
/* if different size, realloc/alloc picture */
- /* XXX: also check h_count and v_count */
- if (width != s->width || height != s->height) {
+ if (width != s->width || height != s->height || bits != s->bits ||
+ memcmp(s->h_count, h_count, sizeof(h_count)) ||
+ memcmp(s->v_count, v_count, sizeof(v_count))) {
s->width = width;
s->height = height;
+ s->bits = bits;
+ memcpy(s->h_count, h_count, sizeof(h_count));
+ memcpy(s->v_count, v_count, sizeof(v_count));
s->interlaced = 0;
/* test interlaced mode */