xxan: protect against chroma LUT overreads.

Message ID 20120314210240.E75F55E0D6@aruru.libav.org
State New
Headers show

Commit Message

Janne Grunau March 14, 2012, 9:02 p.m.
Module: libav
Branch: release/0.8
Commit: c65eadee5d200b3ed2106548e8d0cace3db5e97f

Author:    Ronald S. Bultje <rsbultje@gmail.com>
Committer: Reinhard Tartler <siretart@tauware.de>
Date:      Sat Mar 10 11:57:17 2012 -0800

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>

---

 libavcodec/xxan.c |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)

Patch

diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c
index fb8fb52..0a37d48 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;