aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonald S. Bultje <rsbultje@gmail.com>2012-03-10 11:57:17 -0800
committerReinhard Tartler <siretart@tauware.de>2012-03-14 20:47:19 +0100
commitc65eadee5d200b3ed2106548e8d0cace3db5e97f (patch)
tree70b133fbcaab7d28ff5dee5484cadca9b87a7bc2
parenta43f4bd601e905e3f04c47293a642ac541d727f3 (diff)
downloadffmpeg-c65eadee5d200b3ed2106548e8d0cace3db5e97f.tar.gz
xxan: protect against chroma LUT overreads.
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit f77bfa837636a99a4034d31916a76f7d1688cf5a) Signed-off-by: Reinhard Tartler <siretart@tauware.de>
-rw-r--r--libavcodec/xxan.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c
index fb8fb526ac..0a37d48f6b 100644
--- a/libavcodec/xxan.c
+++ b/libavcodec/xxan.c
@@ -162,7 +162,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
int i, j;
const uint8_t *src, *src_end;
const uint8_t *table;
- int mode, offset, dec_size;
+ int mode, offset, dec_size, table_size;
if (!chroma_off)
return 0;
@@ -171,9 +171,11 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
return -1;
}
bytestream2_seek(&s->gb, chroma_off + 4, SEEK_SET);
- mode = bytestream2_get_le16(&s->gb);
- table = s->gb.buffer;
- offset = bytestream2_get_le16(&s->gb) * 2;
+ mode = bytestream2_get_le16(&s->gb);
+ table = s->gb.buffer;
+ table_size = bytestream2_get_le16(&s->gb);
+ offset = table_size * 2;
+ table_size += 1;
if (offset >= bytestream2_get_bytes_left(&s->gb)) {
av_log(avctx, AV_LOG_ERROR, "Invalid chroma block offset\n");
@@ -196,7 +198,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
for (j = 0; j < avctx->height >> 1; j++) {
for (i = 0; i < avctx->width >> 1; i++) {
val = *src++;
- if (val) {
+ if (val && val < table_size) {
val = AV_RL16(table + (val << 1));
uval = (val >> 3) & 0xF8;
vval = (val >> 8) & 0xF8;
@@ -216,7 +218,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off)
for (j = 0; j < avctx->height >> 2; j++) {
for (i = 0; i < avctx->width >> 1; i += 2) {
val = *src++;
- if (val) {
+ if (val && val < table_size) {
val = AV_RL16(table + (val << 1));
uval = (val >> 3) & 0xF8;
vval = (val >> 8) & 0xF8;